2008年6月25日 星期三

uImage + u-boot的啟動方式

我的kernel的TEXTADDR設在0x00008000,會蓋到uboot,所以不能用kernel的make uImage。

mkimage在u-boot的./tools下,build完u-boot也會把mkimage build出來,可以直接拿來用


make uImage: kernel的make uImgae是用方法的方式1產生的,所以如果要用的話也要用方法1的啟動方式

mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000 -n 'Linux-2.6.16-star' -d arch/arm/boot/zImage arch/arm/boot/uImage

方法1: load address與entry address相同,則放到DRAM上的位置就不能一樣,而且要注意兩個image不要蓋到了,之間至少要留image size的空間,u-boot會把kernel image(不包括64byte header) copy到load address再啟動。
mkimage -A arm -O linux -T kernel -C none -a 0x01500000 -e 0x01500000 -n 'Linux-2.6.16-star' -d arch/arm/boot/zImage arch/arm/boot/uImage

setenv flashaddr 10040000;setenv kfile uImage; setenv ramaddr 1000000;
tftp $(ramaddr) $(kfile); bootm $(ramaddr);

方法2: 若是load address要與放在DRAM上的位置相同,因為u-boot不會自己跳過64byte的header,所以entry address要自己跳過64byte
mkimage -A arm -O linux -T kernel -C none -a 0x01500000 -e 0x01500040 -n 'Linux-2.6.16-star' -d arch/arm/boot/zImage arch/arm/boot/uImage

setenv flashaddr 10040000;setenv kfile uImage; setenv ramaddr 1500000;
tftp $(ramaddr) $(kfile); bootm $(ramaddr);


5.9.4. Execution Control Commands
http://www.denx.de/wiki/DULG/UBootCmdGroupExec

=> help bootm
bootm [addr [arg ...]]
- boot application image stored in memory
passing arguments 'arg ...'; when booting a Linux kernel,
'arg' can be the address of an initrd image
When booting a Linux kernel which requires a flat device-tree
a third argument is required which is the address of the
device-tree blob. To boot that kernel without an initrd image,
use a '-' for the second argument.
If you do not pass a third
a bd_info struct will be passed instead

The bootm command is used to start operating system images. From the image header it gets information about the type of the operating system, the file compression method used (if any), the load and entry point addresses, etc. The command will then load the image to the required memory address, uncompressing it on the fly if necessary. Depending on the OS it will pass the required boot arguments and start the OS at it's entry point.

The first argument to bootm is the memory address (in RAM, ROM or flash memory) where the image is stored, followed by optional arguments that depend on the OS.

Linux requires the flattened device tree blob to be passed at boot time, and bootm expects its third argument to be the address of the blob in memory. Second argument to bootm depens on whether an initrd initial ramdisk image is to be used. If the kernel should be booted without the initial ramdisk, the second argument should be given as "-", otherwise it is interpreted as the start address of initrd (in RAM, ROM or flash memory).

To boot a Linux kernel image without a initrd ramdisk image, the following command can be used:

=> bootm ${kernel_addr} - ${fdt_addr}

If a ramdisk image shall be used, you can type:

=> bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}

Both examples of course imply that the variables used are set to correct addresses for a kernel, fdt blob and a initrd ramdisk image.

ALERT! When booting images that have been loaded to RAM (for instance using TFTP download) you have to be careful that the locations where the (compressed) images were stored do not overlap with the memory needed to load the uncompressed kernel. For instance, if you load a ramdisk image at a location in low memory, it may be overwritten when the Linux kernel gets loaded. This will cause undefined system crashes.

http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&board_pc2020=embedded&index=74&id=2800&mode=&type_pc2020=sametitleLevel-2
應該先把 zImage 轉成 uImage 吧 .. (加 64bytes prefix)

