博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]u-boot-2010.12移植到2440(五,支持内核引导)
阅读量:4107 次
发布时间:2019-05-25

本文共 4280 字,大约阅读时间需要 14 分钟。

u-boot-2010.12移植到2440(五,支持内核引导)

转自

为了让U-boot支持内核引导,需要涉及u-boot和linux内核的配合,u-boot传递启动参数给linux内核。其中以machine ID最为重要,是内核能够正确引导的先决条件。其他参数则通过gd->bd数据结构传递给内核。

1、u-boot的配置和修改

首先需要在include/configs/smdk2440.h中加入以下宏定义:

#define CONFIG_SETUP_MEMORY_TAGS    1 //如果没有定义这个参数,则uboot参数必须加入men=内存大小

#define CONFIG_INITRD_TAG            1

#define CONFIG_CMDLINE_TAG           1 //设置bootargs出入内核必须

#define CONFIG_BOOTARGS         "root=/dev/mtdblock3 rw rootfstype=yaffs noinitrd init=/linuxrc console=ttySAC0,115200 ip=192.168.0.105:192.168.0.7:192.168.0.1:255.255.255.0:comleader:eth0:off"

#define CONFIG_BOOTCOMMAND  "nand read 0x30008000 0x50000 0x200000;bootm 0x30008000"

#define CONFIG_MTD_NAND_YAFFS2   1 //定义一个管理对Yaffs2支持的宏

//开启Nand Flash默认分区,注意此处的分区要和你的内核中的分区保持一致

#define MTDIDS_DEFAULT "nand0=nandflash0"

#define MTDPARTS_DEFAULT "mtdparts=nandflash0:192k(bootloader)," /

                     "64k(params)," /

                     "2m(kernel)," /

                     "-(root)"

 

修改board/samsung/smdk2440/smdk2440.c中的machine id:

gd->bd->bi_arch_number = MACH_TYPE_SMDK2440; /*1008*/

 

然后编译,发现有错误,有未定义函数,这又是新版本的一个BUG,在arch/arm/lib/bootm.c文件中增加头文件:

#include <lmb.h>   /*add by bsc*/

编译之后运行,下载uImage到0x30008000地址,然后用GO命令直接运行:

Tftp 0x30008000 uImage

Go 0x30008040

出现错误“Error: unrecognized/unsupported machine ID (r1 = 0x338afef0).”

此时r1 = 0x338afef0,实际上R1中应该存有uboot传递给linux内核的machine ID 但是此时显然不是。这是因为go命令并未传递任何参数。因此我们通过bootm命令来引导:

tftp 0x30008000 uImage

bootm 0x30008000

 

但是仍然在“Starting kernel ..”地方死机。找到到此处位置在arch/arm/lib/bootm.c中:

static void announce_and_cleanup(void)

{

      printf("/nStarting kernel .../n/n");

 

#ifdef CONFIG_USB_DEVICE

      {

           extern void udc_disconnect(void);

           udc_disconnect();

      }

#endif

      cleanup_before_linux();

}

怀疑cleanup_before_linux()函数有问题,以前的版本没有此函数,因此暂时注销此函数:

static void announce_and_cleanup(void)

{

      printf("/nStarting kernel .../n/n");

 

#ifdef CONFIG_USB_DEVICE

      {

           extern void udc_disconnect(void);

           udc_disconnect();

      }

#endif

      //cleanup_before_linux();/*delete by bsc */

}

重新编译,更新uboot之后再次引导内核,引导成功。此时的内核尚没有文件系统支持。cleanup_before_linux()函数的问题后续进一步研究。

然后,我们将内核烧写入NAND FLASH 然后让系统自动引导。我们可以在common/env_common.c文件中的default_environment[]数组中增加:

   "kk="   "t 0x30000000 zImage;nand erase 0x50000 0x300000;nand write 0x30000000 0x50000 0x200000" "/0"

   "yy="   "t 0x30000000 rootyaffs2.img;nand erase 0x250000 0x3db0000;nand write.yaffs2 0x30000000 0x250000 $(filesize)" "/0"

   "firstboot=" "set bootcmd $(normalboot);save;nand erase 0x50000 0x3f00000;run kk;run yy" "/0"

   "normalboot="   "nand read 0x30008000 0x50000 0x200000;bootm 0x30008000" "/0"

