内核版本为linux-2.6.29.4,目标开发板为mini2440开发板
源码下载:http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.29.4.tar.bz2
移植步骤:
1, 修改顶层Makefile
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
改为:
ARCH ?= arm
CROSS_COMPILE ?=arm-linux-
2, 修改时钟
smdk2440的晶振与mini2440的配置的不同。
vi arch/arm/mach-s3c2440/mach-smdk2440.c
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
/*modified by xxx,************************************************************/
s3c24xx_init_clocks(12000000); //mini2440配置的为12MHZ的晶振
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
3, 修改nandflash的分区信息。要确保跟bootloader的分区信息移植。
vi arch/arm/plat-s3c24xx/common-smdk.c
/*modifiedby xxx ,for 2440**************************************************/
static struct mtd_partitionsmdk_default_nand_part[] = {
[0]= { //对应 /dev/mtdblock0
.name = "U-Boot",
.size = 0x40000,
.offset = 0,
},
[1]= { /对应 /dev/mtdblock1
.name = "U-Boot_env",
.offset= 0x40000,
.size = 0x20000,
},
[2]= { /对应 /dev/mtdblock2
.name = "Kernel",
.offset= 0x60000,
.size = 0x500000,
},
[3]= { /对应 /dev/mtdblock3
.name = "Root",
.offset = 0x560000,
.size = 1024*1024*1024,
},
};
4,添加DM9000网卡驱动
vi arch/arm/mach-s3c2440/mach-smdk2440.c
static struct platform_device *smdk2440_devices[ ] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
/*add by xxxxx ,for mini2440*******************************************************/
&s3c_device_dm9000,
&s3c_device_rtc,
};
修改arch/arm/plat-s3c24xx/devs.c
/*add by xxx ,for mini2440 dm9000*****************************************/
#include<linux/dm9000.h>
#define DM9000_BASE 0x20000300
static struct resource s3c_dm9000_resource[ ]={
[0]={
.start=DM9000_BASE,
.end =DM9000_BASE+0x03,
.flags=IORESOURCE_MEM,
},
[1]={
.start=DM9000_BASE+0x04,
.end =DM9000_BASE+0x04+0x7c,
.flags=IORESOURCE_MEM,
},
[2]={
.start=IRQ_EINT7,
.end =IRQ_EINT7,
.flags=IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
},
};
static struct dm9000_plat_data s3c_device_dm9000_platdata={
.flags=DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
};
struct platform_device s3c_device_dm9000={
.name="dm9000",
.id=0,
.num_resources=ARRAY_SIZE(s3c_dm9000_resource),
.resource=s3c_dm9000_resource,
.dev={
.platform_data=&s3c_device_dm9000_platdata,
}
};
EXPORT_SYMBOL(s3c_device_dm9000);
/*end add**********************************************************************/
修改arch/arm/plat-s3c/include/plat/devs.h
extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
后面添加:
extern struct platform_device s3c_device_dm9000;
5,配置及编译内核
# Make s3c2410_defconfig //使用s3c2410的默认配置
#make menuconfig //只需修改下面几项
[*] Enable loadable module support --->
[*] Module unloading
选择这一个,剩下的可以去掉
System Type ---->
[*] S3C2410 DMA support
S3C2440 Machines --->
[*] SMDK2440
[*] SMDK2440 with S3C2440 CPU module
//System Type这部分,只选这些,其他可以全部去掉,
Boot option ----->
修改启动参数为:noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
可能根据个人板子的设置会不一样,我的是从Nand Flash中加载文件系统,其中mtdblock2(即添加的nand分区smdk_default_nand_part[2])是存放我的Linux文件系统的分区。不过,在bootloader可以传递内核参数的情况下这个设置是无效的。
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
[*] MTD partitioning support
<*> NAND Device Support --->
<*> NAND Flash support for S3C2410/S3C2440 SoC
[ ] S3C2410 NAND Hardware ECC //去除ECC校验
[*] Network device support --->
[*] Ethernet (10 or 100Mbit) --->
<*> DM9000 support
Kernel Features ->
[*]Use the ARM EABI to compile the kernel
[*] Allow old ABI binaries to run with this kernel
至此,修改完毕,重新编译即可
若启动过程出现
UncompressingLinux......................................................................................done, booting the kernel.
并提示machine 号码不匹配的情况,这是因为我们直接在mach-smdk2440.c中修改的代码,导致我们的开发板型号被误认为 smdk2440所致。
我们来看一下mach-smdk2440.c的最后一段代码:
vi arch/arm/mach-s3c2440/mach-smdk2440.c
在最后定义了这样的宏:
MACHINE_START(S3C2440 , ”SMDK2440”)
···
MACHINE_END
该宏在 arch/arm/include/asm/mach/arch.h中有如下定义:
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__attribute_used__ \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
最后展开来也就是:
.nr=MACH_TYPE_S3C2440
.name=SMDK2440
而关于开发板的信息在arch/arm/include/asm/mach/arch.h中也有定义:
struct machine_desc {
unsigned int nr; /*architecture number*/
```
const char *name: /*architecture name*/
}
从以上分析可知,我们的开发板定义成了SMDK2440开发板,而不是mini2440。
这里.nr=MACH_TYPE_S3C2440
也就是说S3C2440就是machine ID的代号,具体值定义在
在arch/arm/tools/mach-types中
s3c2440 ARCH_S3C2440 S3C2440 362
原来我们的machine ID是362~
那bootloader传递进来的值是多少呢?~
Error: unrecognized/unsupported machine ID (r1 = 0x000007cf).
注意到没有?~ 0x7CF转换成10进制也就是1999(即mini2440的machine ID)
所以只要修改内核的 arch/arm/tools/mach-types文件中的如下项即可
s3c2440 ARCH_3C2440 S3C2440 1999
内核支持yafffs文件系统:
可以使用git工具下载yaffs工具,也可以直接在这里下载:
http://download.youkuaiyun.com/detail/fengyaqi123/4525414
解压后,进入yaffs2文件夹
#cd yaffs2
#./patch-ker.sh c/home/xxx/Documents/linux-2.6.29.4
然后
#make menuconfig
FileSystems-->
[*]Miscellaneousfilesystems--->
[*]YAFFS2file system support
退出配置,重新编译即可
#make uImage
参考:http://www.linuxidc.com/Linux/2011-04/34979.htm
附:
由于2.6.29自带的dm9000的驱动不完善,完成会根文件系统的移植后,开发板ping主机时会出现严重的丢包现象,将友善的dm9000.c和dm9000.h文件拷过来覆盖即可。