Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7687772
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2010-08-10 09:27:45

嵌入式学习入门 http://blog.chinaunix.net/u3/117680/showart.php?id=2300212  

      文章——>嵌入式学习入门    全面的讲述学习嵌入式linux中的每个步骤 

 

u-boot对Nor Flash和Nand Flash的启动支持,那现在我们就再来探讨一下u-boot怎样来引导Linux内核的启动。
下载内核参考
内核写进nand flash
 
 
①、机器码的确定
通常,在u-boot和kernel中都会有一个机器码(即:MACH_TYPE),只有这两个机器码一致时才能引导内核,否则就会出现如下mach的错误信息:
 
首先,确定u-boot中的MACH_TYPE。在u-boot的include/asm-arm/mach-types.h文件中针对不同的CPU定义了非常多的MACH_TYPE,可以找到下面这个定义:

#define MACH_TYPE_SMDK2440 1008  //针对2440的MACH_TYPE码的值定义为1008

 
那么我们就修改u-boot的MACH_TYPE代码引用部分,确定u-boot的MACH_TYPE。如下:

#gedit board/samsung/my2440/my2440.c   //修改board_init函数

/* arch number of SMDK2410-Board */
//gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
改为:
gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;

 
其次,确定kernel中的MACH_TYPE。在kernel的arch/arm/tools/mach-types文件中也针对不同的CPU定义了非常多的MACH_TYPE,也可以找到下面这个定义:

smdk2440  MACH_SMDK2440   SMDK2440   1008

 
那么我们就修改kernel的MACH_TYPE代码引用部分,确定kernel的MACH_TYPE。如下:

#gedit arch/arm/mach-s3c2440/mach-smdk2440.c   //修改文件最后面

//MACHINE_START(S3C2440, "SMDK2440")
改为:
MACHINE_START(SMDK2440, "SMDK2440")

 

#gedit arch/arm/kernel/head.S  //在ENTRY(stext)下添加如下代码(红色部分)

ENTRY(stext)

    mov    r0, #0
    mov    r1, #0x3f0   //上面的MACH_TYPE值1008换成十六进制就是0x3f0
    ldr    r2, =0x30000100
 
   
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE

    .......

 
分别重新编译u-boot和kernel。u-boot下载后,记得要saveenv;kernel用tftp下载到内存后使用go命令来测试引导内核,结果可以引导了,如下:
 
准备能被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 -n 'linux-2.6.30.4' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage.img

 
③、Nand Flash的分区。我们查看内核在arch/arm/plat-s3c24xx/common-smdk.c中的分区情况如下

         起始地址      结束地址

uboot : 0x00000000    0x00030000
param : 0x00030000    0x00040000 //注意这个环境变量的地址范围要与上一节补充内容中配置的CONFIG_ENV_OFFSET一致
kernel: 0x00050000    0x00200000
root  : 0x00250000    0x03dac000

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

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

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

saveenv  //保存设置

 
⑤、把uImage.img用tftp下载到内存中,然后再固化到Nand Flash中,操作和执行图如下:

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

nand erase 0x50000 0x200000 //擦除nand的0x50000-0x200000的内容

nand write 0x30000000 0x50000 0x200000 //将内存0x30000000处的内容写入到nand的0x50000处

 
 
最后,我们重新启动开发板,可以看到,内核被u-boot成功引导起来了,如图:
 
阅读(2655) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~