在引导内核启动这块,我是卡了很久的,到现在为止还是不能完全弄明白。
总的来说要想uboot引导内核成功,需要:1.uboot的机器码要与内核上的一致;2.bootargs和bootcmd 参数的设置;3.让uboot支持传递bootargs和bootcmd参数 (s3c2410本身是不支持传递的,需要特别加某些宏);
设置好上面的3点以后,需要把内核烧录到nand flash中,启动uboot才能引导成功;手动引导即把内核下到内存后再bootm时常常会出现如下错误:
暂且略过这些,把我移植的过程记录一下。
1.uboot的机器码要与内核上的一致
(1)先改uboot的机器码,打开uboot源码包中/board/samsung/ok2440v3/0k2440v3.c,修改:
gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;
再打开/include/asm-arm/mach-types.h,里面定义了大部分板子类型的机器码,在这里面可以找到SMDK2440这一项:
#define MACH_TYPE_SMDK2440 1008 //这里的1008(换成16进制是0X3F0)即是板子SMDK2440的机器码,这码数可修改;
(2)接着修改内核的机器码使其与uboot中设定的一致即可。这里内核用的是:linux-2.6.35.4 下载
打开内核源码包中的arch/arm/mach-s3c2440/mach-smdk2440.c,修改:
MACHINE_START(SMDK2440, "SMDK2440") //这句标红色的SMDK2440决定kernel的机器码,这定义在arch/arm/tools/mach-types;
可以打开arch/arm/tools/mach-types文件查看有下面一句:
smdk2440MACH_SMDK2440SMDK2440 1008 //SMDK2440对应机器码1008
(3)上面两步已经完成了机器码的配置,为了更确定能引导内核,可以手动给内核设置跟uboot一致的机器码;
打开内核源码包中arch/arm/kernel/head.S,增加下面语句:
ENTRY(stext)
mov r0,#0 //这里给R0赋0;
mov r1,#0x3f0 //把机器码直接手动赋给R1.0X3F0即为1008;
ldr r2, =0x30000100 //这是环境变量在内存里的加载地址,赋给R2;
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
2.bootargs和bootcmd 参数的设置
(一)打开include/configs/ok2440v3.h,增加参数bootargs:
#define CONFIG_BOOTARGS "root=/dev/nfs rw nfsroot=192.168.1.99:/forlinx/s3c2440/rootfs ip=192.168.1.15:192.168.1.255::255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M"
CONFIG_BOOTARGS这个参数是告诉内核要以什么方式加载根文件系统,我这里加载的是NFS根文件系统:
nfsroot=192.168.1.99:/forlinx/s3c2440/rootfs 这是我的根文件系统在虚拟机上的位置,192.168.1.99是我虚拟机的ip;
ip=192.168.1.15:192.168.1.255::255.255.255.0 这里192.168.1.15是开发板的IP,192.168.1.255是网关,255.255.255.0是掩码;
mem=64M 这里是内存空间大小
(二)在ok2440v3.h文件中再增加参数bootcmd:
#define CONFIG_BOOTCOMMAND "nand read 31000000 500000 500000;bootm 31000000"
nand read 31000000 500000 500000,这句的意思是把以500000(第一个)为起始地址,大小空间为500000(第二个)的内容加载到内存地址31000000 中去;
bootm 31000000;以bootm方式启动31000000处内容。
3.让uboot支持传递bootargs和bootcmd参数 (s3c2410本身是不支持传递的,需要特别加某些宏)
为了告诉告诉uboot把bootcmd 和bootargs参数传给内核;需要在include/configs/ok2440v3.h中增加这几个宏定义:
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_CMDLINE_TAG 1
#define CONFIG_INITRD_TAG 1
因为在
lib_arm/bootm.c文件中用到这几个宏,原本s3c2410是没有定义的,而我们移植的时候是以s3c2410为模板的,自然也没有,故需要增加。
完成上面3步,就可以生成uboot.bin,用tftp 下载到开发板nand flash(地址0--100000可自定义)中,再用tftp把内核下载下来,就能引导内核启动了。内核的制作在下一篇介绍,启动画面如下: