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,

},

};

 

这样就把我们的64MNAND Flash分为四个区:

第一个区从0x000000000x00080000,大小为0.5M

第二个区从0x000800000x00280000,大小为2M

第三个区从0x002800000x00680000,大小为4M

第四个区从0x006800000x04000000,大小为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.cdm9000.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作为DM9000IO

中断使用EINT2,因此需要配置好BANK2EINT2,实现的函数如下(已经在我们的驱动文

件中添加了,不需要手动添加):

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文件系统了。