作者信息

作者: 彭东林

邮箱:pengdonglin137@163.com

QQ:405728433

平台简介

开发板:tiny4412ADK + S700 + 4GB Flash

要移植的内核版本:Linux-4.4.0 (支持device tree)

u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动)

busybox版本:busybox 1.25

交叉编译工具链: arm-none-linux-gnueabi-gcc

(gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29))

注意

继续上文。

到目前为止,板子已经可以起来了,接下来就可以针对板子的情况移植驱动程序了。这个放在以后再做,下面是我折腾过程中得到的一些知识,分享一下。

一、设备树反编译

在内核目录下当我们执行make dtbs后,就会在arch/arm/boot/dts下生成一些.dtb文件,那这个文件里是什么东西呢?我们可以用dtc命令反编译这些dtb文件,这里的可执行程序dtc在Linux内核源码中已经提供了,具体路径是:scripts/dtc/,可以使用下面的命令从Linux源码中编译出这个工具:

make CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm scripts

这样就会在scripts/dtc下生成可执行程序dtc。

当然,如果没有Linux源码,也可以使用apt-get命令安装这个工具,命令如下:

sudo apt-get install device-tree-compiler

下面以exynos4412-tiny4412.dtb为例:

命令:

dtc -I dtb -O dts -o tiny4412.dts arch/arm/boot/dts/exynos4412-tiny4412.dtb

然后就会生成反编译后的文件 tiny4412.dts,部分内容如下:

/dts-v1/;

