Linux内核移植实验指导书
1、获得Linux内核源码
我们的光盘中提供了linux-2.6.24.4的内核源码,也可以从www.kernel.org 上下载。
将linux-2.6.24.4.tar.bz2拷贝到工作目录下,解压,就可以得到完整的Linux内核源码
包:
[root@localhost 2410-s]# pwd
/root/2410-s
[root@localhost 2410-s]# cp /mnt/hgfs/arm/kernel/linux-2.6.24.4.tar.bz2 ./
[root@localhost 2410-s]# tar -xjvf linux-2.6.24.4.tar.bz2
[root@localhost 2410-s]# cd linux-2.6.24.4
2、修改Makefile
为了交叉编译内核,需要修改内核的底层Makefile:
[root@vm-dev linux-2.6.24.4]# vi Makefile
找到下面的两行:
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
修改成如下两行:
ARCH ?= arm
CROSS_COMPILE ?= arm-softfloat-linux-
上面这样修改的意思是说我们的目标平台是arm,使用的交叉编译器的前缀是
arm-softfloat-linux-.
3、得到.config文件
编译内核时会依赖于源代码目录下的.config 文件。如果没有这个文件,在make
menuconfig的时候,会默认按照i386的配置生成.config文件,而这不是我们需要的。因
此我们要有自己的.config文件。
由于我们的配置和SMDK2410开发板的类似,因此可以使用它的.config文件,只需要
把它的.config文件拷贝到源代码根目录下的.config文件即可:
[root@vm-dev linux-2.6.24.4]# cp arch/arm/configs/s3c2410_defconfig .config
4、修改Nand Flash分区
由于我们使用的是SMDK2410开发板的原型,SMDK2410开发板的NAND Flash和我们的
不一样,因此需要修改。打开arch/arm/plat-s3c24xx/common-smdk.c这个文件:
[root@vm-dev linux-2.6.24.4]# vi arch/arm/plat-s3c24xx/common-smdk.c
找到struct mtd_partition smdk_default_nand_part[]这个结构体,并修改它。修改
后的结构体如下面的代码所示:
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "Bootloader",
.size = 0x80000,
.offset = 0,
},
[1] = {
.name = "Linux Kernel",
.offset = 0x80000,
.size = SZ_2M,
},
[2] = {
.name = "Root File System",
.offset = 0x280000,
.size = SZ_4M,
},
[3] = {
.name = "User Space",
.offset = 0x680000,
.size = 0x3980000,
},
};
这样就把我们的64M的NAND Flash分为四个区:
第一个区从0x00000000到0x00080000,大小为0.5M
第二个区从0x00080000到0x00280000,大小为2M
第三个区从0x00280000到0x00680000,大小为4M
第四个区从0x00680000到0x04000000,大小为57.5M
5、添加LCD支持
我们的开发平台上配置有640*480 的液晶屏,我们来为它加上驱动支持。需要在
arch/arm/mach-s3c2410/mach-smdk2410.c中添加一些内容。
[root@vm-dev linux-2.6.24.4]# vi arch/arm/mach-s3c2410/mach-smdk2410.c
首先要包含我们的LCD使用的数据结构的头文件,增加如下内容:
#include <asm/arch/fb.h>
#include <linux/platform_device.h>
然后添加如下内容:
static struct s3c2410fb_display up2410_fb[] __initdata =
{
{
.lcdcon5 = (1<<12)|(1<<11)|(1<<9)|(1<<8)|(1<<0),
.type = (3<<5),
.width = 640,
.height = 480,
.pixclock = 39721,
.xres = 640,
.yres = 480,
.bpp = 16,
.left_margin = 40,
.right_margin = 32,
.hsync_len = 32,
.vsync_len = 2,
.upper_margin = 35,
.lower_margin = 5,
},
};
static struct s3c2410fb_mach_info up2410_fb_info __initdata =
{
.displays = up2410_fb,
.num_displays = 1,
.default_display = 0,
.gpcup = 0xffffffff,
.gpcup_mask = 0x0,
.gpccon = 0xaaaaaaaa,
.gpccon_mask = 0x0,
.gpdup = 0xffffffff,
.gpdup_mask = 0x0,
.gpdcon = 0xaaaaaaaa,
.gpdcon_mask = 0x0,
.lpcsel = 0,
};
然后,在这个文件中找到smdk2410_init这个函数,在函数的末尾添加这样一行,来
对LCD的数据进行设置:
s3c24xx_fb_set_platdata(&up2410_fb_info);
6、添加网卡驱动支持
开发板上配置了DM9000A网卡,内核已经有网卡驱动的实现代码,需要我们做一定的
配置。在arch/arm/mach-s3c2410/mach-smdk2410.c文件中添加如下内容:
static struct resource s3c_dm9ks_resource[] = {
[0] = {
.start = 0x10000000,
.end = 0x10000040,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_EINT2,
.end = IRQ_EINT2,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s3c_device_dm9ks = {
.name = "s3c2410-dm9ks",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_dm9ks_resource),
.resource = s3c_dm9ks_resource,
};
然后,把网卡数据加入smdk2410_devices数组:
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_dm9ks,
};
另外,根据我们的经典2410开发板的配置,网卡驱动需要修改。由于修改的地方比较
多,这里就不详细说明了,直接给出修改后的源文件,在我们光盘的相应src目录下。共两
个文件:dm9000.c和dm9000.h。现在需要作的只是把内核中的drivers/net目录下的这两个
文件用我们提供的文件替换掉。
[root@localhost linux-2.6.24.4]# cp /mnt/hgfs/arm/kernel/dm9000.* drivers/net/
cp:是否覆盖‘drivers/net/dm9000.c’? y
cp:是否覆盖‘drivers/net/dm9000.h’? y
[root@localhost linux-2.6.24.4]#
其中需要注意的是对开发板的初始化。我们的开发板上使用BANK2作为DM9000的IO,
中断使用EINT2,因此需要配置好BANK2和EINT2,实现的函数如下(已经在我们的驱动文
件中添加了,不需要手动添加):
static void uptech_dm9k_init(void)
{
u32 bwscon;
bwscon = __raw_readl(S3C2410_BWSCON);
bwscon&= ~(S3C2410_BWSCON_WS2|S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_32);
bwscon |= (S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_16);
__raw_writel(bwscon, S3C2410_BWSCON);
__raw_writel(S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|
S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh4|S3C2410_BANKCON_Tcah4|
S3C2410_BANKCON_Tacp 6| S3C2410_BANKCON_PMCnorm, S3C2410_BANKCON2);
set_irq_type(IRQ_EINT2,IRQT_RISING);
s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
s3c2410_gpio_pullup(S3C2410_GPF2, 0);
printk(KERN_INFO "Board init for AX88796 finished!\n");
}
然后在这个文件中的axdrv_init函数的开头部分调用这个函数:
static int __init dm9k_init_module(void)
{
uptech_dm_init();
return platform_driver_register(&dm9k_driver);
七、添加YAFFS文件系统支持
将我们提供的YAFFS的源代码yaffs2.tar.gz拷贝到linux-2.6.24.4的同级目
录下,解压该源码包,获得YAFFS源码:
[root@localhost linux-2.6.24.4]# cd ..
[root@localhost 2410-s]# pwd
/root/2410-s
[root@localhost 2410-s]# cp /mnt/hgfs/arm/kernel/yaffs2.tar.gz ./
[root@localhost 2410-s]# tar -zxvf yaffs2.tar.gz
然后进入yaffs2目录,运行./patch-ker.sh给内核打上补丁:
[root@vm-dev 2410-s]# cd yaffs2
[root@vm-dev yaffs2]# ./patch-ker.sh c ../linux-2.6.24.4/
这样打好补丁以后,再做正确的配置,内核就可以支持YAFFS文件系统了。