U-boot如何引导Linux内核启动
2010-12-28 21:22
274 查看
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
四
4.1
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
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
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
怎么传给内核?
全线移植分析系列之四
――
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
怎么传给内核?
相关文章推荐
- U-boot如何引导Linux内核启动
- U-boot如何引导Linux内核启动?
- 【嵌入式Linux学习七步曲之第三篇 Linux系统bootlaoder移植】U-BOOT全线移植分析系列之四--U-boot如何引导Linux内核启动?
- U-BOOT全线移植分析系列之四--U-boot如何引导Linux内核启动?
- U-BOOT全线移植分析系列之四——U-boot如何引导Linux内核启动
- u-boot.lds分析(u-boot-1.3.4 nandflash启动 引导linux内核)
- u-boot.lds分析(u-boot-1.3.4 nandflash启动 引导linux内核)
- Linux内核如何装载和启动一个可执行程序
- 如何用快启动pe修复win10系统引导? 神器
- 第七周——Linux内核如何装载和启动一个可执行程序
- Spring Boot配置的第一个应用(如何启动)
- 从零开始-uboot的移植-前期准备:uboot是如何启动倒数,启动内核的
- u-boot向linux内核传递启动参数
- <Linux>u-boot启动Linux内核分析
- Linux内核如何装载和启动一个可执行程序
- Linux内核如何装载和启动一个可执行程序
- u-boot引导,NFS启动: 问题:IP-Config: Incomplete network configuration information
- u-boot向linux内核传递启动参数
- Spring Boot 2.0(七):Spring Boot 如何解决项目启动时初始化资源
- linux内核如何启动第一个进程