/ {
#address-cells = <;0x1>;
#size-cells = <;0x1>;
interrupt-parent = <;0x1>;
compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
model = "FriendlyARM TINY4412 board based on Exynos4412"; chosen {
stdout-path = "/serial@13800000";
bootargs = "root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200 init=/linuxrc earlyprintk";
}; aliases {
spi0 = "/spi@13920000";
spi1 = "/spi@13930000";
spi2 = "/spi@13940000";
i2c0 = "/i2c@13860000";
i2c1 = "/i2c@13870000";
i2c2 = "/i2c@13880000";
i2c3 = "/i2c@13890000";
i2c4 = "/i2c@138A0000";
i2c5 = "/i2c@138B0000";
i2c6 = "/i2c@138C0000";
i2c7 = "/i2c@138D0000";
i2c8 = "/i2c@138E0000";
csis0 = "/camera/csis@11880000";
csis1 = "/camera/csis@11890000";
fimc0 = "/camera/fimc@11800000";
fimc1 = "/camera/fimc@11810000";
fimc2 = "/camera/fimc@11820000";
fimc3 = "/camera/fimc@11830000";
serial0 = "/serial@13800000";
serial1 = "/serial@13810000";
serial2 = "/serial@13820000";
serial3 = "/serial@13830000";
pinctrl0 = "/pinctrl@11400000";
pinctrl1 = "/pinctrl@11000000";
pinctrl2 = "/pinctrl@03860000";
pinctrl3 = "/pinctrl@106E0000";
fimc-lite0 = "/camera/fimc-lite@12390000";
fimc-lite1 = "/camera/fimc-lite@123A0000";
mshc0 = "/mmc@12550000";
}; memory {
device_type = "memory";
reg = <0x40000000 0x40000000>;
}; clock-controller@03810000 {
compatible = "samsung,exynos4210-audss-clock";
reg = <0x3810000 0xc>;
#clock-cells = <;0x1>;
linux,phandle = <;0x2>;
phandle = <;0x2>;
};
i2s@03830000 {
这个方法对于学习设备树很有帮助。

二、在u-boot打印信息

在u-boot中很多文件中是通过debug(… …)来打印信息,默认情况下这些log是打印不出来的。这个函数的定义是在include/common.h中:

#ifdef DEBUG
#define debug(fmt,args...)    printf (fmt ,##args)
#define debugX(level,fmt,args...) if (DEBUG>=level) printf(fmt,##args);
#else
#define debug(fmt,args...)
#define debugX(level,fmt,args...)
#endif /* DEBUG */
所以可以在调用debug函数的C文件的最上面添加  #define DEBUG  即可。这个方法在Linux内核以及Android当中也很常用。

三、打开Linux内核启动早期的log

有时会遇到当在u-boot中执行完bootm后,打印出start kernel后串口就没有再输出任何信息了。此时就需要打开内核早期的log:

make menuconfig

Kernel hacking  --->

[*] Kernel low-level debugging functions (read help!)

Kernel low-level debugging port (Use Samsung S3C UART 0 for low-level debug)

[*] Early printk

对于earlyprintk,还需要在bootargs中添加参数earlyprintk才能生效,有了上面这几个配置,会有下面几个宏生效:

CONFIG_DEBUG_LL=y

CONFIG_DEBUG_S3C_UART0=y

CONFIG_DEBUG_LL_INCLUDE="debug/exynos.S"

CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_EARLY_PRINTK=y

关于earlyprintk的解析在文件arch/arm/kernel/early_printk.c中:

   1: extern void printch(int);

   2: 

   3: static void early_write(const char *s, unsigned n)

   4: {

   5:     while (n-- >; 0) {

   6:         if (*s == '\n')

   7:             printch('\r');

   8:         printch(*s);

   9:         s++;

  10:     }

  11: }

  12:  

  13: static void early_console_write(struct console *con, const char *s, unsigned n)

  14: {

  15:     early_write(s, n);

  16: }

  17:  

  18: static struct console early_console_dev = {

  19:     .name =        "earlycon",

  20:     .write =    early_console_write,

  21:     .flags =    CON_PRINTBUFFER | CON_BOOT,

  22:     .index =    -1,

  23: };

  24: 

  25: static int __init setup_early_printk(char *buf)

  26: {

  27:     early_console = &;early_console_dev;

  28:     register_console(&;early_console_dev);

  29:     return 0;

  30: }

  31:  

  32: early_param("earlyprintk", setup_early_printk);

其中printch都是通过汇编语言实现的。

在arch/arm/Kconfig.debug中可以看到:

config DEBUG_LL
    bool "Kernel low-level debugging functions (read help!)"
    depends on DEBUG_KERNEL
    help
      Say Y here to include definitions of printascii, printch, printhex
      in the kernel.  This is helpful if you are debugging code that
      executes before the console is initialized
.

config DEBUG_S3C_UART0
    depends on PLAT_SAMSUNG
    select DEBUG_EXYNOS_UART if ARCH_EXYNOS
    select DEBUG_S3C24XX_UART if ARCH_S3C24XX
    select DEBUG_S5PV210_UART if ARCH_S5PV210
    bool "Use Samsung S3C UART 0 for low-level debug"
    help
      Say Y here if you want the debug print routines to direct
      their output to UART 0. The port must have been initialised
      by the boot-loader before use.

config DEBUG_LL_INCLUDE
    string
    ……
    default "debug/exynos.S" if DEBUG_EXYNOS_UART

config EARLY_PRINTK
    bool "Early printk"
    depends on DEBUG_LL
    help
      Say Y here if you want to have an early console using the
      kernel low-level debugging functions. Add earlyprintk to your
      kernel parameters to enable this console.

从上面的信息我们可以知道:

  • 在串口终端尚未注册时,内核定义了printascii、printch以及printhex用于调试;
  • early console使用的也是上面定义的函数,需要在传递给内核的参数中添加earlyprintk参数
  • Linux内核早期的print函数的输出串口要跟u-boot下使用的一致,即内核不再负责初始化了,让u-boot来做,所以二者一定要一致,否则那些print函数以及earlyprintk都没法输出信息;
  • 可以参考arch/arm/kernel/debug.S,printascii、printch以及printhex都是在这里定义的;
  • 在kernel进入C函数(start_kernel)后可以调用early_print来打印信息,它是在arch/arm/kernel/setup.c中定义的:
   1: void __init early_print(const char *str, ...)

   2: {

   3:     extern void printascii(const char *);

   4:     char buf[256];

   5:     va_list ap;

   6: 

   7:     va_start(ap, str);

   8:     vsnprintf(buf, sizeof(buf), str, ap);

   9:     va_end(ap);

  10:  

  11: #ifdef CONFIG_DEBUG_LL

  12:     printascii(buf);

  13: #endif

  14:     printk("%s", buf);

  15: }

可以看到,early_print也会调用printascii和printk,意思是用early_print打印的信息可能会重复出现在终端上(printk会缓冲一部分,当bootconsole注册后,会将printk缓冲区中的内容输出)。

上面所说的打印函数只能在内核自解压后的函数中才能使用,那么内核自解压过程中的信息是不是也可以打印呢?可以,内核自解压相关的文件在arch/arm/boot/compressed/下面,我们所熟知的:

Uncompressing Linux... done, booting the kernel.

就是这个目录下的代码打印出来的,具体代码如下:

arch/arm/boot/compressed/misc.c

   1: void

   2: decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,

   3:         unsigned long free_mem_ptr_end_p,

   4:         int arch_id)

   5: {

   6:     ......

   7:     putstr("Uncompressing Linux...");

   8:     ret = do_decompress(input_data, input_data_end - input_data,

   9:                 output_data, error);

  10:     ......

  11:     putstr(" done, booting the kernel.\n");

  12: }

其中,putstr的定义如下:

   1: static void putstr(const char *ptr)

   2: {

   3:     char c;

   4: 

   5:     while ((c = *ptr++) != '\0') {

   6:         if (c == '\n')

   7:             putc('\r');

   8:         putc(c);

   9:     }

  10:  

  11:     flush();

  12: }

putc是汇编实现的,arch/arm/boot/compressed/debug.S:

   1: #include CONFIG_DEBUG_LL_INCLUDE

   2:  

   3: ENTRY(putc)

   4:     addruart r1, r2, r3

   5:     waituart r3, r1

   6:     senduart r0, r1

   7:     busyuart r3, r1

   8:     mov     pc, lr

   9: ENDPROC(putc)

  10:  

  11:  

其中addruart的实现因soc的不同而不同,对于exynos4412,它的实现是(arch/arm/include/debug/exynos.S):

   1: .macro addruart, rp, rv, tmp

   2:     mrc    p15, 0, \tmp, c0, c0, 0

   3:     and    \tmp, \tmp, #0xf0

   4:     teq    \tmp, #0xf0        @@ A15

   5:     ldreq    \rp, =EXYNOS5_PA_UART

   6:     movne    \rp, #EXYNOS4_PA_UART    @@ EXYNOS4

   7:     ldr    \rv, =S3C_VA_UART

   8: CONFIG_DEBUG_S3C_UART != 0

   9:     add    \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)

  10:     add    \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)

  11: if

  12: .endm

这个函数的目的就是获得控制调试uart的寄存器的物理基地址(rp)和虚拟基地址(rv),这里也没有初始化uart的代码,所以必须跟u-boot使用的串口一致。

