转载于:[url]http://blog.chinaunix.net/u2/68846/showart_693620.html[/url]
[root@gliethttp linux-2.4.19-rmk7]#make at91rm9200dk_config
[root@gliethttp linux-2.4.19-rmk7]#make oldcnofig //使用dk板默认配置
如果想定制,可以继续执行
[root@gliethttp linux-2.4.19-rmk7]#make menuconfig
[root@gliethttp linux-2.4.19-rmk7]#make Image
[root@gliethttp linux-2.4.19-rmk7]#/usr/local/arm/2.95.3/bin/arm-linux-objcopy -O binary -S vmlinux linux.bin
[root@gliethttp linux-2.4.19-rmk7]#gzip -v9 linux.bin
[root@gliethttp linux-2.4.19-rmk7]#mkimage -A arm -O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage
这样我们得到了Linux启动压缩内核uImage,默认运行地址为0x21000000,
还有一个RAM启动盘-名字为ramdisk-rmk7,在普通的PC机上叫initrd-2.4.20-8.img,在
/boot/grub/menu.lst文件中,我们可以看到它的使用方法:
***********************
root (hd0,6)
kernel /boot/vmlinuz-2.4.20-8 ro root=LABEL=/ ##########内核文件
initrd /boot/initrd-2.4.20-8.img ##########RAM启动盘文件
***********************
ramdisk-rmk7的默认运行地址为0x21100000,
只要有上边的两个文件,Linux内核就能够正常的工作了。
uBoot中进行如下设置
Uboot > tftp 21000000 uImage ##########装载内核到内存21000000处
Uboot > tftp 21100000 ramdisk-rmk7 ##########装载RAM启动盘到21100000处
Uboot > setenv bootargs root=/dev/ram rw initrd=0x21100000,6000000 ramdisk_size=15360 console=ttyS0,115200 mem=32M
Uboot > bootm 21000000
如上是通过tftp直接将内核文件uImage和RAM启动盘加载到内存中,然后运行,下面讲讲如何
将这两个文件固化到Flash中,然后通过Flash进行加载启动:
1)将RAM启动盘固化到c0000000为起始地址的Flash中
U-Boot > tftp 20000000 PATH/ramdisk-rmk7
U-Boot > cp.b 20000000 c0000000 ramdisk_size
2)将uImage内核镜像固化到紧跟RAM盘存储空间之后
U-Boot > tftp 20000000 PATH/uImage
U-Boot > cp.b 20000000 c0000000+ramdisk_size image_size
3)存储之后,就要配置uBoot启动加载参数了
U-Boot > setenv ramdisk cp.b c0000000 21100000 ramdisk_size
U-Boot > setenv image cp.b c0000000+ramdisk_size 21000000 image_size<
U-Boot > setenv boot bootm 21000000
U-Boot > setenv bootcmd run ramdisk\; run image\; run boot
U-Boot > saveenv
U-Boot > run bootcmd
*************************************************
arch/arm/Makefile
//
内核运行虚拟地址
TEXTADDR = 0xC0008000
*************************************************
arch/arm/boot/Makefile
//
内核加载地址
ZRELADDR = 0x20008000
*************************************************
arch/arm/boot/compressed/Makefile
//
自解压程序地址
ZTEXTADDR = 0x00000000
(
linux- 2.4.19 -rmk7
内核的自解压函数
gunzip
位于
/lib/inflate.c
中,为
gzip- 1.0.3
版本,现在在
PC
上使用
gzip
函数压缩出来的文件不能被
gzip- 1.0.3
版本的
gunzip
识别,所以
linux-2.4.19-rmk7
内核自解压的功能等于不能使用
,
默认值
ZTEXTADDR= 0x00000000
表示不使用。(只能通过
uBoot
的
gunzip
解压加载)
)
***********************************************
//uImage
存放地址
= 0x21000000
***********************************************
mkimage -A arm -O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage
-A:CPU
类型
-O:
操作系统
-C:
采用的压缩方式
-a:
内核加载地址
-e:
内核入口地址
***********************************************
uBoot
的
do_bootm
(
cmd_tbl_t *
cmdtp
,
int
flag
,
int
argc
,
char *
argv
[]);
函数将检验存放到
0x21000000
地址处的经过
mkimage
格式化的
uImage
数据的头部
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
;
(ih_ep
值为
0x20008000
,
ih_load
值为
0x20008000
)
如果头部各个域值和
crc
合法,那么
do_bootm
将调用如下
gunzip
解压函数对
0x21000000
+sizeof
(
image_header_t
)
地址处的压缩内核进行解压:
gunzip
((
void*
)
ntohl
(
hdr
->ih_load
),
0x400000
,
data
,(
int*
)
&
len
)
;
1.
hdr
->ih_load
为输出数据地址
0x20008000
2.
0x400000
为
gunzip
解压输出数据上限值-
4M
3.
data
为输入数据地址
data
=
0x21000000
+sizeof
(
image_header_t
);
4.
Len
为输入数据长度
len
= ntohl
(
hdr
->ih_size
);
解压完成后将会存储解压后数据的实际大小
压缩的
Linux
内核文件
uImage
,经由
gunzip
解压函数后,通过
do_bootm_linux
(
cmdtp
,
flag
,
argc
,
argv
,
addr
,
len_ptr
,
verify
);
函数向
Linux
内核传递内核运行所需的
5
个参数
kernel
=
(
void
(
*
)(
bd_t *
,
ulong
,
ulong
,
ulong
,
ulong
))
hdr
->ih_ep
;
1.
hdr
->ih_ep
为
0x20008000
/*
* 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
*/
(
*
kernel
) (
kbd
,
initrd_start
,
initrd_end
,
cmd_start
,
cmd_end
);
这样完成了
Linux
系统启动所需要
5
个参数的传递,至此
uBoot
的工作已经结束,
Linux
将在
0x20008000
地址处正式运