U-boot如何引导Linux内核启动

U-BOOT 全线移植分析系列之四 ―― U-boot 如何引导Linux 内核启动?

 

Sailor_forever  sailing_9806@163.com 转载请注明

http://blog.csdn.net/sailor_8318/archive/2008/08/05/2773412.aspx

 

【摘要】本节介绍了 U-boot 使用 go bootm 启动 linux 内核的方法。首先 介绍了 mkimage 的参数意义和 bootm 的详细执行流程。然后分析了如何利用 mkimage 生成内核映象的方法。 对于 bootm 方式的内核是否压缩、- a 、- e 、运行地址等 16 种组合情况,给出了详细的测试过程,提出了 6 种可用方法种的三种最优解。

 

【关键字】: U-boot AT91RM9200 bootm mkimage ;- a ;- e ;- c

 

U-boot 如何引导 Linux 内核启动?

4.1  GO 命令引导未用 mkimage 生成的内核

4.1.1 非压缩内核 Image

1)        运行地址!= 链接地址 0x20008000 ,不能启动

Uboot> tftp 21000000 Image;tftp 21100000 ramdisk;go 21000000

。。。。

done

Bytes transferred = 6993691 (6ab71b hex)

## Starting application at 0x21000000 ...

Error: a 在哪提示的?

 

2)        运行地址=链接地址 0x20008000 不能启动,难道是 ramdisk 的问题

Uboot> tftp 20008000 Image;tftp 21100000 ramdisk;go 20008000

。。。。

done

Bytes transferred = 6993691 (6ab71b hex)

## Starting application at 0x21000000 ...

Error: a

 

4.1.2 压缩内核 zImage

1)        运行地址!=链接地址 0x20008000 ,能启动,内核自解压成功, 但是解压后的内核运行错误

Uboot> tftp 21000000 zImage;tftp 21100000 ramdisk;go 21000000

。。。。。。。。。。。

done

Bytes transferred = 6993691 (6ab71b hex)

## Starting application at 0x21000000 ...

Uncompressing Linux............................................................. don e, booting the kernel.

€?~?? 鄜屈

 

2)        运行地址==链接地址 0x20008000 ,能启动,内核自解压成功, 但是解压后的内核运行错误

 

Uboot> tftp 20008000 zImage;tftp 21100000 ramdisk; go 20008000

## Starting application at 0x20008000 ...

Uncompressing Linux............................................................. done, booting the kernel .

€?~?? 鄜屈

 

上面的 ramdisk 都是添加了 uboot 的头的,去掉头部再试试。去掉了还是不行, go 方法的 ramdisk 的地址是怎么设置的??要详细看下 uboot ramdisk 这块是如何跟内核交互的?

 

4.2 Mkimage 参数意义解析

通过 mkimage 这个 tool 可以给 zImage 添加一个 header

typedef struct image_header {

        uint32_t    ih_magic; /* Image Header Magic Number      */

        uint32_t    ih_hcrc;    /* Image Header CRC Checksum    */

        uint32_t    ih_time;    /* Image Creation Timestamp   */

        uint32_t    ih_size;     /* Image Data Size           */

        uint32_t    ih_load;    /* Data     Load  Address              */

        uint32_t    ih_ep;              /* Entry Point Address             */

        uint32_t    ih_dcrc;    /* Image Data CRC Checksum        */

        uint8_t             ih_os;               /* Operating System         */

        uint8_t             ih_arch;    /* CPU architecture         */

        uint8_t             ih_type;    /* Image Type                  */

        uint8_t             ih_comp;  /* Compression Type                */

        uint8_t             ih_name[IH_NMLEN];    /* Image Name                */

} image_header_t;

 

header 是如何生成的?利用 u-boot 里面的 mkimage 工具来生成 uImage   u-boot 源码包 /tools/mkimage.c )

这里解释一下参数的意义:

-A ==> set architecture to 'arch'

-O ==> set operating system to 'os'

-T ==> set image type to 'type' “kernel 或是 ramdisk”

-C ==> set compression type 'comp'

-a ==> set load address to 'addr' (hex)

-e ==> set entry point to 'ep' (hex) (内核启动时在此位置查询完整的内核印象)

-n ==> set image name to 'name'