四、在内核自解压时dump内存

这是在调试设备树在内存中的镜像被自解压后的内核覆盖时发现的。下面是使用方法:

  • 首先需要按照上面的一节配置内核打开那几个宏
  • 修改arch/arm/boot/compressed/head.S,如下:
   1: diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S

   2: index 06e983f..7ecde2e 100644

   3: --- a/arch/arm/boot/compressed/head.S

   4: +++ b/arch/arm/boot/compressed/head.S

   5: @@ -22,6 +22,8 @@

   6:   * 100% relocatable.  Any attempt to do so will result in a crash.

   7:   * Please select one of the following when turning on debugging.

   8:   */

   9: +#define DEBUG

  10: +

  11:  #ifdef DEBUG

  12:  

  13:  #if defined(CONFIG_DEBUG_ICEDCC)

  14: @@ -65,7 +67,7 @@

  15:          .endm

  16:  #else

  17:          .macro    loadsp,    rb, tmp

  18: -        addruart \rb, \tmp

  19: +        addruart \rb, \tmp, \tmp

  20:          .endm

  21:  #endif

  22:  #endif

  23: @@ -536,6 +538,24 @@ not_relocated:    mov    r0, #0

  24:   *   r7  = architecture ID

  25:   *   r8  = atags pointer

  26:   */

  27: +        stmfd    sp!, {r0-r3, r10-r12, lr}

  28: +        kputc    #'\n'

  29: +        kputc    #'a'

  30: +        kputc    #'t'

  31: +        kputc    #'a'

  32: +        kputc    #'g'

  33: +        kputc    #'s'

  34: +        kputc    #':'

  35: +        kputc    #' '

  36: +        kputc    #'0'

  37: +        kputc    #'x'

  38: +        kphex    r8, 8        /* atags pointer */

  39: +        kputc    #'\n'

  40: +        mov    r0, r8

  41: +        bl    memdump        /* dump 256 bytes at start of kernel */

  42: +        kputc    #'\n'

  43: +        ldmfd    sp!, {r0-r3, r10-r12, lr}

  44: +

  45:          mov    r0, r4

  46:          mov    r1, sp            @ malloc space above stack

  47:          add    r2, sp, #0x10000    @ 64k max

  48: @@ -546,6 +566,26 @@ not_relocated:    mov    r0, #0

  49:          mov    r1, r7            @ restore architecture number

  50:          mov    r2, r8            @ restore atags pointer

  51:  

  52: +        stmfd    sp!, {r0-r3, r10-r12, lr}

  53: +        kputc    #'\n'

  54: +        kputc    #'\n'

  55: +        kputc    #'a'

  56: +        kputc    #'t'

  57: +        kputc    #'a'

  58: +        kputc    #'g'

  59: +        kputc    #'s'

  60: +        kputc    #':'

  61: +        kputc    #' '

  62: +        kputc    #'0'

  63: +        kputc    #'x'

  64: +        kphex    r8, 8        /* atags pointer */

  65: +        kputc    #'\n'

  66: +        mov    r0, r8

  67: +        bl    memdump        /* dump 256 bytes at start of kernel */

  68: +        kputc    #'\n'

  69: +        ldmfd    sp!, {r0-r3, r10-r12, lr}

  70: +

  71: +

  72:  #ifdef CONFIG_ARM_VIRT_EXT

  73:          mrs    r0, spsr        @ Get saved CPU boot mode

  74:          and    r0, r0, #MODE_MASK

可以使用kputc打印出一个字符,kphex用于打印一个指定位宽的十六进制数,将需要dump的内粗地址存放入r0,然后调用memdump即可,memdump会dump出256B的内容。u-boot在跳转到内核的时候传递三个参数,分别给了r0、r1、r2,在没有设备树之前,传给r0,r1和r2的分别是0,machid以及u-boot传给Linux内核参数的地址(如0x40000100),在有了设备树之后,传给r0的是0,传给r1的值无所谓,传给r2的是设备树镜像在内存中的地址。效果如下:

U-Boot 2010.12-00000-gb391276-dirty (Jan 17 2016 - 06:03:22) for TINY4412

 

 

CPU:    S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]

        APLL = 1400MHz, MPLL = 800MHz

 

Board:  TINY4412

DRAM:   1023 MiB

 

vdd_arm: 1.2

vdd_int: 1.0

vdd_mif: 1.1

 

BL1 version:  N/A (TrustZone Enabled BSP)

 

 

Checking Boot Mode ... SDMMC

REVISION: 1.1

MMC Device 0: 3803 MB

MMC Device 1: 3728 MB

MMC Device 2: N/A

*** Warning - using default environment

 

Net:    No ethernet found.

Hit any key to stop autoboot:  0 

TINY4412 # 

TINY4412 # dnw 0x40000000

OTG cable Connected!

Now, Waiting for DNW to transmit data

Download Done!! Download Address: 0x40000000, Download Filesize:0x43bde8

Checksum is being calculated.....

Checksum O.K.

TINY4412 # dnw  0x41000000

OTG cable Connected!

Now, Waiting for DNW to transmit data

Download Done!! Download Address: 0x41000000, Download Filesize:0x27752e

Checksum is being calculated...

Checksum O.K.

TINY4412 # dnw 0x42000000

OTG cable Connected!

Now, Waiting for DNW to transmit data

