转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/22829023
写此文时,已是深夜。不得不说回想起来还是时间比较长了。但是这是值得的。。。本文将从0开始移植内核。会对我出现的一些错误进行整理。希望对大家有些帮助。
内核版本linux-2.6.22.6(比较老,但是基本步骤都差不多)开发环境:mini2440
电脑主机系统:Ubuntu 10.04.4开发板bootloader:uboot
交叉编译器 arm-linux-gcc-4.3.2
1.首先到到 http://www.kernel.org/去下载内核源码。我是下载的linux-2.6.22.6.tar.bz2
2.将内核源码解压,可以解压到任意你想放源码文件的地方
tar xvzf linux-2.6.22.6.tar.gz
3.进入内核源码,修改顶层Makefile文件中的编译器选项。
gedit Makefile 打开Makefile
将makefile里的
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
修改为
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
4.修改内核中平台的时钟频率(mini2440开发板使用12M晶振)。
修改内核源码 “arch/arm/mach- s3c2440/mach-smdk2440.c” 文件的 163 行,
把 16.9344MHz 修改为12MHz
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(12000000); //修改为 12000000,默认为 16934400
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
5.修改对nand的分区信息。要让内核知道nand flash的分区信息,设置成跟bootloader一致。
在arch/arm/plat-s3c24xx/common-smdk.c(我用的3.4.91内核此文件在/arch/arm/mach-s3c24xx/common-smdk.c)中修改smdk_default_nand_part[],注意这个一定
要跟bootloader的一致。在我的板子中修改如下:
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "supervivi",
.size = 0x000000030000,
.offset = 0,
},
[1] = {
.name = "Kernel",
.offset = 0x000000050000,
.size = 0x000000200000,
},
[2] = {
.name = "root",
.offset = 0x000000250000,
.size = 0x000003DAC000,
}
};
此处我通过supervivi查看到的分区信息写进去竟然不对,我通过mini2440原来的内核启动信息查
到分区信息如下:
Creating 3 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x000000000000-0x000000030000 : "supervivi"
0x000000050000-0x000000250000 : "Kernel"
0x000000250000-0x000003ffc000 : "root"
按照韦东山老师的uboot修改:
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "bootloader",
.size = 0x00040000,
.offset = 0x00000000,
},
[1] = {
.name = "params",
.offset = 0x00040000,
.size = 0x00020000,
},
[2] = {
.name = "kernel",
.offset = 0x00060000,
.size = 0x00200000,
},
[3] = {
.name = "root",
.offset = 0x00260000,
.size = 0x0fda0000,
},
};
韦东山老师的uboot分区:(在uboot下输入命令mtdparts)
device nand0
#: name size offset mask_flags
0: bootloader 0x00040000 0x00000000 0
1: params 0x00020000 0x00040000 0
2: kernel 0x00200000 0x00060000 0
3: root 0x0fda0000 0x00260000 0
active partition: nand0,0 - (bootloader) 0x00040000 @ 0x00000000
defaults:
mtdids : nand0=nandflash0
mtdparts: mtdparts=nandflash0:256k@0(bootloader),128k(params),2m(kernel),-(root)
***********************************************************************************************************
2014.7.27补充
后期做项目发现内核实在精简不到2M一下,所以更改了uboot分区,下面是修改方法:
uboot命令行中:setenv mtdparts mtdparts=nandflash0:256k@0(bootloader),128k(params),3m(kernel),-(root)
然后: save
再次mtdparts :
device nand0
#: name size offset mask_flags
0: bootloader 0x00040000 0x00000000 0
1: params 0x00020000 0x00040000 0
2: kernel 0x00300000 0x00060000 0
3: root 0x0fca0000 0x00360000 0
active partition: nand0,0 - (bootloader) 0x00040000 @ 0x00000000
***********************************************************************************************************
注释:我用的是韦东山老师的uboot。。大家根据自己的uboot分区进行修改。
另外这个文件还要修改smdk_nand_info如下:
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 0, //default is 20
.twrph0 = 30, //default is 60
.twrph1 = 0, //defualt is 20
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
//这个没修改,直接过了。
6.修改机器码。
mini2440 使用的 supervivi 的机器码是782,这里需要修改机器码,否则会出现不能启动的情况。
机器码保存在内核源码的 “arch/arm/tools/mach-types” 文件中,在大概 379 行,把原来的 362
改为782保存即可。
//用韦东山老师uboot的同学此处可以省略
7. 修改drivers/mtd/nand/s3c2410.c,去掉nand flash 的ECC。(此步未做,通过)
如果内核是通过U-BOOT 写到Nand Flash的, U-BOOT 通过的软件ECC算法产生ECC校 验码,
这与内核校验的ECC码不一样, 内核中的ECC码是由S3C2410中Nand Flash控制器产生 的。所以,
我在这里选择禁止内核ECC校验。
搜索关键字NAND_ECC_SOFT,s3c2410_nand_init_chip函数里,修改NAND_ECC_SOFT
为 NAND_ECC_NONE
8.增加Yaffs2文件系统的支持
首先到 http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/网站下 载一个 yaffs 文件系统的补丁。
得到补丁包后,解压补丁,然后打上 yaffs2 的补丁,方法如下:
#tar xvfz cvs-root.tar.gz (解压得到补丁目录 cvs)
#cd cvs/yaffs2/ (进到 yaffs2 的补丁目录下)
# ./patch-ker.sh c /work/transplantation/trans_show/linux-2.6.22.6
(执行补丁脚本,打补丁到内核中,其中/work/transplantation/trans_show/linux-2.6.22.6
为内核源码的地址)
此时到内核源码的“fs/”目录下面您将看到新添加了一个名为“yaffs2/”的目录,同时 fs/目录下面的
Makefile 文件和 Kconfig 文件也添加了 yaffs2 的配置和编译条件。
9.配置内核
调用自带的一个默认配置单, 该配置单在内核源码的 “arch/arm/configs/”
目录下面,名为:“s3c2410_defconfig”,该配置文件里面选择了几乎所有的和 S3C24XX 系列
CPU 相关的 配置选项,我们完全可以在该配置单的基础上进行配置。
# cp arch/arm/configs/s3c2410_defconfig .config
# make menuconfig
(1).General setup --->
[*] Configure standard kernel features (for small systems) --->
选上这项,否则文件系统中的一些选项不会出现
(2). System Type ---->
[*] S3C2410 DMA support [*] Support ARM920T processor
S3C2440 Machines --->
[*] SMDK2440
[*] SMDK2440 with S3C2440 CPU module
(3).[*] Enable loadable module support --->
[*] Module unloading
(4).Device Drivers --->
<*> Memory Technology Device (MTD) support --->
[*] MTD partitioning support
<*> NAND Device Support --->
<*> NAND Flash support for S3C2410/S3C2440 SoC
[ ] S3C2410 NAND Hardware ECC //这个要去掉
[*] Network device support --->
[*] Ethernet (10 or 100Mbit) --->
<*> DM9000 support
< > Real Time Clock --->
(5).File systems----->
Miscellaneous filesystems --->
<*>YAFFS2 file system support
(6).kernel Features----->
[*]Use the ARM EABI to compile the Kernel
保存退出
10.编译内核 make zImage
编译完成后下载内核启动即可。
出现问题:1.make menuconfig的时候出现一大堆错误和警告,错误足足有一页多,就不贴了。
解决办法是
$sudo apt-get install libncurses5-dev
2.下载时候出现Verifying Checksum ... Bad Data CRC
解决办法
配置好内核按照如上步骤make后。生成的uImage看下大小,注意不要比你UBOOT里面分配的区间大。
3.
下载内核到flash中,运行到如下即停止没有下文:
Uncompressing Linux……………………done,booting the kernel
解决办法
确保在配置内核时选上了在Device Drivers->Character devices->Serial drivers中选择加载Samsung SoC serial support ,然后再选上Support for console on Samsung SoC serial port 。
4 出现如下警告
解决办法:
在device drivers -> Memory Technology Device (MTD) support --->
发现里面有个选项:
Caching block device access to MTD devices这个选项配置上
当你解决完前四个问题后,你会发现你能够烧写YAFFS文件系统了。当你想烧写Jffs系统的时候你会惊讶的发现烧写不进去
5.解决办法。在启动UBOOT的时候进行如下设置。
当然你要想再烧写YAFFS还需要再设置回来。至于原因就是uboot没能够自动识别文件系统类型。
本文参考的资料:韦东山视频第一期(内核移植)
http://blog.csdn.net/hpwzd/article/details/7365781(虽然他也是转载的,但是原文地址连接打不开,如原作者看到,请与我联系)
排名不分先后