Chinaunix首页 | 论坛 | 博客
  • 博客访问: 79693
  • 博文数量: 11
  • 博客积分: 1401
  • 博客等级: 上尉
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 16:16
文章分类
文章存档

2011年(1)

2009年(10)

我的朋友

分类: LINUX

2009-05-30 13:37:59

U-Boot-2008.10移植后引导内核(一)

    U-Boot移植好后就要考虑如何引导内核了(以下介绍的是bootm方式,开发板是友善之臂的mini2440)。所用的U-Boot是前面博文里介绍移植的U-Boot-2008.10 ,内核是mini2440光盘中的kernel-2.6.13。U-Boot引导内核分三步:内核的编译、tftp及启动参数的设置、下载固化。

(一)内核的编译
    通常,u-boot为kernel提供一些kernel无法知道的信息,比如ramdisk在RAM中的地址。Kernel也必须为U-boot提供必要的信息,如通过mkimage这个工具(在u-boot代码的tools目录中)可以给zImage添加一个header,也就是使得通常编译的内核zImage添加一个数据头,把添加头后的image通常叫uImage,uImage是可以被U-boot直接引导的内核镜像。那么如何使用mkimage工具而产生uImage的呢?


1. 工具 mkimage
    编译U-Boot成功后,在u-boot代码的tools目录中生成一些工具,比如mkimage。将它们复制到/usr/local/bin 目录下,就可以直接使用了。现在我们编译内核需要用到mkimage来生成U-Boot格式的内核映像文件uImage 。复制完成后在终端输入命令" mkimage "并回车,显示关于mkimage的提示信息,表示你现在已经可以使用此命令了:
Usage: mkimage -l image
          -l ==> list image header information
       mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
    -A ==> set architecture to 'arch'         //用于指定CPU类型,比如ARM
    -O ==> set operating system to 'os'     //用于指定操作系统,比如Linux
    -T ==> set image type to 'type'          //用于指定image类型,比如Kernel
    -C ==> set compression type 'comp'     //指定压缩类型
    -a ==> set load address to 'addr' (hex)  //指定image的载入地址
    -e ==> set entry point to 'ep' (hex)       //内核的入口地址,一般是:image的载入地址+0x40(信息头的大小)
    -n ==> set image name to 'name'          //image在头结构中的命名
    -d ==> use image data from 'datafile'    //无头信息的image文件名
    -x ==> set XIP (execute in place)         //设置执行位置
mkimage [-D dtc_options] -f fit-image.its fit-image


2. 内核修改
    友善之臂提供的 kernel-2.6.13 内核中屏蔽了生成 uImage 的规则, 我们要重新打开这一功能,只需要修改几句话(当然也可以用打补丁的方法)。
    修改文件 kernel-2.6.13/arch/arm/Makefile :
 
 # Convert bzImage to zImage
 bzImage: zImage
 
zImage Image xipImage bootpImage aesopk uImage: vmlinux
  $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
 
 zinstall install: vmlinux
 
    修改文件 kernel-2.6.13/arch/arm/boot/Makefile :
 
 export ZRELADDR INITRD_PHYS PARAMS_PHYS
 
 # ghcstop fix

targets := Image zImage xipImage bootpImage aesopk uImage
 
 ifeq ($(CONFIG_XIP_KERNEL),y)
 
......
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
      -C none -a $(ZRELADDR) -e $(ZRELADDR) \
      -n 'Linux-$(KERNELRELEASE)' -d $< $@
 
 
$(obj)/uImage: $(obj)/zImage FORCE
 $(call if_changed,uimage)

 # @cp -f arch/arm/boot/uImage /korea-dokdo/tftpboot/aesopk  # jdh added
 @echo '  Image $@ is ready'
 
 #ghcstop fix
 $(obj)/Image.gz: $(obj)/Image FORCE

3. 编译

    在内核的根目录下执行命令进行编译。如果之前编译过,最好先 make clean 一下。然后 make zImage 生成 zImage 的内核(在此之前别忘了参看说明书装载缺省配置文件)。最后在目录kernel-2.6.13/arch/arm/boot下执行命令            
