u-boot-2009.08引导内核学习笔记
发布时间:2020-12-15 06:27:32 所属栏目:百科 来源:网络整理
导读:U-Boot移植好后就要考虑如何引导内核了(以下介绍的是bootm方式,开发板是友善之臂的mini2440)。所用的U-Boot是移植的U-Boot-2009.08 ,内核是mini2440光盘中的kernel-2.6.29。U-Boot引导内核分三步:内核的编译、启动参数的设置、下载固化。 (一)内核的
U-Boot移植好后就要考虑如何引导内核了(以下介绍的是bootm方式,开发板是友善之臂的mini2440)。所用的U-Boot是移植的U-Boot-2009.08 ,内核是mini2440光盘中的kernel-2.6.29。U-Boot引导内核分三步:内核的编译、启动参数的设置、下载固化。
(一)内核的编译 ? ? 通常,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. 编译 -------------------------------------------------------------------------------- ? ? 在内核的根目录下执行命令进行编译。如果之前编译过,最好先 make clean 一下。然后 make zImage 生成 zImage 的内核(在此之前别忘了参看说明书装载缺省配置文件)。最后在目录kernel-2.6.29/arch/arm/boot下执行命令? ?? ?? ?? ? mkimage -n 'linux-2.6.29' -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.29/arch/arm/boot下。 注:这里我用的mkimage是在U-BOOT-2009.08版本中生成的,在执行mkimage -n 'linux-2.6.29' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage.img时,会出现错误,错误提示代码大概意思是说zImage是不支持的image类型,提示中还会列出支持的image类型。 开始还以为编译出来的zImage文件有问题,结果用友善提光盘中提供的zImage文件执行时也出同样的错误。在网上找了很多别人的做法也都是这么做的,没办法,最后试着将zImage文件改名为kernel,再执行命令:mkimage -n 'linux-2.6.29' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d kernel uImage.img?? 顺利通过了。 关于mkimage -a -e参数的设置,还有另一种方式,具体请google一下。 (二)启动参数的设置 这里我用的是通过串口下载的方式,故暂不提tftp的设置. 将bootcmd的参数改变成从nand flash引导kernel(每次开机后让u-boot复制到sdram中,再使用env参数中的bootm命令引导)。方法是在u-boot提示符下输入: set bootcmd 'nand read 0x31000000 0x80000 0x00200000;bootm 0x31000000'再改变bootargs,使得从nand flash启动根文件系统。方法是在u-boot提示符下输入: set bootargs 'noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0'最后保存设置: saveenv 注:这里需要特别说明的一下的是set bootcmd 'nand read 0x31000000 0x80000 0x00200000;bootm 0x31000000',这个启动命令的意思是:启动时从nand flash的0x80000处(也就是内核存放在NAND FLASH中的起始地址)开始读取大小为0x200000的数据到内存地址0x31000000处,最后调用bootm指令启动内核,bootm指令参数为0x31000000即内核在RAM中的起始地址。 关于内核在NAND FLASH中起始地址的设置,我这里设置的为0x80000.这里主要根据U-BOOT存放区域和UBOOT启动参数存放区域来确定。下面列一个我的NAND区域划分: 0x00000000-0x00060000? ???//u-boot 0x00060000-0x00080000? ???//启动参数,即saveenv命令,将设置的参数保存的地址。 这个地址区的确定,可查看UBOOT代码./u-boot-2009.08/include/configs/mini2440.h #define CONFIG_ENV_OFFSET 0X60000 #define CONFIG_ENV_SIZE? ? ? ? 0x20000? ? ? ? /* Total Size of Environment Sector */ 从这两个宏,可以得知参数保存的区域为0x00060000-0x00080000。 0x00080000-0x00280000? ?//内核 内核区域的起始地址尤其关键,如果在用nand write指令固化内核到NAND FLASH中时,写入起始地址在0x00080000之前时,就可以能导致覆盖u-boot和启动参数,导致无法开始或失去上面设置过的启动参数,而无法引导内核。 0x00280000-之后的就是文件系统存放的区域了。 (三)下载固化 1. 引导系统测试 -------------------------------------------------------------------------------- ? ? 我们先把内核下载到内存中(地址为环境参数bootcmd中的nand read 和bootm 后的地址),然后我们执行bootm命令(同一个地址)看能不能启动系统。在U-Boot下执行: loadx 0x31000000 ? ? //通过超级终端传送文件,将uImage.img下载到0x31000000 ? ? 在提示下载完成后再执行: bootm 0x31000000 ? ? 如果成功则证明我们的设置没有问题(如果有文件系统的话可以正常启动,这个文件系统可以是用Nor Flash 中的 supervivi 烧到 Nand Flash中的)。 很不幸失败了..... 加载内核时跑到: Starting kernel ... Uncompressing Linux.......................................................................................... done,booting the kernel. 到这里就不动了。老办法GOOGLE一下,发现这是个经典问题了,经典问题自有经典的办法解决: 1、u-boot中的命令行参数中console设定有问题,对2.6的内核应该使用ttySAC0,而不是ttyS0。更改为"console=ttySAC0"就可以解决问题。 2、u-boot中FCLK与kernel时钟频率不一致。kernel的FCLK为200MHz,但是uboot的默认值是202.8MHz。(vivi默认的也是200MHz,所以vivi不会出现这个问题。)这样修改uboot的时钟频率设定就可以解决问题。 3. u-boot传递的mach_type参数与内核设置的mach_type不对。 通过分析,发现存在第三种问题。 a).通过对U-BOOT-2009.08代码的分析,mach_type参数在board_Init函数中传出来,在u-boot-2009.08/board/mini2440/mini2440.c文件中, #if defined(CONFIG_S3C2440) /* arch number of S3C2440 -Board */ ? ???gd->bd->bi_arch_number = MACH_TYPE_S3C2440 ; #endif 由此可见,mach_type的值由宏MACH_TYPE_S3C2440定义决定。 在u-boot-2009.08/include/asm-arm/mach-types.h中可以找到,默认定义为: #define MACH_TYPE_S3C2440? ?? ?? ?? ???362 b).通过对友善内核2.6.29代码分析,在./linux-2.6.29/arch/arm/mach-s3c2440/mach-mini2440.c中,找到MACHINE_START(MINI2440,"FriendlyARM Mini2440 development board"),由此发现,由MINI2440这个参数确定。 在./linux-2.6.29/arch/arm/tools/mach-types中,找到 mini2440? ? ? ? ? ? ? ? MACH_MINI2440? ? ? ? ? ? ? ? MINI2440? ? ? ? ? ? ? ? 1999 由此可见,内核设定的mach_type的值为1999。 c).将U-BOOT中,#define MACH_TYPE_S3C2440? ?? ?? ?? ???362 改为#define MACH_TYPE_S3C2440? ?? ?? ?? ???1999 重新编译uboot,启动nor flash中的 supervivi将重新编译得到的uboot.bin烧到NAND FLASH中,按上面所说的方法测试加载到RAM中的内核。 一长串串的打印英文飘过,OK。。。引导内核成功了。 2.下载固化 ---------------------------------------------------------------------------------------- 在u-boot下输入loadx 0x31000000,通过超级终端将uImage下载到内存中。 接着执行 nand erase 0x80000 0x200000 删除掉该区域原有的数据。 执行 nand write 0x31000000 0x80000 0x200000,将内存中的kernel烧入nand flash。 重新开机,OK。。。。。引导成功。。。 ==== http://blog.chinaunix.net/space.php?uid=22278460&do=blog&id=1777658 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 正则表达式 – 分隔符之间匹配文本:贪婪或惰性正则表达式?
- 教你高效学习台湾曹祖胜老师的OnlineSemilar系列的——vb.n
- 如何在Xcode xib编辑器中查看颜色代码?
- 解决Vue使用mint-ui loadmore实现上拉加载与下拉刷新出现一
- dojo toolkit 的query
- c# – 在Singleton上使用Dispose来清理资源
- c# – 我的机器上的Stopwatch.IsHighResolution == false.为
- ruby-on-rails – Rails访问公用文件夹中的文件夹
- 从当前方法C#调用方法2类
- c# – 如果Modal对话框打开,Task.Factory.StartNew()运行在