-d ==> use image d ata from 'datafile'

-x ==> set XIP (execute in place ,即不进行文件的拷贝,在当前位置执行 )

 

对于 ARM linux 内核映象用法:

-A arm     -------- 架构是 arm
-O linux    --------
操作系统是
linux
-T kernel  --------
类型是
kernel
-C none/bzip/gzip    --------
压缩类型

-a 20008000 ---- image
的载入地址 (hex) ,通常为 0xX00008000
-e 200080XX----
内核的入口地址 (hex) XX 0x40 或者
0x00
-n linux-XXX --- image
的名字,任意

-d nameXXX             ----
无头信息的 image 文件名,你的源内核文件
uImageXXX    ----
加了头信息之后的 image 文件名,任意取

 

4.3 Bootm 的流程分析

Bootm 命令在 /common/cmd_bootm.c do_bootm 函数

 

》》》》》》》》》》》获取当前内核的地址,默认地址或者 bootm 的第一个参数

默认的加载地址或传递给 bootm 命令(优先)与实际的内核存放地址需要一致

if (argc < 2) {

                addr = load_addr; // load_addr = CFG_LOAD_ADDR;

        } else {

                addr = simple_strtoul(argv[1], NULL, 16);

        }

printf ("## Booting image at %08lx .../n", addr);

 

》》》》》》》》》》》》获得 image 头, 没有 mkimage 的就返回了

memmove (&header, (char *)addr, sizeof(image_header_t));

 

》》》》》》》》》》》》打印头部信息

print_image_hdr ((image_header_t *)addr);

实例:

Image Name:   dd-kernel-2.4.19

   Image Type:   ARM Linux Kernel Image (gzip compressed)

   Data Size:    869574 Bytes = 849.2 kB

   Load Address: 20008000

   Entry Point:  20008000

 

》》》》》》》》》》》》校验 image 头部

printf ("   Verifying Checksum ... ");       printf ("OK/n");

 

》》》》》》》》》》》》检查 image 支持的体系结构即 —A 选项是否为 arm 或者 ppc

 

》》》》》》》》》》》》检查 image 的类型

TYPE_MULTI 是否指内核与文件系统一起,内核后面有个分界线

switch (hdr->ih_type)

case IH_TYPE_KERNEL:

                name = "Kernel Image";

                break;

        case IH_TYPE_MULTI:

 

》》》》》》》》》》判断内核的压缩类型

此处的内核是否压缩非 zImage Image 的概念,而是指内核在被 mkimage 处理前是否用 gunzip 等压缩过

switch (hdr->ih_comp) {  

        case IH_COMP_NONE:         // 非压缩内核

                if(ntohl(hdr->ih_load) == addr) {      

// 当前内核存放的地址与- a 指定的一致,则不搬动,- e 必须必- a 0x40

                       printf ("   XIP %s ... ", name);

                } else {

// 当前内核存放的地址与- a 指定的不一致,则将内核搬到- a 地址,此时- a 与- e 必相同

memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);

。。。。

case IH_COMP_GZIP:

                printf ("   Uncompressing %s ... ", name);

                if (gunzip ( (void *)ntohl(hdr->ih_load) , unc_len,

// 压缩内核,将除去头部的内核解压到 -a 指定的地址了,要求- a 与- e 相同

// 为防止解压缩时覆盖,对于压缩内核,内核存放地址最好在 —a 后面

                           (uchar *)data, (int *)&len) != 0) {

                       do_reset (cmdtp, flag, argc, argv);

                }

                break;

 

》》》》》》》》》》》》》》》》判断操作系统类型

switch (hdr->ih_os) {

        default:                    /* handled by (original) Linux case */

        case IH_OS_LINUX:

            do_bootm_linux  (cmdtp, flag, argc, argv, addr , len_ptr, verify);        

// 前四个为传给 bootm 的, addr 为内核最初的存放地址,没有用处

            break;

 

#ifdef CONFIG_PPC

static boot_os_Fcn do_bootm_linux;

#else

extern boot_os_Fcn do_bootm_linux;

由上可知,对于 ppc 和其他体系结构的 do_bootm_linux 函数实现是不一样的

》》》》》》》》》》》》》》启动 Linux 内核

do_bootm_linux (cmd_tbl_t *cmdtp, int flag,

                int    argc, char *argv[],

                ulong        addr,

                ulong        *len_ptr,

                int    verify)

 

》》》》》》》》》》》》获取命令行参数

if ((s = getenv("bootargs")) == NULL)

                s = "";

        strcpy (cmdline, s);

 

》》》》》》》》》》》》赋内核启动地址

kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong)) hdr->ih_ep;

