先介绍一下此次移植的主要目标对象:
平台:Windows 7 旗舰版 And Fedora 9
目标板:mini2440
目标系统: linux-2.6.32.2
交叉编译链: arm-liunux-gcc 4.4.3
busybox版本: busy.1.13.3
yaffs2版本: yaffs2-20100330(友善那坑爹的文档说光盘有这个压缩包……我有你妹啊……这个是我从官网下载的)
本来以为吧,有友善的移植文档作为参考,只要一步一步来,应该会比较顺利的……不过很快我发现我真是太天真了……友善那坑爹的移植文档实在是让我火大……一个简单的移植过程,在有参考文档的前提下,足足搞了哥4天时间,期间因为按部就班地按照友善的移植文档而犯了不少让人抓狂的错误……再说一次,哥TMD真的是很火大!
好吧,发泄了一通之后要平静下来了……记录一下整个移植过程,为以后留点笔记……移植期间参考了网上不少的文章,实在是万分感谢这些文章的作者……没有他们的共享精神,可能我现在还在懊恼那些坑爹的错误……为此,我一定要把自己的移植过程写出来……如果有人因为这篇文章而解决了某些问题,那我一定会由衷地感到高兴。
先说一下移植步骤,这个是很重要的:
1.解压linux内核
2.修改目标平台
3.到arch/arm/mach-s3c2440文件夹,把mach-mini2440.c剪切到另外一个地方,建立自己的mach-mini2440,复制smdk-2440.c的内容到刚建立的mach-mini2440.c,修改晶振,修改MACHINE_START宏,增加分区信息,注意对照原来的mach-mini2440.c添加一些头文件,这些文件分别是:
#include
#include
#include
#include
#include
另外还需要在mini2440_map_io这个函数里添加一行:s3c_device_nand.dev.platform_data = &mini2440_nand_info;
不然还是会出现离奇的错误。原因一会具体再说。
这个时候板文件就算完成了,如果这个时候make mini2440_defconfig之后再make zImage,烧到板子上之后启动应该就能看到分区信息了。
不过这时候还没有文件系统。
4。内核移植完成,开始移植文件系统。按照移植文档建立脚本文件:
#!/bin/sh
echo "------Create rootfs directons start...--------"
mkdir rootfs
cd rootfs
echo "--------Create root,dev....----------"
mkdir root dev etc boot tmp var sys proc lib mnt home usr
mkdir etc/init.d etc/rc.d etc/sysconfig
mkdir usr/sbin usr/bin usr/lib usr/modules
echo "make node in dev/console dev/null"
mknod -m 600 dev/console c 5 1
mknod -m 600 dev/null c 1 3
mkdir mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp
mkdir var/lib var/lock var/run var/tmp
chmod 1777 tmp
chmod 1777 var/tmp
echo "-------make direction done---------"
注意我加的一个目录"usr",不加的话会出现错误,友善那坑爹的文档害得我不浅啊……无语……
5.建立/etc目录下的文件
(1)、拷贝主机 etc 目录下的passwd、group、shadow文件到 rootfs/etc目录下。
(2) etc/sysconfig目录下新建文件HOSTNAME,内容为”winson”,这里可以输入你想输入的名字 。
(3) etc/inittab文件
(4)etc/init.d/rcS
(5)etc/fstab
(6)etc/profile
6.编译busybox到rootfs中。
7.打包文件系统,我的是256M的NAND,友善那坑爹文档说用mkyaffs2img这个来打包,结果哥打包了不下数十次,没一次成功的,我就纳闷了,我都按足步骤了,怎么还这样……后来改了用mkyaffs2img-128,果然……啥也别说了,哥再次对友善的移植文档表示无语……
8.下载到目标板,运行!
具体移植过程:
1.安装交叉编译工具链
这个不说,按照文档来就行。
2.移植linux内核
先到官网下一个2.6.32的源码回来,或者用友善光盘里面的也行。不过最好不要用他光盘里面的那个,因为那个已经把所有一切的都配置好了,驱动也移植好了,啥都不用我们搞,这样不利于我们的学习,自己做一遍更加有利于加深印象。
解压内核代码:
tar -zxvf linux-2.6.32.2.tar.gz
进入内核目录修改顶层Makefile:
cd linux-2.6.32.2
ARCH ?= arm //使用的目标平台
CROSS_COMPILE ?= arm-linux- //使用的交叉编译器
事实上从2.6.31版本开始,linux已经支持mini2440了,就这样修改了平台,然后make mini2440_defconfig, make zImage编译内核下载到板子上也可以启动内核,不过会出现一系列的难以理解的问题(至少对于我来说是如此)。一开始那两天,我就是为了求快,使用了linux自己的板文件,于是怎么搞都不对,总是提示unable to xxxxxxx的错误,貌似是不能初始化一个可用的控制台,然后上网找了很多资料,还是不能解决,崩溃。于是铁定了心,重头开始搞!
现在我们不使用其默认的板文件,我们自己按照友善的移植文档的步骤来自己搞。
cd arch/arm/mach-s3c2440
把原本的mach-mini2440.c移到别的地方,等一下还要参考。COPY smdk-2440.c这个文件的内容,然后建立自己的mach-mini2440.c,粘贴。到smdk2440_map_io(void)函数,修改晶振,改成12000000,
s3c24xx_init_clocks(12000000); //修改为 12000000
因为友善的板子用的就是这个频率,一般开发板由于成本的考虑,都使用这种低频率的晶振源,然后由CPU的内部时钟逻辑提高频率,具体可以参考这篇文章。
然后修改MACHINE_START宏,宏的第一个参数一定要是MINI2440,第二个无所谓。
用VIM打开刚才复制得到的mach-mini2440.c文件,原来是smdk2440,所以将该文件中的所有的smdk2440替换成mini2440,可以在vim中,输入下面的命令进行替换;g表示全局替换,global.
除此之外,还要在 mini2440_machine_init(void)函数中,把smdk_machine_init()函数调用注释掉。为什么要注释掉……这个我也不大懂……求大神解释……
static void __init mini2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&mini2440_fb_info);
s3c_i2c0_set_platdata(NULL);
s3c_device_nand.dev.platform_data = &mini2440_nand_info; //添加
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
//smdk_machine_init()
}
修改Nand分区信息
在我们创建的mach-mini2440.c文件中添加NandFlash的分区信息,主要参考友善之臂的分区表。bootloader的分区表必须跟内核的分区表一样。不是说个格式一样,是说分区的信息一样。
内容如下:添加下面的结构体,注意,要添加到最前面,就是include完头文件之后。不然下面使用这些信息的时候,会出现编译错误,就是很常见的编译错误,变量定义在使用之后。
static struct mtd_partition mini2440_default_nand_part[] = {
[0] = {
.name = "U-boot",//这里是 bootloader所在的分区,可以放置 u-boot,
.size = 0x00040000,//对应/dev/mtdblock0
.offset = 0,
},
[1] = {
.name = "param",// ;这里是supervivi的参数区,其实也属于bootloader的
.offset = 0x00040000,//一部分,如果u-boot 比较大,可以把此区域覆盖掉
.size = 0x00020000,//不会影响系统启动,对应/dev/mtdblock1
},
[2] = {
.name = "Kernel",//内核所在的分区,大小为 5M,足够放下大部分自己定制的
.offset = 0x00060000,//巨型内核了,比如内核使用了更大的Linux Logo图片
.size = 0x00500000,//对应/dev/mtdblock2 等
},
[3] = {
.name = "root",//文件系统分区,主要用来存放yaffs2 文件系统
.offset = 0x00560000,//内容,对应/dev/mtdblock3
.size = 1024 * 1024 * 1024, //
},
//此区域代表了整片的nand flash,主要是预留使用,比如以后可以通过应用程序访
问读取/dev/mtdblock4就能实现备份整片nand flash了。 可以没哟这个分区
[4] = {
.name = "nand",
.offset = 0x00000000,
.size = 1024 * 1024 * 1024, //
}
};
还需要添加NandFlash的设置表。
//这里是开发板的nand flash 设置表,因为板子上只有一片,因此也就只有一个表
static struct s3c2410_nand_set mini2440_nand_sets[] = {
[0] = {
.name = "NAND",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(mini2440_default_nand_part),
.partitions = mini2440_default_nand_part,
},
};
//这里是nand flash本身的一些特性,一般需要对照datasheet填写,大部分情况下按照以下参数填写即可
static struct s3c2410_platform_nand mini2440_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(mini2440_nand_sets),
.sets = mini2440_nand_sets,
.ignore_unset_ecc = 1,
};
还需要把 nand flash 设备注册到系统中,
static struct platform_device *mini2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
-
&s3c_device_iis,