U-BOOT下使用bootm引导内核方法
http://www.cnitblog.com/luofuchong/archive/2007/01/12/21834.html
S3C2410架构下的bootm只对sdram中的内核镜像文件进行操作(好像AT91架构提供了一段从flash复制内核镜像的代码,不过针对s3c2410架构就没有这段代码,虽然可以在u-boot下添加这段代码,不过好像这个用处不大),所以请确保你的内核镜像下载到sdram 中,或者在bootcmd下把flash中的内核镜像复制到sdram中。

如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。

使用mkimage生成kernel image,会在内核的前面加上了64byte的信息,供建立tag之用。

bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte(這裡說的是『你』要手動改-e的值,後推64byte(0x40),u-boot不會自動幫你跳!!!因此會有兩種給參數的方式,相對的啟動方式也不同),以跳过这64byte的头部。


mkimage
-a参数后是内核的运行地址,-e参数后是入口地址。

-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-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 data from 'datafile'
-x ==> set XIP (execute in place)
方法一、
mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.img

sbc2410=>tftp 0x31000000 zImage.img
sbc2410=>bootm 0x31000000



方法二、
mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img

sbc2410=>tftp 0x30008000 zImage.img
sbc2410=>bootm 0x30008000


三、固化
sbc2410=>tftp 0x30008000 zImage.img
sbc2410=>nand erase 0x30000 0x1d0000
sbc2410=>nand write 0x30008000 0x30000 0x1d0000

设置u-boot启动命令:
1、针对方法一:
sbc2410=>setenv bootcmd nand read 0x31000000 0x30000 0x1d0000\;bootm 0x31000000
sbc2410=>saveenv
2、针对方法二:
sbc2410=>setenv bootcmd nand read 0x30008000 0x30000 0x1d0000\;bootm 0x30008000
sbc2410=>saveenv


U-BOOT(bootloader)程序的特点功能
http://www.dz863.com/Embedded-Systems-Design/Embedded-Design/U-BOOT-bootloader.htm
识别二进制、ELF32、uImage格式的Image,对Linux引导有特别的支持。U-BOOT对Linux 内核进一步封装为uImage。封装如下:
#{CROSS_COMPILE}-objcopy -O binary -R.note -R.comment -S vmlinux \ linux.bin
#gzip -9 linux.bin
#tools/mkimage -A arm -O linux -T kernel -C gzip -a 0xc0008000 -e\
0xc0008000 -n “Linux-2.4.20” -d linux.bin.gz /tftpboot/uImage
即在Linux内核镜像vmLinux前添加了一个特殊的头,这个头在include/image.h中定义,包括目标操作系统的种类(比如Linux, VxWorks等)、目标CPU的体系机构(比如ARM、PowerPC等)、映像文件压缩类型(比如gzip、bzip2等)、加载地址、入口地址、映像名称和映像的生成时间。当系统引导时,U-BOOT会对这个文件头进行CRC校验,如果正确,才会跳到内核执行。


http://blog.chinaunix.net/u1/43047/showart_1010014.html
The data movement of uImage bootup by u-boot

1. Kernel Load Address. This is the address, where the kernel was linked
to when you built the vmlinux and can be found in arch/arm/Makefile.
The default for it is:

ifeq ($(CONFIG_CPU_32),y)
PROCESSOR = armv
TEXTADDR = 0xC0008000
LDSCRIPT = arch/arm/vmlinux-armv.lds.in
endif

Provide this as "-a" parameter to mkimage.

2. Kernel Entry Point. This is the address, where ARMboot jumps to to
enter the Kernel. It usually is the same as the kernel load address.

Provide this as "-e" parameter to mkimage.

3. The Network Download Address. This is where you download the mkimage
File. This address MUST BE different to the Kernel Load Address, and
should be sufficiently far away to allow ARMboot to relocate the
image to the final Kernel Load Address. Loading to the 5th MB
within the RAM is usually a good idea, eg. if the RAM begins at
0xc0000000

沒有留言: