FL2440开发板内核移植笔记
参考:http://bbs.witech.com.cn/thread-468-1-1.html
宿主机:RedhatLinux AS4
目标机:s3c2440
交叉编译器:arm-linux-gcc-3.4.1或者arm-linux-gcc4.3.2
交叉编译器路径:/usr/local/arm/3.4.1(如果用4.3.2,则修改成/usr/local/arm/4.3.2)
要移植的内核版本:linux-2.6.33
文件系统类型:yaffs2(目前使用光盘中linux-2.6.28的文件系统touch.yaffs)
笔记作者:japleak
下载内核linux-2.6.33.tar.gz(http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.33.tar.gz中可以找到),然后还需要下载yaffs2文件系统,目的是为了给内核打补丁。下载地址为:http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/yaffs2.tar.gz?view=tar(此步骤很重要,如果yaffs2不正确,可能引起无法正常编译通过)。
将下载的文件存放在/usr/src/中。
分别解压缩:
[root@WEB188src]#tarxzflinux-2.6.33.tar.gz
[root@WEB188src]# tar xzf yaffs2.tar.gz
为内核增加yaffs2补丁
[root@WEB188src]#cdyaffs2
[root@WEB188yaffs2]# ./patch-ker.sh c ../linux-2.6.33/
Updating../linux-2.6.33//fs/Kconfig
Updating../linux-2.6.33//fs/Makefile
网上的教程都是说要修改机器码的,但是经我测试,是完全不用修改的,无论是在2.6.12还是在2.6.28或者是2.6.33,有兴趣的同学可以测试下,附网上修改机器码教程如下(修改机器码。进入内核目录,修改机器码跟bootloader的机器码一致(FL2440为193)
[root@WEB188yaffs2]# cd ../linux-2.6.33
[root@WEB188linux-2.6.33]#vi arch/arm/tools/mach-types
首先删除以下行:
s3c2410 ARCH_S3C2410 S3C2410 182
然后将以下行:
s3c2440 ARCH_S3C2440 S3C2440 362
修改为:
s3c2440 ARCH_S3C2440 S3C2440 193
)
指定目标板machine、编译器和编译器路径。修改Makefile文件,注意将CROSS_COMPILE对应到你系统中交叉编译器地址
[root@WEB188yaffs2]#viMakefile
将两行:
ARCH ?= $(SUBARCH)
CROSS_COMPILE?=
修改为以下两行:
ARCH?=arm
CROSS_COMPILE?=/usr/local/arm/3.4.1/bin/arm-linux-
注意:其实这里直接改成CROSS_COMPILE ?=arm-linux-,然后在环境变量中再添加/usr/local/arm/3.4.1/bin更加好,因为直接修改成CROSS_COMPILE ?=/usr/local/arm/3.4.1/bin/arm-linux-的话会有时候出错的。
网上说的是要增加devfs文件管理器的支持,但是我不增加也可以让内核跑起来的,有兴趣的同学可以测试下,反正我是没有增加devfs文件管理器的支持的。附增加devfs文件管理器的支持:
[root@WEB188linux-2.6.33]# vi fs/Kconfig
找到以下行:
menu"Pseudo filesystems"
在此行后面增加以下内容:
configDEVFS_FS
bool "/dev filesystem support (OBSOLETE)"
default y
configDEVFS_MOUNT
bool"Automatically mount at boot"
defaulty
dependson DEVFS_FS
注意:这个一定要修改的,不然会显示乱码。修改晶振频率(可解决打印信息乱码问题)。修改文件arch/arm/mach-s3c2440/mach-smdk2440.c
[root@WEB188linux-2.6.33]# vi arch/arm/mach-s3c2440/mach-smdk2440.c
将如下行:
s3c24xx_init_clocks(16934400);
修改为:
s3c24xx_init_clocks(12000000);
这里要对应你们bootloader中的分区信息的,可能有些开发板不同,自己参照自己的bootloader修改吧,这个是我的bootloader中的分区信息。修改MTD分区。打开文件arch/arm/plat-s3c24xx/common-smdk.c,此处注意两个地方:一、必须跟bootloader分区一样,二、文件系统fs_yaffs必须在第4个分区,即索引号为3。其他一些分区信息可以不要,如下:
[root@WEB188linux-2.6.33]# vi arch/arm/plat-s3c24xx/common-smdk.c
找到staticstruct mtd_partition smdk_default_nand_part[]的结构体,将内容修改为:
[0] = {
.name ="boot",
.size =0x00020000,
.offset = 0
},
[1]= {
.name="bootParam",
.size =0x00060000,
.offset =0x00020000,
},
[2] = {
.name ="Kernel",
.size =0x00300000,
.offset =0x00500000,
},
[3] = {
.name ="fs_yaffs",
.size =0x03c00000,
.offset =0x00800000,
},
[4] = {
.name ="eboot",
.size =0x00080000,
.offset=0x04400000,
},
[5] = {
.name ="WINCE",
.size =0x03b80000,
.offset =0x04480000,
}
关闭ECC校验。修改文件drivers/mtd/nand/s3c2410.c
[root@WEB188linux-2.6.33]#vidrivers/mtd/nand/s3c2410.c
将以下行:
chip->ecc.mode = NAND_ECC_SOFT;
修改为:
chip->ecc.mode=NAND_ECC_NONE;
修改nandflash驱动,支持K9F1G08的nandflash。文件为:drivers/mtd/nand/nand_bbt.c
[root@WEB188linux-2.6.33]# vi drivers/mtd/nand/nand_bbt.c
将以下两个部分进行修改
staticstructnand_bbt_descrlargepage_memorybased={
.options = 0,
.offs = 0,
.len=1,//原始值为2,改成1
.pattern =scan_ff_pattern
};
staticstruct nand_bbt_descr largepage_flashbased = {
.options =NAND_BBT_SCAN2NDPAGE,
.offs=0,
.len=2,//原始值为2,改成1
.pattern =scan_ff_pattern
};
把s3c2410的默认配置写入config文件(有的yaffs2可能会出错)。
[root@WEB188linux-2.6.33]# make s3c2410_defconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/docproc
HOSTCCscripts/basic/hash
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/kxgettext.o
SHIPPEDscripts/kconfig/zconf.tab.c
SHIPPEDscripts/kconfig/lex.zconf.c
SHIPPEDscripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
fs/yaffs2/Kconfig:179:unknown option "boot"
make[1]:***[s3c2410_defconfig]错误1
make:*** [s3c2410_defconfig]错误2
以上出现错误,主要是补丁造成,修改fs/yaffs2/Kconfig的179行,将boot改成bool,即改成如下:
bool"Disable yaffs2 block refreshing"
[root@WEB188linux-2.6.33]# make s3c2410_defconfig
#
#configuration written to .config
#
配置内核,注意SystemType中,S3C2440中只选择以下内容即可。
[root@WEB188linux-2.6.33]# make menuconfig
配置CPU选项(记得跟S3C2440Machines平级的其它以及子项都不选)
SystemType --->
S3C2440 Machines --->
[*] SMDK2440
[*] SMDK2440 withS3C2440 CPU module
配置yaffs2选项
Filesystems --->
[*]Miscellaneousfilesystems--->
<*> YAFFS2 filesystem support
-*- 512 byte /page devices
-*- 2048 byte(or larger) / page devices
[*] Autoselect yaffs2 format
[*] Cacheshort names in RAM
最后等着基本内核大功告成把。
[root@WEB188linux-2.6.33]#makezImage
移植USBhost驱动,仅仅需要修改配置即可
[root@WEB188linux-2.6.33]# make menuconfig
DeviceDrivers --->
[*] USB support --->
{*} Support forHost-side USB
[*]USBdevicefilesystem(DEPRECATED)
[*] USB deviceclass-devices (DEPRECATED)
<*> OHCI HCDsupport
<*> USB MassStorage support
[*] HID Devices --->
{*} Generic HIDsupport
[*] /dev/hidraw rawHID device support
SCSI device support --->
<*> SCSI devicesupport
[*] legacy /proc/scsi/support
<*> SCSI disksupport
<*> SCSI tapesupport
移植RTC驱动
[root@WEB188linux-2.6.33]# make menuconfig
DeviceDrivers --->
<*> Real Time Clock --->
[*] Set system timefrom RTC on startup and resume
(rtc0) RTC used to setthe system time
[ ] RTC debug support
***RTCinterfaces***
[*] /sys/class/rtc/rtcN (sysfs)
[*] /proc/driver/rtc(procfs for rtc0)
[*] /dev/rtcN(character devices)
<*> Samsung S3Cseries SoC RTC
然后添加对设备的支持
[root@WEB188linux-2.6.33]#viarch/arm/mach-s3c2440/mach-smdk2440.c
将smdk2440_devices增加一行&s3c_device_rtc,。最终效果如下:
staticstruct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,//新增的一行
};
移植UDA1341驱动
[root@WEB188linux-2.6.33]# vi arch/arm/mach-s3c2440/mach-smdk2440.c
在开始添加头文件
#include<sound/s3c24xx_uda134x.h>
#include<mach/gpio-fns.h>
并在正文开始区增加:
staticstructs3c24xx_uda134x_platform_datas3c24xx_uda134x_data={
.l3_clk =S3C2410_GPB(4),
.l3_data =S3C2410_GPB(3),
.l3_mode =S3C2410_GPB(2),
.model =UDA134X_UDA1341,
};
staticstruct platform_device s3c24xx_uda134x = {
.name ="s3c24xx_uda134x",
.dev = {
.platform_data = &s3c24xx_uda134x_data,
}
};
将下面代码添加到平台中
staticstruct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,
&s3c24xx_uda134x,//增加这里
};
配置内核
[root@WEB188linux-2.6.33]# make menuconfig
DeviceDrivers --->
<*> Sound cardsupport --->
<*> AdvancedLinux Sound Architecture --->
<*> OSSMixer API
<*> OSS PCM(digital audio) API
[*] OSS PCM(digital audio) API - Include plugin system
[*] Supportold ALSA API
[*] Verboseprocfs contents
[*] Verboseprintk
[*] Genericsound devices --->
<*> ALSAfor SoC audio support --->
<*> SoC Audio for the Samsung S3C24XX chips
<*> SoC I2S Audio support UDA134X wired to a S3C24XX
移植DM9000驱动,修改drivers/net/dm9000.c文件
[root@WEB188linux-2.6.33]# vi drivers/net/dm9000.c
#include<mach/regs-gpio.h>
#include<mach/irqs.h>
#include<mach/hardware.h>
在dm9000_probe函数开始增加(注意是开始处,而不是函数上面):
unsignedchar ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};
static void *bwscon;
static void *gpfcon;
static void *extint0;
static void *intmsk;
#define BWSCON (0x48000000)
#define GPFCON (0x56000050)
#define EXTINT0 (0x56000088)
#define INTMSK (0x4A000008)
bwscon=ioremap_nocache(BWSCON,0x0000004);
gpfcon=ioremap_nocache(GPFCON,0x0000004);
extint0=ioremap_nocache(EXTINT0,0x0000004);
intmsk=ioremap_nocache(INTMSK,0x0000004);
writel(readl(bwscon)|0xc0000,bwscon);
writel( (readl(gpfcon) &~(0x3 << 14)) | (0x2 << 14), gpfcon);
writel( readl(gpfcon) |(0x1 << 7), gpfcon); // Disable pull-up
writel( (readl(extint0)& ~(0xf << 28)) | (0x4 << 28), extint0); //risingedge
writel( (readl(intmsk)) & ~0x80, intmsk);
在这个函数最后修改以下位置
if(!is_valid_ether_addr(ndev->dev_addr)) {
/* try readingfrom mac */
mac_src ="chip";
for (i = 0; i <6; i++)
//ndev->dev_addr[i]= ior(db, i+DM9000_PAR);
ndev->dev_addr[i]=ne_def_eth_mac_addr[i];//修改这里
}
修改arch/arm/mach-s3c2440/mach-smdk2440.c,添加设备
staticstruct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,
&s3c24xx_uda134x,
&s3c_device_dm9000,//此处添加
};
修改文件arch/arm/plat-s3c24xx/devs.c
[root@WEB188linux-2.6.33]# vi arch/arm/plat-s3c24xx/devs.c
添加头文件:
#include<linux/dm9000.h>
以及以下信息:
staticstruct resource s3c_dm9000_resource[] = {
[0] = {
.start =S3C24XX_PA_DM9000,
.end =S3C24XX_PA_DM9000+ 0x3,
.flags = IORESOURCE_MEM
},
[1]={
.start =S3C24XX_PA_DM9000 + 0x4, //CMD pin is A2
.end = S3C24XX_PA_DM9000+ 0x4 + 0x7c,
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ
},
};
static structdm9000_plat_data s3c_device_dm9000_platdata = {
.flags=DM9000_PLATF_16BITONLY,
};
struct platform_devices3c_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);
修改arch/arm/plat-s3c/include/plat/devs.h 45行附近,添加
[root@WEB188linux-2.6.33]# vi arch/arm/plat-s3c/include/plat/devs.h
externstruct platform_device s3c_device_dm9000;
修改arch/arm/mach-s3c2410/include/mach/map.h
[root@WEB188linux-2.6.33]# vi arch/arm/mach-s3c2410/include/mach/map.h
新增
/*DM9000 */
#define S3C24XX_PA_DM9000 0x20000300
#define S3C24XX_VA_DM9000 0xE0000000
(如果无法发现网卡,请进行操作:)修改arch/arm/mach-s3c2410/mach-smdk2410.c在smdk2410_devices增加以下行
&s3c_device_dm9000,
另外在staticstructmap_descsmdk2410_iodesc[]__initdata增加以下内容
[0]= {
.virtual = (unsigned long)S3C24XX_VA_DM9000,
.pfn = __phys_to_pfn(S3C24XX_PA_DM9000),
.length = SZ_1M,
.type = MT_DEVICE,
},
移植LCD。打开文件arch/arm/mach-s3c2410/mach-smdk2410.c
[root@WEB188linux-2.6.33]# vi arch/arm/mach-s3c2410/mach-smdk2410.c
在以下两个结构体中staticstruct s3c2410fb_display smdk2440_lcd_cfg[] __initdata,staticstruct s3c2410fb_mach_info smdk2440_fb_info __initdata,改成如下代码
staticstruct s3c2410fb_display smdk2440_lcd_cfg[] __initdata = {
{
/*Config for 320x240 LCD */
.lcdcon5= S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE|
S3C2410_LCDCON5_INVVFRAME|
S3C2410_LCDCON5_PWREN|
S3C2410_LCDCON5_HWSWP,
.type = S3C2410_LCDCON1_TFT,
.width = 320,
.height = 240,
.pixclock = 270000,
.xres = 320,
.yres = 240,
.bpp = 16,
.left_margin = 8,
.right_margin = 5,
.hsync_len = 63,
.upper_margin = 15,
.lower_margin = 3,
.vsync_len = 5,
},
};
staticstruct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
.displays =smdk2440_lcd_cfg,
.num_displays =ARRAY_SIZE(smdk2440_lcd_cfg),
.default_display = 0,
.lpcsel = 0,
};
移植内核是会出现的问题:
1、Freeinginit memory: 168K
Kernelpanic - not syncing: Attempted to kill init!
,解决
原来问题在这里
Kernel Features --->
[*]UsetheARMEABItocompilethekernel
[*] Allowold ABI binaries to run with this kernel (EXPERIMENTA)
出现这个问题与编译器有关,3.4.1的编译器选择这个会出错的,而4.3.2选择这个不会出错的,而且4.3.2不选择这个,内核是没有办法启动的。
2、LoadKernel...
UncompressingLinux... done, booting the kernel.
这个问题是用4.3.2才会出现的,估计是串口驱动没有设置好,小弟现在都没有解决,所以暂时还是用3.4.1的编译器
以上是我编译内核是出现过的问题,如果有错的地方,希望大家指出,谢谢。