第三、Linux 内核的编译和移植。
这一个是重点,因为网上的大多数资源是ARM9 的,而且因为内核版本上的差异问题自己很难发现,所以自己在做这一块费了很大的功夫,如果你需要在内核中添加一些小的驱动程序来测试一下自己的内核,可以参考一下
make menuconfig 后加载你自己需要的驱动配置就可以了。 我自己在学习Linux内核移植,是参考网络资源和飞凌提供的ARM Linux2.6.28 源码做的,这些都可以在网上下载到。我要写的是在移植过程中出现的一些问题和解决办法,
1、需要修改nandflash 的分区信息
在 arch/arm/mach-s3c64xx/mach-smdk6410.c 中,这些信息我在飞凌提供的内核中找了好久都没有找到,最后才发现飞凌将这些硬件信息都进行了模块化的管理,在linux2.6.28 内核中这些信息放在了 ./arch/arm/plat-s3c/include/plat 中,而我们要使用的nandflash 分区信息 在partition.h。而在他提供的Linux2.6.36.11 将这些信息放在了 ./arch/arm/mach-s3c64xx/include/mach 中。 中飞凌将这些信息统一目录,然后系统分开调用,也是项目的需要,但这里却极大的增加了我们的开发难度,因为我们不可能一次就能高明白这里调用联系。如果我们需要加载LED 驱动的话就需要这里的 gpio 信息,如果你在编译的时候缺少那个gpio的信息头文件,就可以在这里找到。下面是mach-smdk6410.c 中添加 nandflash 分区信息的修改方法,其中蓝色字体的部分都是需要修改的部分。
添加头文件 #include <plat/nand.h>#include <linux/mtd/partitions.h>#include <mtd/mtd-abi.h>#include <asm/mach/flash.h>struct mtd_partition s3c_partition_info[] = {
{
.name = "Bootloader",
.offset = 0,
.size = (256*SZ_1K),
.mask_flags =MTD_CAP_NANDFLASH,
},
{
.name = "Kernel",
.offset = (256*SZ_1K),
.size = (4*SZ_1M) - (256*SZ_1K),
.mask_flags = MTD_CAP_NANDFLASH,
},
#if defined (CONFIG_SPLIT_ROOT_FILESYSTEM)
{
.name = "Rootfs",
.offset = (4*SZ_1M),
.size = (80*SZ_1M),//
},
#endif
{
.name = "File System",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
static struct s3c2410_nand_set s3c_nandset[]={
[0]= {
.name ="s3c24xx-nand",
.nr_chips = 1,
.nr_partitions =ARRAY_SIZE(s3c_partition_info),
.partitions =s3c_partition_info,
}
};
static struct s3c2410_platform_nand s3c_platform={
.tacls =25,
.twrph0 =55,
.sets = &s3c_nandset,
.nr_sets =ARRAY_SIZE(s3c_nandset),};
//add here…
static struct platform_device *smdk6410_devices[] __initdata = {
#ifdef CONFIG_SMDK6410_SD_CH0
&s3c_device_hsmmc0,
#endif
#ifdef CONFIG_SMDK6410_SD_CH1
&s3c_device_hsmmc1,
#endif
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_fb,
&s3c_device_ohci,
&s3c_device_usb_hsotg,
&s3c64xx_device_iisv4,
//add here
&s3c_device_nand,
//add here…
}
static void __init smdk6410_map_io(void){
u32 tmp;
//add here
s3c_device_nand.name = "s3c6410-nand";
//add here…
…
}
static void __init smdk6410_machine_init(void){
u32 cs1;
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata);
//add here
s3c_nand_set_platdata(&s3c_platform);//
//add here…
}
1.1 关闭NAND。 ECC 校验。ECC是“Error Correcting Code”的简写,中文名称是“错误检查和纠正”。
在文件 drivers/mtd/nand/s3c_nand.c 文件中,将
nand->ecc.mode = NAND_ECC_SOFT; 改为:
nand->ecc.mode = NAND_ECC_NONE;
配置中去掉的这个选项在代码中并没有完全去掉,只是去掉了硬件校验的方式,换成了软件校验。只有在代码中给改成NAND_ECC_NONE,才不会校验,但是这样是不提倡的。
2、 给内核打yaffs2文件系统的补丁 如果你需要就打上。
第一步,我们需要YAFFS2的源码,如果大家有兴趣想了解YAFFS2文件系统的驱动原理的话可以直接去访问他们的官网,地址是,上面说的很详细的,也有源码下载地址,怕大家进去后难找,直接贴出YAFFS2的最新源码地址吧?p=yaffs2.git;a=summary,直接点击,点那个2011年6月28号的那个版本,点击最右边的SNAPSHOT下载,这个是目前最新的YAFFS2的源码了
第二步,将下载下来的YAFFS2最新源码 YAFFS2.tar.gz 放入你LINUX的任意一个目录下,执行 tar zxvf YAFFS2.tar.gz 然后进入YAFFS2源码包,由于最新的源码再执行脚本 patch-ker.sh 时 有四个参数,可以追加:c,l,m,s,
./patch-ker.sh c/l m/s kernelpath
if c/l is c, then copy. If l then link
if m/s is m, then use multi version code. If s then use single version code
上面这段英文应该很好懂吧,简而言之,C 是复制文件,L是链接文件,M是多种,S是单个的,
那么在这里,我们只需执行 ./patch-ker.sh c m /your linux2.6.39.2 kernel directory
上面命令完成下面三件事情:
(1) 修改内核fs/Kconfig
增加一行:source "fs/yaffs2/Kconfig"
(2) 修改内核fs/Kconfig
增加一行:ojb-$(CONFIG_YAFFS_FS) +=yaffs2/
(3) 在内核fs/目录下创建yaffs2目录
将yaffs2源码目录下面的Makefile.kernel文件复制为内核fs/yaffs2/Makefie;
将yaffs2 源码目录的Kconfig文件复制到内核fs/yaffs2目录下;
将yaffs2源码目录下的*.c *.h文件复制到内核fs/yaffs2目录下.打完补丁要将yaffs2的源码拷贝到fs目录下,要不然编译的时候会出现yaffs_fs.c 的报错信息。
配置支持 yaffs2 文件系统。
Filesystem--->
Miscellaneous filesystems--->
<*>YAFFS2 file system support
[*] Lets Yaffs do its own ECC
Native language support
<*> Codepage 437 (United States,Canada)
<*>Simplified Chinese charset(GB2312)
<*>Traditional Chinese charset(Big5)
<*>NLS ISO 8859-1(Latin1:Western European Languages)
<*>NLS UTF-8
3、修改的机器号
网上很多关于arm9 的都要这样做,这样做的原理是,在uboot启动的时候会传来一个机器号,如果的内核的机器号和uboot的传来的相同才能启动,而如果不是就不可以启动。 为什么我在写Uboot 时强调如果你是OK6410的板子,后者说是按照飞凌源码来学习的话,不要修改刚才的smdk6410 的参数,因为飞凌uboot 和 他们自己的内核使用这个smdk6410 的机器码来传递。 所以加入你上面的uboot没有修改的话,这里也不需要修改。