基于s3c2410開發(fā)板的2.6.26.5內(nèi)核移植
這是本人的一個課程總結(jié),其中涉及幾個驅(qū)動文件在最小內(nèi)核編譯時是不需要的。
kernel:2.6.26.5
gcc:arm-linux-gcc(gcc 3.4.1)
cpu:s3c2410
編譯設(shè)置
使用arm-linux-交叉編譯工具鏈
修改根目錄下Makefile
ARCH ?= arm
CROSS_COMPILE ?=arm-linux-
內(nèi)核移植
nand分區(qū)
修改arch/arm/plat-s3c24xx/common-smdk.c,找到相關(guān)代碼做如下修改
static struct mtd_partition smdk_default_nand_part[] = {
/* [0] = {
.name = "Boot Agent",
.size = SZ_16K,
.offset = 0,
},
[1] = {
.name = "S3C2410 flash partition 1",
.offset = 0,
.size = SZ_2M,
},
[2] = {
.name = "S3C2410 flash partition 2",
.offset = SZ_4M,
.size = SZ_4M,
},
[3] = {
.name = "S3C2410 flash partition 3",
.offset = SZ_8M,
.size = SZ_2M,
},
[4] = {
.name = "S3C2410 flash partition 4",
.offset = SZ_1M * 10,
.size = SZ_4M,
},
[5] = {
.name = "S3C2410 flash partition 5",
.offset = SZ_1M * 14,
.size = SZ_1M * 10,
},
[6] = {
.name = "S3C2410 flash partition 6",
.offset = SZ_1M * 24,
.size = SZ_1M * 24,
},
[7] = {
.name = "S3C2410 flash partition 7",
.offset = SZ_1M * 48,
.size = SZ_16M,
}*/
/* start: for harbour */
[0] = {
name: "bootloader",
size: 0x00100000,
offset: 0x0,
},
[1] = {
name: "kernel",
size: 0x00300000,
offset: 0x00100000,
},
[2] = {
name: "root",
size: 0x02800000,
offset: 0x00400000,
},
[3] = {
name: "user",
size: 0x00f00000,
offset: 0x02d00000,
}
};
/* end: for harbour */
static struct s3c2410_nand_set smdk_nand_sets[] = {
[0] = {
.name = "NAND",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
.partitions = smdk_default_nand_part,
},
};
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 0,
.twrph0 = 30,
.twrph1 = 0,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
此時如果運(yùn)行
#make s3c2410_defconfig啟用s3c2410默認(rèn)內(nèi)核配置
#make menuconfig
修改
boot option
default command line
root=/dev/mtdblock2 init=linuxrc console=ttySAC0,115200
運(yùn)行
#make bzImage
此時的內(nèi)核就可在板上跑通了。
觸摸屏驅(qū)動移植
修改arch/arm/mach-s3c2410/mach-smdk2410.c,添加
static struct s3c2410ts_mach_info s3c2410_tscfg __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
};
修改static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
/*start: for harbour*/
&s3c_device_ts, //加入此行
/*end: for harbour*/
};
在static void __init smdk2410_init(void)中加入:
s3c24xx_ts_set_platdata(&s3c2410_tscfg);
在include/asm-arm/plat-s3c24xx/devs.h中加入
extern struct platform_device s3c_device_ts;
在driver/input/touchscreen/下添加s3c2410-ts.c文件,
在include/asm-arm/arch-s3c2410/下添加ts.h文件,ts.h文件內(nèi)容如下:
#ifndef __ASM_ARM_S3C2410_TS_H
#define __ASM_ARM_S3C2410_TS_H
struct s3c2410ts_mach_info {
int delay;
int presc;
int oversampling_shift;
};
extern void __init s3c24xx_ts_set_platdata(struct s3c2410ts_mach_info *);
#endif /* __ASM_ARM_S3C2410_TS_H */
修改arch/arm/plat-s3c24xx/devs.c,加入
#include
/* Touch Screen Controller */
struct platform_device s3c_device_ts = {
.name = "s3c2410-ts",
.id = -1,
};
EXPORT_SYMBOL(s3c_device_ts);
void __init s3c24xx_ts_set_platdata(struct s3c2410ts_mach_info *pd)
{
struct s3c2410ts_mach_info *npd;
npd = kmalloc(sizeof(*npd), GFP_KERNEL);
if (npd) {
memcpy(npd, pd, sizeof(*npd));
s3c_device_ts.dev.platform_data = npd;
} else {
printk(KERN_ERR "no memory for TS platform datan");
}
}
將s3c2410-ts.c文件拷入drivers/input/touchscreen/目錄下。
修改drivers/input/touchscreen/Makefile
加入obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410-ts.o
修改drivers/input/touchscreen/Kconfig,在if INPUT_TOUCHSCREEN下加入
config TOUCHSCREEN_S3C2410
tristate “s3c2410 touchscreen”
depends on ARCH_SMDK2410
default y
help
This is used for supporting s3c2410 touchscreen.
LCD驅(qū)動移植
修改arch/arm/mach-s3c2410/mach-smdk2410.c,添加
static struct s3c2410fb_display s3c2410fb_lcd_display __initdata = {
.width = 320,
.height = 240,
.xres = 320,
.yres = 240,
.bpp = 16,
.lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVCLK |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_HWSWP |
(0<<7) |
(0<<6) |
(0<<1),
.type =S3C2410_LCDCON1_TFT,
.pixclock = 270000,
.left_margin = 7,
.right_margin = 8,
.hsync_len = 29,
.upper_margin = 11,
.lower_margin = 14,
.vsync_len = 2,
};
static struct s3c2410fb_mach_info s3c2410fb_lcdcfg __initdata = {
.displays = &s3c2410fb_lcd_display,
.num_displays = 1,
.default_display = 0,
.lpcsel = 0x0,
.gpccon = 0xaa9556a9,
.gpccon_mask = 0xfffffff,
.gpcup = 0xffffffff,
.gpcup_mask = 0xffffffff,
.gpdcon = 0xaaaaaaaa,
.gpdcon_mask = 0xfffffff,
.gpdup = 0xffffffff,
.gpdup_mask = 0xffffffff,
};
在static void __init smdk2410_init(void)中加入:
s3c24xx_fb_set_platdata(&s3c2410fb_lcdcfg);
用提供的s3c2410fb.c.nbsp;替換drivers/video/s3c2410fb.c.
聲卡驅(qū)動移植
將s3c2410sound.c加到目錄/sound/oss下;
修改sound/oss下的Kconfig文件:
在文件中添加:
Config S3C2410_SOUND_OSS
Tristate “S3C2410 1341 sound driver ”
修改/linux-2.6.14/sound/oss下的Makefile文件:
在文件中添加一行:
Obj-$(CONFIG_S3C2410_SOUND_OSS) += s3c2410sound.o
網(wǎng)卡(DM9000)驅(qū)動移植
修改arch/arm/mach-s3c2410/mach-smdk2410.c,找到如下代碼修改:
#define pSMDK2410_ETH_IO (__phys_to_pfn(0x18000000))
static struct map_desc smdk2410_iodesc[] __initdata = {
/* start: for harbour */
{vSMDK2410_ETH_IO, pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE},
/* end: for harbour */
};
在如下結(jié)構(gòu)體中添加:
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_dm9000,
};
修改arch/arm/plat-s3c24xx/devs.c中添加:
#include
#define DM9000A_BASE 0x18000300
#define DM9000A_OFFSET1 0x03
#define DM9000A_OFFSET2 0x04
static struct resource s3c_dm9000_resource[] = {
[0] = {
.start = DM9000A_BASE, // 0x19000000 + 0x300,
.end = DM9000A_BASE+DM9000A_OFFSET1,//0x19000000 + 0x300 + 0x03,
.flags = IORESOURCE_MEM
},
[1] = {
.start = DM9000A_BASE+DM9000A_OFFSET2,//0x19000000 + 0x300 + 0x04,
.end = DM9000A_BASE+DM9000A_OFFSET2+DM9000A_OFFSET1, //old is 7f 0x3f
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT19,
.end = IRQ_EINT19,
.flags = IORESOURCE_IRQ,//|IORESOURCE_IRQ_LOWEDGE,
}
};
static struct dm9000_plat_data s3c_device_dm9000_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
struct platform_device s3c_device_dm9000 = {
.name= "dm9000",
.id= -1,
.num_resources= ARRAY_SIZE(s3c_dm9000_resource),
.resource= s3c_dm9000_resource,
.dev= {
.platform_data = &s3c_device_dm9000_platdata,
}
};
EXPORT_SYMBOL(s3c_device_dm9000);
修改drivers/net/dm9000.c:用提供的dm9000.c替換原有的文件。
文件系統(tǒng)建立
利用原來的rootfs文件目錄,在dev目錄下建立設(shè)備文件,
#mknod console c 5 1
#mknod null c 1 3
#mknod zero c 1 5
#mkdir input
#mknod mice c 13 63
#mknod mouse0 c 13 32
#mknod event0 c 13 64
#mkdir mtdblock
#mknod 0 b 31 0
#mknod 1 b 31 1
#mknod 2 b 31 2
#mknod 3 b 31 3
#mkdir vc
#mknod 0 c 4 0
#mknod 1 c 4 1
#mknod 2 c 4 2
#mkdir tts
#mknod 0 c 204 64
#mknod 1 c 204 65
#mknod 2 c 204 66
#mkdir shm
#mkdir usb
其他的文件可根據(jù)需要如此添加,由于cramfs為只讀文件系統(tǒng),2.6.26.5內(nèi)核去掉了devfs,所以要在文件系統(tǒng)中建立好需要的文件節(jié)點(diǎn),或者是將dev目錄掛載成可讀寫文件系統(tǒng),使用udev來添加設(shè)備節(jié)點(diǎn)。
修改usr/etc/rc.local
注釋掉rm –r /dev/ts
ln –sf /dev/input/mouse0 /dev/ts
目的是為了消除一條錯誤提示信息。
內(nèi)核配置
修改內(nèi)核源碼根目錄下的Makefile,
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
直接使用內(nèi)核中專門為s3c2410提供的配置文件,在arch/arm/configs下
#make s3c2410_defconfig
#make menuconfig進(jìn)行其他配置
添加tmpfs支持
File systems ->
Pseudo filesystems >
[*] Virtual memory file system support (former shm fs)
這樣就可以將tmpfs進(jìn)行掛載,來開辟出可寫的目錄。
選中觸摸屏接口
Device Drivers->
Input device support ->
[*]Event interface
2.6.26.5內(nèi)核用event接口取代了原來的tsdev接口,因此此處應(yīng)選中event interface。