注意,对于压缩过的内核,会将内核解压到 -a 指定的地址, 此时 -a -e 地址必须相同

 

》》》》》》》》》》》判断 bootm 的命令参数中是否有 initrd

        if (argc >= 3) {

                addr = simple_strtoul(argv[2], NULL, 16);

                printf ("## Loading RAMDisk Image at %08lx .../n", addr);

 

若有 initrd 则赋值,否则为 0

 

》》》》》》》》》》》》》》》启动 Linux 内核

/*

          * Linux Kernel Parameters:

          *    r3 : ptr to board info data

          *   r4: initrd_start or 0 if no initrd

          *   r5: initrd_end - unused if r4 is 0

          *   r6: Start of command line string

          *   r7: End   of command line string

          */

//*kbd = *(gd->bd); 在上面赋值的

        (*kernel) ( kbd , initrd _start, initrd_end, cmd_start, cmd_end);

 

启动流程的总结:

 

对于 gzip 压缩的内核 bootm 命令会首先判断 bootm xxxx 这个指定的地址 xxxx 是否与 -a 指定的加载地址相同。

(1) 如果不同的话会从这个地址开始提取出这个 64byte 的头部,对其进行分析,然后把去掉头部的内核复制到 -a 指定的 load 地址中去运行之(此时- e 选型必须同 -a

(2) 如果相同的话那就让其原封不动的放在那,但 -e 指定的入口地址会推后 64byte ,以跳过这 64byte 的头部。

 

对于 gzip 压缩过的内核,因为 u-boot 要对其解压, 因此运行地址是不能等于- a 指定的地址的,且必须有一定的间隔, 否则解压到- a 的内核会覆盖当前运行的程序。此时要求- a 等于- e 指定的地址。

 

4.4 如何用 mkimage 生成 uImage

 

1> mkimage 如何指定入口参数 ( -e  0xxxxxx)

2> mkimage 指定了入口参数后, 你用 tftpboot 下载 kernel 到哪个地址?

3> -c 如何指定?

 

u boot 里面的解压和内核自解压的区别: u-boot 里面的解压实际上是 bootm 实现的 mkimage -C bzip2 或者 gzip 生成的 uImage 进行解压 kernel 的自解压是对 zImage 进行解压,发生在 bootm 解压之后。

 

U-boot 对内核添加头部时,前面已经用 gzip 压缩过一次内核了,而不是指原有的内核印象是否是压缩内核。 uImage 本身被压缩了,即对原来的 zImage/Image 添加了 U-boot 的压缩方式,使得生成的 uImage 变小了。 此时- c gzip

若没有对 zImage/Image gzip 命令压缩过,则 -c none

 

综合上面分析, mkimage 的影响因子为:

e ,内核的入口地址是否与- a 相同

Tftpaddr ,即将内核加载到 RAM 中运行的地址,决定是否搬运或解压内核

c ,内核是否经过 gzip 压缩过,决定了是搬运还是解压

 

另外内核本身为非压缩的 Image zImage 也是一个影响因子。组合情况共 2^4 =16

 

4.5 Bootm 命令引导 mkimage 生成的内核全程解析

4.5.1 非压缩的 Image 内核

 

1 Mkimage 之前用 gzip Image 进行压缩

<1> -a=-e = 0x20008000 tftpaddr= 0x21000000

解压到- a 指定的地址,成功启动

Uboot> tftp 21000000 uImage-zip-8000;tftp 21100000 ramdisk;bootm 21000000

## Booting image at 21000000 ...

   Image Name:   dd-kernel-2.4.19-zip-8000

   Image Type:   ARM Linux Kernel Image (gzip compressed)

   Data Size:    869629 Bytes = 849.2 kB

   Load Address: 20008000

   Entry Point:  20008000

   Verifying Checksum ... OK

   Uncompressing Kernel Image ... OK

 

Starting kernel ...

 

Linux version 2.4.19-rmk7 (root@dding) (gcc version 2.95.3 20010315 (release)) #42 10 11 14:15:35 CST 2007

AT91RM9200DK login: root

 

<2> -a=-e = 0x20008000 tftpaddr= 0x20008000

解压失败,启动失败

Uboot> tftp 20008000 uImage-zip-zImage-8000;tftp 21100000 ramdisk;bootm 20008000

 

Uboot> tftp 20008000 uImage-zip-8000;tftp 21100000 ramdisk;bootm 20008000

## Booting image at 20008000 ...

   Image Name:   dd-kernel-2.4.19-zip-8000

   Image Type:   ARM Linux Kernel Image (gzip compressed)

   Data Size:    869629 Bytes = 849.2 kB

   Load Address: 20008000

   Entry Point:  20008000

   Verifying Checksum ... OK

   Uncompressing Kernel Image ... Error: inflate() returned -3

GUNZIP ERROR - must RESET board to recover

由于当前运行地址 tftpaddr 与解压缩后的地址- a 重合了,导致解压缩失败,因此二者必须相隔一定的距离

 

<3> -a=0x20008000 -e = 0x20008040 tftpaddr= 0x21000000

能够解压到- a 地址,但- e 指定的入口不对,启动失败

 

Uboot> tftp 21000000 uImage-zip-8040;tftp 21100000 ramdisk;bootm 21000000

 

TFTP from server 192.168.0.12; our IP address is 192.168.0.15

Filename 'uImage-zip-8040'.

Load address: 0x21000000

。。。。。。。。。

## Booting image at 21000000 ...

   Image Name:   dd-kernel-2.4.19-zip-8040

   Image Type:   ARM Linux Kernel Image (gzip compressed)

   Data Size:    869629 Bytes = 849.2 kB

   Load Address: 20008000

   Entry Point:  20008040

   Verifying Checksum ... OK

   Uncompressing Kernel Image ... OK

 

Starting kernel ... 死了

 

<4> -a=-e = 0x20008000 tftpaddr= 0x20008000

解压失败,入口也不对,启动失败

 

2 Mkimage 之前未对 Image 进行压缩

 

<1> -a=-e = 0x20008000 tftpaddr= 0x21000000

搬动到- a 指定的地址,成功启动

Uboot> tftp 21000000 uImage-nzip-8000;tftp 21100000 ramdisk;bootm 21000000

## Booting image at 21000000 ...

   Image Name:   dd-kernel-2.4.19-nzip-8000

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    1873059 Bytes =  1.8 MB

   Load Address: 20008000

   Entry Point:   20008000

   Verifying Checksum .. . Bad Data CRC

为什么总是校验失败呢?当前的内核印象为 1.8M ,难道太大了,后面的 ramdisk 将其覆盖??

下面未拷贝 ramdisk ,校验成功,成功启动,无法安装跟文件系统,是因为无 ramdisk 。说明上面确实是覆盖了,因此要对于大的内核印象要合理设置 tftpaddr 的地址和 ramdisk 的地址

 

Addr ramdisk )= 0x2110 0000

Addr tftpaddr )= 0x2100 0000