Download Done!! Download Address: 0x42000000, Download Filesize:0xa53a

Checksum is being calculated.

Checksum O.K.

TINY4412 # bootm 0x40000000 0x41000000 0x42000000

## Booting kernel from Legacy Image at 40000000 ...

   Image Name:   Linux-4.4.0-gbd49c0f-dirty

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    4439464 Bytes = 4335 KiB

   Load Address: 40008000

   Entry Point:  40008000

   Verifying Checksum ... OK

## Loading init Ramdisk from Legacy Image at 41000000 ...

   Image Name:   ramdisk

   Image Type:   ARM Linux RAMDisk Image (gzip compressed)

   Data Size:    2585838 Bytes = 2525 KiB

   Load Address: 00000000

   Entry Point:  00000000

   Verifying Checksum ... OK

## Flattened Device Tree blob at 42000000

   Booting using the fdt blob at 0x42000000

   Loading Kernel Image ... OK

OK

## Loading init Ramdisk from Legacy Image at 41000000 ...

   Image Name:   ramdisk

   Image Type:   ARM Linux RAMDisk Image (gzip compressed)

   Data Size:    2585838 Bytes = 2525 KiB

   Load Address: 00000000

   Entry Point:  00000000

   Verifying Checksum ... OK

   Loading Ramdisk to 43a84000, end 43cfb4ee ... OK

   Loading Device Tree to 413f2000, end 413ff539 ... OK

 

Starting kernel ...

 

 

atags: 0x413F2000

413F2000: EDFE0DD0 3AD50000 48000000 849E0000  28000000 11000000 10000000 00000000

413F2020: 22070000 3C9E0000 00000000 0040A843  00000000 EF742700 00000000 00000000

413F2040: 00000000 00000000 01000000 00000000  03000000 04000000 00000000 01000000

413F2060: 03000000 04000000 0F000000 01000000  03000000 04000000 1B000000 01000000

413F2080: 03000000 38000000 2C000000 65697266  796C646E 2C6D7261 796E6974 32313434

413F20A0: 6D617300 676E7573 7978652C 34736F6E  00323134 736D6173 2C676E75 6E797865

413F20C0: 0034736F 03000000 2F000000 37000000  65697246 796C646E 204D5241 594E4954

413F20E0: 32313434 616F6220 62206472 64657361  206E6F20 6E797845 3434736F 00003231

 

Uncompressing Linux... done, booting the kernel.

 

 

atags: 0x413F2000

413F2000: EDFE0DD0 3AD50000 48000000 849E0000  28000000 11000000 10000000 00000000

413F2020: 22070000 3C9E0000 00000000 0040A843  00000000 EF742700 00000000 00000000

413F2040: 00000000 00000000 01000000 00000000  03000000 04000000 00000000 01000000

413F2060: 03000000 04000000 0F000000 01000000  03000000 04000000 1B000000 01000000

413F2080: 03000000 38000000 2C000000 65697266  796C646E 2C6D7261 796E6974 32313434

413F20A0: 6D617300 676E7573 7978652C 34736F6E  00323134 736D6173 2C676E75 6E797865

413F20C0: 0034736F 03000000 2F000000 37000000  65697246 796C646E 204D5241 594E4954

413F20E0: 32313434 616F6220 62206472 64657361  206E6F20 6E797845 3434736F 00003231

 

[    0.000000] Booting Linux on physical CPU 0xa00

[    0.000000] Linux version 4.4.0-gbd49c0f-dirty (root@ubuntu) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #25 SMP PREEMPT Tue Jan 19 05:50:47 PST 2016