然后我们只需用run kk命令即可实现内核的下载和烧写。重启之后通过bootm 0x30008000来实现引导。

2、制作u-boot能够直接引导的linux内核。

首先linux启动过程中需要校验machine ID,因此我们修改修改linux内核的文件arch/arm/tools/mach-types中:

s3c2440      ARCH_S3C2440    S3C2440       1008 //1008,与uboot中一致

说明:不建议直接修改arch/arm/kernel/head.S文件通过R1寄存器直接传递machine ID给内核。

U-boot并不能直接支持linux的zImage,u-boot支持的镜像文件格式为uImage。通 常,kernel的启动需要u-boot提供一些参数信息,比如ramdisk在RAM中的地址。经过编译后的u-boot在根目录下的tools目录 中,会有个叫做mkimage的工具,他可以给zImage添加一个header,也就是说使得通常我们编译的内核zImage添加一个数据头信息部分,我们把添加头后的image通常叫uImage,uImage是可以被u-boot直接引导的内核镜像。

mkimage工具的使用:中括号括起来的是可选的

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)     //设置执行位置

先将u- boot下的tools中的mkimage复制到主机的/usr/local/bin目录下,这样就可以在主机的任何目录下使用该工具了。现在我们进入 kernel生成目录(一般是arch/arm/boot目录),然后执行如下命令,就会在该目录下生成一个uImage.img的镜像文件,把他复制到 tftp目录下,这就是我们所说的uImage。

mkimage -'linux-2.6.37.1' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage

 

设置修改u-boot的启动参数,在u-boot命令行下输入:

//设置启动参数,意思是将nand0x50000-0x00200000(kernel分区一致)的内容读到内存0x30008000中,然后用bootm命令来执行:

set bootcmd 'nand read 0x30008000 0x50000 0x00200000;bootm 0x30008000'

saveenv  //保存设置

把uImage用tftp下载到内存中,然后再固化到Nand Flash中,操作如下:

tftp 0x30000000 uImage  //uImage.img下载到内存0x30000000

nand erase 0x50000 0x200000 
//擦除nand0x50000-0x200000的内容
nand write 0x30000000 0x50000 0x200000 
//将内存0x30000000处的内容写入到nand0x50000

最后,我们重新启动开发板,可以看到,内核被u-boot成功引导起来了。

说明:linux最新版本的交叉编译过程参见另外的文章。

 

转载地址:http://qhpsi.baihongyu.com/

你可能感兴趣的文章
linux进程监控和自动重启的简单实现
查看>>
OpenFeign学习(三):OpenFeign配置生成代理对象
查看>>
OpenFeign学习(四):OpenFeign的方法同步请求执行
查看>>
OpenFeign学习(五):OpenFeign请求结果处理及重试控制
查看>>
OpenFeign学习(六):OpenFign进行表单提交参数或传输文件
查看>>
OpenFeign学习(七):Spring Cloud OpenFeign的使用
查看>>
Ribbon 学习(二):Spring Cloud Ribbon 加载配置原理
查看>>
Ribbon 学习(三):RestTemplate 请求负载流程解析
查看>>
深入理解HashMap
查看>>
XML生成(一):DOM生成XML
查看>>
XML生成(三):JDOM生成
查看>>
Ubuntu Could not open lock file /var/lib/dpkg/lock - open (13:Permission denied)
查看>>
collect2: ld returned 1 exit status
查看>>
C#入门
查看>>
查找最大值最小值
查看>>
杨辉三角
查看>>
冒泡排序法
查看>>
C#中ColorDialog需点两次确定才会退出的问题
查看>>
16、Memento 备忘录模式
查看>>
Java基础篇(一)
查看>>