Addr ramdisk )- Addr tftpaddr )= 0x10 0000 1M < 1.8M

Uboot> tftp 21000000 uImage-nzip-8000;bootm 21000000

## Booting image at 21000000 ...

   Image Name:   dd-kernel-2.4.19-nzip-8000

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    1873059 Bytes =  1.8 MB

   Load Address: 20008000

   Entry Point:  20008000

    Verifying Checksum ... OK

OK

 

Starting kernel ...

 

Linux version 2.4.19-rmk7 (root@dding) (gcc version 2.95.3 20010315 (release)) #44 10 11 17:27:24 CST 2007

。。。。。。。

Kernel panic: VFS: Unable to mount root fs on 01:00

 

Addr ramdisk - 2M = 0x20f0 0000 Addr tftpaddr )成功启动

 

Uboot> tftp 20f00000 uImage-nzip-8000;tftp 21100000 ramdisk;bootm 20f00000

## Booting image at 20f00000 ...

   Image Name:   dd-kernel-2.4.19-nzip-8000

   Image Type:    ARM Linux Kernel Image (uncompressed)

   Data Size:    1873059 Bytes =  1.8 MB

   Load Address: 20008000

   Entry Point:  20008000

   Verifying Checksum ... OK

OK

 

Starting kernel ...