[    0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d

[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache

[    0.000000] Machine model: FriendlyARM TINY4412 board based on Exynos4412

[    0.000000] bootconsole [earlycon0] enabled

[    0.000000] cma: Reserved 64 MiB at 0x7bc00000

[    0.000000] Memory policy: Data cache writealloc

[    0.000000] Samsung CPU ID: 0xe4412011

[    0.000000] PERCPU: Embedded 12 pages/cpu @ef79b000 s18816 r8192 d22144 u49152

[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260352

[    0.000000] Kernel command line: root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200 init=/linuxrc earlyprintk

[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)

[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)

[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)

[    0.000000] Memory: 960824K/1047552K available (5867K kernel code, 293K rwdata, 2288K rodata, 440K init, 315K bss, 21192K reserved, 65536K cma-reserved, 195584K highmem)

[    0.000000] Virtual kernel memory layout:

[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)

[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)

[    0.000000]     vmalloc : 0xf0800000 - 0xff800000   ( 240 MB)

[    0.000000]     lowmem  : 0xc0000000 - 0xf0000000   ( 768 MB)

[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)

[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)

[    0.000000]       .text : 0xc0008000 - 0xc07ff200   (8157 kB)

[    0.000000]       .init : 0xc0800000 - 0xc086e000   ( 440 kB)

[    0.000000]       .data : 0xc086e000 - 0xc08b7418   ( 294 kB)

[    0.000000]        .bss : 0xc08ba000 - 0xc0908d28   ( 316 kB)

可以看到 Uncompressing Linux... done, booting the kernel.前后就是dump出的设备树的内容(大小端 可能有些问题).

五、CONFIG_ARM_APPENDED_DTB

这个宏是Linux内核中的,它的作用是支持zImage+dtb的启动方式。为什么要有种方式呢?因为很多厂家都有自己的bootloader,但是这些bootloader并不都一定支持设备树,为了实现支持设备树启动,就引入了这种启动方式,即将编译出的zImage和编译出的设备树镜像文件拼成一个新的镜像,在内核的自解压代码中会识别到,不会出现自解压时导致设备树被覆盖,具体实现如下(arch/arm/boot/compressed/head.S)

mov    r5, #0            @ init dtb size to 0

#ifdef CONFIG_ARM_APPENDED_DTB

/*

*   r0  = delta

*   r2  = BSS start

*   r3  = BSS end

*   r4  = final kernel address (possibly with LSB set)

*   r5  = appended dtb size (still unknown)

*   r6  = _edata

*   r7  = architecture ID

*   r8  = atags/device tree pointer

*   r9  = size of decompressed image

*   r10 = end of this image, including  bss/stack/malloc space if non XIP

*   r11 = GOT start

*   r12 = GOT end

*   sp  = stack pointer

*

* if there are device trees (dtb) appended to zImage, advance r10 so that the

* dtb data will get relocated along with the kernel if necessary.

*/

 

ldr    lr, [r6, #0]

#ifndef __ARMEB__

ldr    r1, =0xedfe0dd0        @ sig is 0xd00dfeed big endian

#else

ldr    r1, =0xd00dfeed

#endif

cmp    lr, r1

bne    dtb_check_done        @ not found

 

#ifdef CONFIG_ARM_ATAG_DTB_COMPAT

/*

 * OK... Let's do some funky business here.

 * If we do have a DTB appended to zImage, and we do have

 * an ATAG list around, we want the later to be translated

 * and folded into the former here. No GOT fixup has occurred

 * yet, but none of the code we're about to call uses any

 * global variable.

*/

 

/* Get the initial DTB size */

ldr    r5, [r6, #4]

#ifndef __ARMEB__

/* convert to little endian */

eor    r1, r5, r5, ror #16

bic    r1, r1, #0x00ff0000

mov    r5, r5, ror #8

eor    r5, r5, r1, lsr #8

#endif

/* 50% DTB growth should be good enough */

add    r5, r5, r5, lsr #1

/* preserve 64-bit alignment */

add    r5, r5, #7

bic    r5, r5, #7

/* clamp to 32KB min and 1MB max */

cmp    r5, #(1 <;< 15)

movlo    r5, #(1 <;< 15)

cmp    r5, #(1 <;< 20)

movhi    r5, #(1 <;< 20)

/* temporarily relocate the stack past the DTB work space */

add    sp, sp, r5

 

stmfd    sp!, {r0-r3, ip, lr}

mov    r0, r8

mov    r1, r6

mov    r2, r5

bl    atags_to_fdt

 

/*

 * If returned value is 1, there is no ATAG at the location

 * pointed by r8.  Try the typical 0x100 offset from start

 * of RAM and hope for the best.

 */

cmp    r0, #1

sub    r0, r4, #TEXT_OFFSET

bic    r0, r0, #1

add    r0, r0, #0x100

mov    r1, r6

mov    r2, r5

bleq    atags_to_fdt

 

ldmfd    sp!, {r0-r3, ip, lr}

sub    sp, sp, r5

#endif

 

mov    r8, r6            @ use the appended device tree

 

/*

 * Make sure that the DTB doesn't end up in the final

 * kernel's .bss area. To do so, we adjust the decompressed

 * kernel size to compensate if that .bss size is larger

 * than the relocated code.

 */

ldr    r5, =_kernel_bss_size

adr    r1, wont_overwrite

sub    r1, r6, r1

subs    r1, r5, r1

addhi    r9, r9, r1

 

/* Get the current DTB size */

ldr    r5, [r6, #4]

#ifndef __ARMEB__

/* convert r5 (dtb size) to little endian */

eor    r1, r5, r5, ror #16

bic    r1, r1, #0x00ff0000

mov    r5, r5, ror #8

eor    r5, r5, r1, lsr #8

#endif

 

/* preserve 64-bit alignment */

add    r5, r5, #7

bic    r5, r5, #7

 

/* relocate some pointers past the appended dtb */

add    r6, r6, r5

add    r10, r10, r5

add    sp, sp, r5

dtb_check_done:

#endif

拼接方法:

cat zImage dts/exynos4412-tiny4412.dtb > dtbImage

也可以修改内核编译系统,在编译完成后自动实现拼接,可以参考下面的博文实现:

http://www.cnblogs.com/pengdonglin137/p/5134364.html

下面是使用dtbImage启动的方法:

1、修改设备树 arch/arm/boot/dts/exynos4412-tiny4412.dts

diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts

index 4840bbd..1e33ede 100644

--- a/arch/arm/boot/dts/exynos4412-tiny4412.dts

+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts

@@ -21,6 +21,7 @@

 

        chosen {

                stdout-path = &;serial_0;

+               bootargs = "root=/dev/ram0 rw rootfstype=ext4 ramdisk=8192 initrd=0x41000000,8M console=ttySAC0,115200 init=/linuxrc mem=1024M"

        };


        memory {

@@ -78,7 +79,7 @@

        bus-width = <;4>;

        pinctrl-0 = <;&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;

        pinctrl-names = "default";

-       status = "okay";

+       status = "disabled";

 };

 

 &;serial_0 {

2、编译设备树 make dtbs,将生成的.dtb跟zImag拼接起来生成dtbImage

3、使用ramdisk启动,目前不能使用ramdisk.img,还不知道为什么。

4、启动开发板,进入u-boot命令行模式,执行如下命令:

在u-boot里执行下载dtbImage的命令: dnw 0x40008000

在开发机上执行: dnw dtbImage

在u-boot里执行下载ramdisk的命令:dnw 0x41000000

在开发机上执行: dnw ramdisk

启动内核: bootm 0x40008000   (u-boot不识别未压缩的ramdisk,ramdisk的地址在bootargs中指定为0x41000000,而且上面我们已经把ramdisk下载到0x41000000了)

下面是完整的log:

U-Boot 2010.12-00000-gb391276-dirty (Jan 17 2016 - 06:03:22) for TINY4412

 

 

CPU:    S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]

        APLL = 1400MHz, MPLL = 800MHz

 

Board:  TINY4412

DRAM:   1023 MiB

 

vdd_arm: 1.2

vdd_int: 1.0

vdd_mif: 1.1

 

BL1 version:  N/A (TrustZone Enabled BSP)

 

 

Checking Boot Mode ... SDMMC

REVISION: 1.1

MMC Device 0: 3803 MB

MMC Device 1: 3728 MB

MMC Device 2: N/A

*** Warning - using default environment

 

Net:    No ethernet found.

Hit any key to stop autoboot:  0 

TINY4412 # dnw 0x40008000

OTG cable Connected!

Now, Waiting for DNW to transmit data

Download Done!! Download Address: 0x40008000, Download Filesize:0x446302

Checksum is being calculated.....

Checksum O.K.

TINY4412 # dnw 0x41000000

OTG cable Connected!

Now, Waiting for DNW to transmit data

Download Done!! Download Address: 0x41000000, Download Filesize:0x800000

Checksum is being calculated.........

Checksum O.K.

TINY4412 # bootm 0x40008000

Boot with zImage

 

Starting kernel ...

 

 

atags: 0x40CF68E8

40CF68E8: EDFE0DD0 72A50000 38000000 749E0000  28000000 11000000 10000000 00000000

40CF6908: FE060000 3C9E0000 00000000 00000000  00000000 00000000 01000000 00000000

40CF6928: 03000000 04000000 00000000 01000000  03000000 04000000 0F000000 01000000

40CF6948: 03000000 04000000 1B000000 01000000  03000000 38000000 2C000000 65697266

40CF6968: 796C646E 2C6D7261 796E6974 32313434  6D617300 676E7573 7978652C 34736F6E

40CF6988: 00323134 736D6173 2C676E75 6E797865  0034736F 03000000 2F000000 37000000

40CF69A8: 65697246 796C646E 204D5241 594E4954  32313434 616F6220 62206472 64657361

40CF69C8: 206E6F20 6E797845 3434736F 00003231  01000000 736F6863 00006E65 03000000

 

Uncompressing Linux... done, booting the kernel.

 

 

atags: 0x40CF68E8

40CF68E8: EDFE0DD0 72A50000 38000000 749E0000  28000000 11000000 10000000 00000000

40CF6908: FE060000 3C9E0000 00000000 00000000  00000000 00000000 01000000 00000000

40CF6928: 03000000 04000000 00000000 01000000  03000000 04000000 0F000000 01000000

40CF6948: 03000000 04000000 1B000000 01000000  03000000 38000000 2C000000 65697266

40CF6968: 796C646E 2C6D7261 796E6974 32313434  6D617300 676E7573 7978652C 34736F6E

40CF6988: 00323134 736D6173 2C676E75 6E797865  0034736F 03000000 2F000000 37000000

40CF69A8: 65697246 796C646E 204D5241 594E4954  32313434 616F6220 62206472 64657361

40CF69C8: 206E6F20 6E797845 3434736F 00003231  01000000 736F6863 00006E65 03000000

 

[    0.000000] Booting Linux on physical CPU 0xa00

[    0.000000] Linux version 4.4.0-gbd49c0f-dirty (root@ubuntu) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #25 SMP PREEMPT Tue Jan 19 05:50:47 PST 2016

[    0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d

[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache

[    0.000000] Machine model: FriendlyARM TINY4412 board based on Exynos4412

[    0.000000] cma: Reserved 64 MiB at 0x7c000000

[    0.000000] Memory policy: Data cache writealloc

[    0.000000] Samsung CPU ID: 0xe4412011

[    0.000000] PERCPU: Embedded 12 pages/cpu @ef79b000 s18816 r8192 d22144 u49152

[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260608

[    0.000000] Kernel command line: root=/dev/ram0 rw rootfstype=ext4 ramdisk=8192 initrd=0x41000000,8M console=ttySAC0,115200 init=/linuxrc mem=1024M

[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)

[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)

[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)

[    0.000000] Memory: 956196K/1048576K available (5867K kernel code, 293K rwdata, 2288K rodata, 440K init, 315K bss, 26844K reserved, 65536K cma-reserved, 196608K highmem)

[    0.000000] Virtual kernel memory layout:

[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)

[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)

[    0.000000]     vmalloc : 0xf0800000 - 0xff800000   ( 240 MB)

[    0.000000]     lowmem  : 0xc0000000 - 0xf0000000   ( 768 MB)

[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)

[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)

[    0.000000]       .text : 0xc0008000 - 0xc07ff200   (8157 kB)

[    0.000000]       .init : 0xc0800000 - 0xc086e000   ( 440 kB)

[    0.000000]       .data : 0xc086e000 - 0xc08b7418   ( 294 kB)

[    0.000000]        .bss : 0xc08ba000 - 0xc0908d28   ( 316 kB)

[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1

[    0.000000] Preemptible hierarchical RCU implementation.

[    0.000000]  Build-time adjustment of leaf fanout to 32.

[    0.000000]  RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.

[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=4

[    0.000000] NR_IRQS:16 nr_irqs:16 16

[    0.000000] GIC physical location is 0x10490000

[    0.000000] L2C: platform modifies aux control register: 0x02070000 ->; 0x3e470001

[    0.000000] L2C: platform provided aux values permit register corruption.

[    0.000000] L2C: DT/platform modifies aux control register: 0x02070000 ->; 0x3e470001

[    0.000000] L2C-310 enabling early BRESP for Cortex-A9

[    0.000000] L2C-310: enabling full line of zeros but not enabled in Cortex-A9

[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled

[    0.000000] L2C-310 cache controller enabled, 16 ways, 1024 kB

[    0.000000] L2C-310: CACHE_ID 0x4100c4c8, AUX_CTRL 0x4e470001

[    0.000000] Exynos4x12 clocks: sclk_apll = 466666667, sclk_mpll = 800000000

[    0.000000]  sclk_epll = 96000000, sclk_vpll = 108000000, arm_clk = 1400000000

[    0.000000] Switching to timer-based delay loop, resolution 41ns

[    0.000000] clocksource: mct-frc: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns

[    0.000003] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns

[    0.000122] Console: colour dummy device 80x30

[    0.000135] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=120000)

[    0.000144] pid_max: default: 32768 minimum: 301

[    0.000209] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)

[    0.000217] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes)

[    0.000586] CPU: Testing write buffer coherency: ok

[    0.000772] CPU0: thread -1, cpu 0, socket 10, mpidr 80000a00

[    0.000999] Setting up static identity map for 0x400082c0 - 0x40008318

[    0.045048] CPU1: thread -1, cpu 1, socket 10, mpidr 80000a01

[    0.060041] CPU2: thread -1, cpu 2, socket 10, mpidr 80000a02

[    0.075042] CPU3: thread -1, cpu 3, socket 10, mpidr 80000a03

[    0.075082] Brought up 4 CPUs

[    0.075096] SMP: Total of 4 processors activated (192.00 BogoMIPS).

[    0.075101] CPU: All CPU(s) started in SVC mode.

[    0.075611] devtmpfs: initialized

[    0.084566] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4

[    0.084839] lcd0-power-domain@10023C80 has as child subdomain: tv-power-domain@10023C20.

[    0.085225] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 9556302231375000 ns

[    0.087164] pinctrl core: initialized pinctrl subsystem

[    0.087929] NET: Registered protocol family 16

[    0.089226] DMA: preallocated 256 KiB pool for atomic coherent allocations

[    0.105005] cpuidle: using governor ladder

[    0.120000] cpuidle: using governor menu

[    0.120747] exynos-audss-clk 3810000.clock-controller: setup completed

[    0.157138] SCSI subsystem initialized

[    0.157506] usbcore: registered new interface driver usbfs

[    0.157580] usbcore: registered new interface driver hub

[    0.157660] usbcore: registered new device driver usb

[    0.158780] Advanced Linux Sound Architecture Driver Initialized.

[    0.159857] clocksource: Switched to clocksource mct-frc

[    0.169153] missing cooling_device property

[    0.169163] failed to build thermal zone cpu-thermal: -2

[    0.169260] NET: Registered protocol family 2

[    0.169627] TCP established hash table entries: 8192 (order: 3, 32768 bytes)

[    0.169686] TCP bind hash table entries: 8192 (order: 5, 163840 bytes)

[    0.169803] TCP: Hash tables configured (established 8192 bind 8192)

[    0.169921] UDP hash table entries: 512 (order: 2, 24576 bytes)

[    0.169950] UDP-Lite hash table entries: 512 (order: 2, 24576 bytes)

[    0.170092] NET: Registered protocol family 1

[    0.170297] RPC: Registered named UNIX socket transport module.

[    0.170305] RPC: Registered udp transport module.

[    0.170310] RPC: Registered tcp transport module.

[    0.170315] RPC: Registered tcp NFSv4.1 backchannel transport module.

[    0.170461] Trying to unpack rootfs image as initramfs...

[    0.170628] rootfs image is not initramfs (junk in compressed archive); looks like an initrd

[    0.193515] Freeing initrd memory: 8192K (c1000000 - c1800000)

[    0.194996] futex hash table entries: 1024 (order: 4, 65536 bytes)

[    0.204233] romfs: ROMFS MTD (C) 2007 Red Hat, Inc.

[    0.204924] bounce: pool size: 64 pages

[    0.204936] io scheduler noop registered

[    0.204945] io scheduler deadline registered

[    0.205116] io scheduler cfq registered (default)

[    0.209955] dma-pl330 12680000.pdma: Loaded driver for PL330 DMAC-141330

[    0.209967] dma-pl330 12680000.pdma:         DBUFF-32x4bytes Num_Chans-8 Num_Peri-32 Num_Events-32

[    0.213022] dma-pl330 12690000.pdma: Loaded driver for PL330 DMAC-141330

[    0.213032] dma-pl330 12690000.pdma:         DBUFF-32x4bytes Num_Chans-8 Num_Peri-32 Num_Events-32

[    0.213909] dma-pl330 12850000.mdma: Loaded driver for PL330 DMAC-141330

[    0.213919] dma-pl330 12850000.mdma:         DBUFF-64x8bytes Num_Chans-8 Num_Peri-1 Num_Events-32

[    0.271176] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled

[    0.272413] 13800000.serial: ttySAC0 at MMIO 0x13800000 (irq = 44, base_baud = 0) is a S3C6400/10

[    0.908554] console [ttySAC0] enabled

[    0.912530] 13810000.serial: ttySAC1 at MMIO 0x13810000 (irq = 45, base_baud = 0) is a S3C6400/10

[    0.921327] 13820000.serial: ttySAC2 at MMIO 0x13820000 (irq = 46, base_baud = 0) is a S3C6400/10

[    0.930171] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 47, base_baud = 0) is a S3C6400/10

[    0.939720] [drm] Initialized drm 1.1.0 20060810

[    0.953371] brd: module loaded

[    0.958359] loop: module loaded

[    0.959171] usbcore: registered new interface driver r8152

[    0.959302] usbcore: registered new interface driver asix

[    0.960434] usbcore: registered new interface driver ax88179_178a

[    0.966498] usbcore: registered new interface driver cdc_ether

[    0.972325] usbcore: registered new interface driver dm9601

[    0.977884] usbcore: registered new interface driver smsc75xx

[    0.983611] usbcore: registered new interface driver smsc95xx

[    0.989325] usbcore: registered new interface driver net1080

[    0.994965] usbcore: registered new interface driver cdc_subset

[    1.000873] usbcore: registered new interface driver zaurus

[    1.006454] usbcore: registered new interface driver cdc_ncm

[    1.012397] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver

[    1.018528] ehci-exynos: EHCI EXYNOS driver

[    1.022808] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver

[    1.028850] ohci-exynos: OHCI EXYNOS driver

[    1.033363] usbcore: registered new interface driver usb-storage

[    1.039544] mousedev: PS/2 mouse device common for all mice

[    1.045326] s3c-rtc 10070000.rtc: failed to find rtc source clock

[    1.050645] s3c-rtc: probe of 10070000.rtc failed with error -2

[    1.056739] i2c /dev entries driver

[    1.062046] device-mapper: ioctl: 4.34.0-ioctl (2015-10-28) initialised: dm-devel@redhat.com

[    1.069226] sdhci: Secure Digital Host Controller Interface driver

[    1.074585] sdhci: Copyright(c) Pierre Ossman

[    1.079056] Synopsys Designware Multimedia Card Interface Driver

[    1.086865] usbcore: registered new interface driver usbhid

[    1.090471] usbhid: USB HID core driver

[    1.097222] NET: Registered protocol family 10

[    1.099233] sit: IPv6 over IPv4 tunneling driver

[    1.103848] NET: Registered protocol family 17

[    1.107765] NET: Registered protocol family 15

[    1.112340] Registering SWP/SWPB emulation handler

[    1.118177] hctosys: unable to open rtc device (rtc0)

[    1.134172] ALSA device list:

[    1.134208]   No soundcards found.

[    1.134917] RAMDISK: ext2 filesystem found at block 0

[    1.134972] RAMDISK: Loading 8192KiB [1 disk] into ram disk... done.

[    1.262918] EXT4-fs (ram0): mounted filesystem with red data mode. Opts: (null)

[    1.263014] VFS: Mounted root (ext4 filesystem) on device 1:0.

[    1.263132] devtmpfs: mounted

[    1.263411] Freeing unused kernel memory: 440K (c0800000 - c086e000)

 

Please press Enter to activate this console. 

[root@tiny4412 ]# 

[root@tiny4412 ]# 

最新文章

  1. selenium常用的js总结
  2. js中网页高度与宽度那些事
  3. Apache常用配置项
  4. [vim]vim 在win下乱码解决
  5. JAVA基础知识之Collections工具类
  6. JQuery插件之图片轮播插件–slideBox
  7. 基于Qt的P2P局域网聊天及文件传送软件设计
  8. RocketMQ入门(3)拉取消息
  9. unix-环境高级编程-读书笔记与习题解答-第三篇
  10. TCP Linger的坑
  11. 浅谈android的selector,背景选择器
  12. body全屏
  13. DFB系列 之 Flip()更新buffe
  14. vue-cli——vue-resource登录注册实例
  15. 菜鸟系列docker——docker基本概念(1)
  16. linux 环境变量函数getenv()和putenv()的使用
  17. Powerdesigner设计表生成SQL脚本(带有注释)
  18. Tensorflow动态seq2seq使用总结(r1.3)
  19. WEB网页监控系统的设计框架思路具体解释
  20. LeetCode 79 Word Search(单词查找)

热门文章

  1. 使用 Visual Studio 部署 .NET Core 应用 ——.Net Core 部署到SUSE Linux Enterprise Server 12 SP2 64 位(GNOME 版本3.20.2)
  2. MiCode108 猜数字
  3. LightOJ - 1370
  4. mac下谷歌chrome浏览器的快捷键
  5. opencv中矩阵计算的一些函数
  6. [转载]Python logging模块详解
  7. AIOps实践三板斧:从可视化、自动化到智能化
  8. asp.net webform 打造私人后台管理系统(附源码)
  9. Codeforces 1082 D. Maximum Diameter Graph-树的直径-最长链-构造题 (Educational Codeforces Round 55 (Rated for Div. 2))
  10. 【ModelMap】jsp中显示springmvc modelmap传递的对象