mkimage -n 'linux-2.6.13' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage.img
生成 U-Boot可以引导的内核,生成的文件名为uImage.img (也可以使用默认设置,在内核根目录下执行make uImage,生成默认的文件名为uImage)。生成的内核文件都在目录kernel-2.6.13/arch/arm/boot下。
 
(二)tftp及启动参数的设置
    这些设置需要修改环境变量(env的参数),应该是不需要修改u-boot源代码的,修改了也没用。应该是在u-boot命令行下面用setenv xxx xxx 这样来设置后,saveenv写入env扇区才能生效的。若直接修改代码,也不会影响到env扇区,除非env扇区是空的。我们先用Nor Flash中的supervivi把移植好的U-Boot烧到Nand Flash中(用选项a)。

1. 依据所在的网络环境设置网络参数。
    开发板和主机必须处于同一个子网,在U-Boot倒数完自动启动之前回车,进入命令行模式,可以用命令print查看当前环境变量(env)的设置。网络参数的修改参照如下:(省略号改为自己的参数)

setenv ipaddr ......    (开发板IP地址)
setenv gatewayip ...... (网关)
setenv serverip ......  (tftp服务器的IP地址)
setenv netmask 255.255.255.0
setenv ethaddr ......

后两个参数一般不需要修改。然后保存设置:
saveenv (别忘了回车)
2. 修改启动参数

    将bootcmd的参数改变成从nand flash引导kernel(每次开机后让u-boot复制到sdram中,再使用env参数中的bootm命令引导)。方法是在u-boot提示符下输入:
set bootcmd 'nand read 0x31000000 0x50000 0x00200000;bootm 0x31000000'
再改变bootargs,使得从nand flash启动根文件系统。方法是在u-boot提示符下输入:
set bootargs 'noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0'
最后保存设置:
saveenv

(三)下载固化
    我们将使用mini2440光盘里的windows平台工具tftpboot进行下载。首先把我们编译好的内核uImage.img(或uImage)拷贝到tftpboot目录下,然后双击tftpd32.exe准备下载。在用U-Boot把内核和文件系统固化到Nand Flash之前,我们先做一个实验确保我们的设置没有问题,可以正常引导系统。


1. 引导系统实验
    我们先把内核下载到内存中(地址为环境参数bootcmd中的nand read 和bootm 后的地址),然后我们执行bootm命令(同一个地址)看能不能启动系统。在U-Boot下执行:
tftp 0x31000000 uImage.img (或uImage)
    在提示下载完成后再执行:
bootm 0x31000000
    如果成功则证明我们的设置没有问题(如果有文件系统的话可以正常启动,这个文件系统可以是用Nor Flash 中的 supervivi 烧到 Nand Flash中的)。
2. 下载固化
   对nand flash的空间划分如下。其中0x40000~0x50000的空间没有使用。作为保留空间。

                            起始地址             结束地址
uboot            :       0x00000000      0x00030000      0
param           :       0x00030000      0x00040000      0
kernel           :       0x00050000      0x00200000      0
root              :       0x00250000      0x03dac000      0

    在u-boot下输入tftp 0x30000000 uImage.img(或uImage),稍等即可下载uImage到内存中。
    接着执行 nand erase 0x50000 0x200000 删除掉kernel空间原有的数据。
    执行 nand write 0x30000000 0x50000 0x200000,将内存中的kernel烧入nand flash。
    接下来,输入tftp 30000000 root_qtopia_tp.img,将根文件系统镜象下载到内存中。
    再输入nand erase 0x250000 0x3dac000 将root空间内原有数据删除。
    再输入nand write.yaffs 0x30000000 0x250000 0x3f82020,其中0x3f82020是文件系统镜象的size,一定不能写错,它可以tftp下载完毕后看到。如写错了,可能会形成假坏块。
 
注意:U-Boot引导的内核需要用U-Boot下载固化。用Nor Flash 中的 supervivi的选项k下载是无法启动的。
 
    然后等烧写完成后,重启开发板就可以正常引导内核了。

阅读(2422) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

chinaunix网友2009-07-28 16:33:30

所以我们设置的环境变量 bootcmd 的地址必须与那两个相同的地址有一段距离(应该是大于0x40),这样才能正常启动系统。 ------------------------------------------------ 为什么是大于0x40而不是大于内核的大小,难道只搬移0x40个字节吗?