Linux version 2.4.19-rmk7 (root@dding) (gcc version 2.95.3 20010315 (release)) #44 10 11 17:27:24 CST 2007

AT91RM9200DK login: root

 

<2> -a=-e = 0x20008000 tftpaddr= 0x20008000

不搬动,但- e 地址不对,失败

 

<3> -a=0x20008000 -e = 0x20008040 tftpaddr= 0x20008000

不搬动,但未 成功启动,入口地址对的啊?????

Uboot> tftp 20008000 uImage-nzip-8040;tftp 21100000 ramdisk;bootm 20008000

 

## Booting image at 20008000 ...

   Image Name:   dd-kernel-2.4.19-nzip-8040

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    1873059 Bytes =  1.8 MB

   Load Address: 20008000

   Entry Point:  20008040

   Verifying Checksum ... OK

   XIP Kernel Image ... OK

 

Starting kernel ... 死了????

 

<4> -a=0x20008000 -e = 0x20008040 tftpaddr= 0x21000000

搬动,但- e 地址不对,失败

 

4.5.2 压缩的 zImage 内核

 

1 Mkimage 之前用 gzip zImage 进行压缩,即- c gzip

<1> -a=-e = 0x20008000 tftpaddr= 0x21000000

解压到- a 指定的地址,成功启动

Uboot> tftp 21000000 uImage-zip-zImage-8000;tftp 21100000 ramdisk;bootm 21000000

 

TFTP from server 192.168.0.12; our IP address is 192.168.0.15

Filename 'uImage-zip-zImage-8000'.

Load address: 0x21000000

## Booting image at 21000000 ...

   Image Name:   dd-zip-zImage-8000

   Image Type:   ARM Linux Kernel Image (gzip compressed)

   Data Size:    876753 Bytes = 856.2 kB

   Load Address: 20008000

   Entry Point:  20008000

   Verifying Checksum ... OK

   Uncompressing Kernel Image ... OK  // U-boot 对内核解压

 

Starting kernel ...

Uncompressing Linux.. ............ 压缩内核 zImage 自解压 ......................... done, booting the kernel.

 

Linux version 2.4.19-rmk7 (root@dding) (gcc version 2.95.3 20010315 (release)) #43 10

AT91RM9200DK login: root

[root@AT91RM9200DK /root]$ls

 

<2> -a=-e = 0x20008000 tftpaddr= 0x20008000

解压失败 启动失败

Uboot> tftp 20008000 uImage-zip-zImage-8000;tftp 21100000 ramdisk;bootm 20008000

 

TFTP from server 192.168.0.12; our IP address is 192.168.0.15

Filename 'uImage-zip-zImage-8000'.

Load address: 0x20008000

## Booting image at 20008000 ...

   Image Name:   dd-zip-zImage-8000

   Image Type:   ARM Linux Kernel Image (gzip compressed)

   Data Size:    876753 Bytes = 856.2 kB

   Load Address: 20008000

   Entry Point:  20008000

   Verifying Checksum ... OK

   Uncompressing Kernel Image ... Error: inflate() returned -3

GUNZIP ERROR - must RESET board to recover

由于当前运行地址 tftpaddr 与解压缩后的地址- a 重合了,导致解压缩失败,因此二者必须相隔一定的距离

 

<3> -a=0x20008000 -e = 0x20008040 tftpaddr= 0x21000000 ,失败

 

Uboot> tftp 21000000 uImage-zip-zImage-8040;tftp 21000000 ramdisk;bootm 21000000

 

TFTP from server 192.168.0.12; our IP address is 192.168.0.15

Filename 'uImage-zip-zImage-8040'.

Load address: 0x21000000

。。。。。。。。。

## Booting image at 21000000 ...

Bad Magic Number 难道对于压缩内核,幻数对的条件是- a ==- e 地址??即压缩内核默认- a ==- e ??

此法肯定失败,但问题出在这,还真不对啊,不试了,感兴趣的朋友可以玩下

 

2 Mkimage 之前未对 zImage 进行压缩,即- c none

 

<1> -a=-e = 0x20008000 tftpaddr= 0x21000000

搬动到- a 指定的地址,成功启动

Uboot> tftp 21000000 uImage-nzip-zImage-8000;tftp 21100000 ramdisk;bootm 21000000

## Booting image at 21000000 ...

   Image Name:   dd-nzip-zImage-8000

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    881748 Bytes = 861.1 kB

   Load Address: 20008000

   Entry Point:  20008000

   Verifying Checksum ... OK

OK

 

Starting kernel ...

Uncompressing Linux............................................................. done, booting the kernel.

 

Linux version 2.4.19-rmk7 (root@dding) (gcc version 2.95.3 20010315 (release)) #43 10 11 14:25:14 CST 2007

AT91RM9200DK login:

 

<2> -a=-e = 0x20008000 tftpaddr= 0x20008000

不搬动,但- e 地址不对,失败

Uboot> tftp 20008000 uImage-nzip-zImage-8000;tftp 21100000 ramdisk;bootm 20008000

## Booting image at 20008000 ...

   Image Name:   dd-nzip-zImage-8000

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    881748 Bytes = 861.1 kB

   Load Address: 20008000

   Entry Point:  20008000

   Verifying Checksum ... OK

    XIP Kernel Image ... OK

 

Starting kernel ... 死了。。。

 

<3> -a=0x20008000 -e = 0x20008040 tftpaddr= 0x20008000

不搬动 成功启动

Uboot> tftp 20008000 uImage-nzip-zImage-8040;tftp 21100000 ramdisk;bootm 20008000

 

## Booting image at 20008000 ...

   Image Name:   dd-nzip-zImage-8040

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    881748 Bytes = 861.1 kB

   Load Address: 20008000

   Entry Point:  20008040

   Verifying Checksum ... OK

   XIP Kernel Image ... OK

 

Starting kernel ...

 

Uncompressing Linux............................................................. done, booting the kernel.

Linux version 2.4.19-rmk7 (root@dding) (gcc version 2.95.3 20010315 (release)) #43 10 11 14:25:14 CST 2007

AT91RM9200DK login:

 

<4> -a=0x20008000 -e = 0x20008040 tftpaddr= 0x21000000

搬动,但- e 地址不对,失败

 

4.5.3 关于压缩及非压缩内核 bootm 启动的全面总结

 

由上面的 16 个例子,我们可以看出,能够启动内核的由以下几种情况:

各种情况对应的统一 ramdiskaddr= 0x21100000

<1> 非压缩的 Image 内核:

-a=-e = 0x20008000 –c=none tftpaddr= 0x20f00000

此法主要由于内核太大,导致 tftpaddr 做了一定的修正

-a= 0x20008000 -e = 0x20008040 –c=none tftpaddr=0x20008000

此法理论上可行,但我未试验成功,有兴趣的朋友可以探究下

对于非压缩的 Image 内核, mkimage 之前不压缩的话,内核印象较大,此法不常用

 

-a=-e = 0x20008000 –c=gzip tftpaddr= 0x21000000

–c=gzip 压缩内核必须解压,只有这种情况成功;其他解压覆盖或者- e 入口不对

 

<2> 压缩的 zImage 内核:

-a=-e = 0x20008000 –c=none tftpaddr= 0x21000000

-a= 0x20008000 -e = 0x20008040 –c=none tftpaddr=0x20008000

-a=-e = 0x20008000 –c=gzip tftpaddr= 0x21000000

–c=gzip 压缩内核必须解压,只有这种情况成功;其他解压覆盖或者- e 入口不对

zImage 已经压缩过一次了,一般无需再压缩,此法不常用

 

常见方法:

<1> 非压缩的 Image 内核:

-a=-e = 0x20008000 –c=gzip tftpaddr= 0x21000000

<2> 压缩的 zImage 内核:

-a=-e = 0x20008000 –c=none tftpaddr= 0x21000000

-a= 0x20008000 -e = 0x20008040 –c=none tftpaddr=0x20008000

 

 

 

待续:

U-boot 如何向 Linux 内核传递命令行参数?

Go 引导内核的详细方法?

Ramdisk initrd 怎么传给内核?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值