http://blog.sina.com.cn/s/blog_8f9cdbbd01016rgn.html
一.修改平台输入时钟和机器码
修改内核源码arch/arm/mach-s3c2440/mach-smdk2440.c” 文件的大概162行或163行,把16.9344MHz改为12MHz,因为TQ2440使用的就是12MHz的外部时钟源输入,即把16934400改为12000000。
在TQ2440使用的uboot中设定了机器码为168,所以内核这里需要修改机器码,否则会
出现不能启动的情况。机器码保存在内核源码的“arch/arm/tools/mach-types”文件中,在大概379行,把
原来的362改为168保存即可。
二.利用默认配置单做配置单
#make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-
在“Load an Alternate Configuration File”回车,输入arch/arm/configs/s3c2410_defconfig,点OK
然后返回到配置界面,进入到“SystemType”选项下的配置单:
![TQ2440成功移植linux-2.6.29内核 TQ2440成功移植linux-2.6.29内核](https://i-blog.csdnimg.cn/blog_migrate/e09a68ed77214d95b49c167346297bcd.jpeg)
然后配置各个平台如下所示
SystemType --->
S3C2410Machines --->
[*]SMDK2410/A9M2410
[]IPAQH1940
[]AcerN30
[]SimtecElectronicsBAST(EB2410ITX)
[]NexVisionOTOMBoard
[]AMLM5900Series
[]ThorcomVR1000
[]QT2410
S3C2412Machines --->
[]SMDK2413
[]SMDK2412
[]VMSTMS
S3C2440Machines --->
[]SimtecElectronicsANUBIS
[]SimtecIM2440D20(OSIRIS) module
[]HPiPAQrx3715 [*]SMDK2440
[]NexVisionNEXCODER2440LightBoard
[*]SMDK2440withS3C2440CPUmodule
S3C2442Machines --->
[]SMDM2440withS3C2442CPUmodule
S3C2443Machines --->
[]SMDK2443
配置完毕这个地方后,退回到最初的配置单。
在配置单中添加自己的信息
然后配置选项,配置如下
(Generalsetup --->
[*]Promptfordevelopmentand/orincompletecode/drivers
(-EmbedSky)Localversion-appendtokernelrelease
[*]SystemVIPC
(17)Kernellogbuffersize(16=>64KB,17=>128KB)
-*-Namespacessupport
ChooseSLABallocator(SLUB(UnqueuedAllocator)) --->
选择是否支持EEAABBII
然后对是否支持EABI进行选择,配置如下:
KernelFeatures --->
Memorysplit(3G/1Guser/kernelsplit) --->
[]PreemptibleKernel(EXPERIMENTAL)
[*]UsetheARMEABItocompilethekernel
[*] AllowoldABIbinariestorunwiththiskernel(EXPERIMENTAL)
[]HighMemory Support(EXPERIMENTAL)
Memorymodel(FlatMemory) --->
[]AddLRUlisttotracknon-evictablepages
(4096)Lowaddressspacetoprotectfromuserallocation
说明:如果您使用的4.3.3的编译器(也就是支出EABI 的编译器),
那么就选中它;如果您使用3.4.5或以下的编译器,那么就不要选中它。
然后保存自己的配置单为.config
三.Nand Flash 驱动移植
修改内核源码“arch/arm/plat-s3c24xx/common-smdk.c”文件,在109 行左右,有一个结构体名为:
smdk_default_nand_part[],将其修改为如下列表所示:
staticstructmtd_partitionsmdk_default_nand_part[]={
[0]={
.name ="EmbedSky_Board_uboot",
.offset =0x00000000,
.size =0x00040000,
},
[1]={
.name ="EmbedSky_Board_kernel",
.offset =0x00200000,
.size =0x00300000,
},
[2]={
.name ="EmbedSky_Board_yaffs2",
.offset =0x00500000,
.size =MTDPART_SIZ_FULL
}
};
然后修改NandFlash 的读写匹配时间,修改common-smdk.c 文件的刚刚修改后的大概140行左右的
smdk_nand_info结构体,修改内容如下:(这个步骤可以不用做)
staticstructs3c2410_platform_nandsmdk_nand_info={
.tacls =10,
.twrph0 =25,
.twrph1 =10,
.nr_sets =ARRAY_SIZE(smdk_nand_sets),
.sets =smdk_nand_sets,
};
然后修改“drivers/mtd/nand/s3c2410.c”文件的752行,将原来的内容改为如下所示:
chip->ecc.mode =NAND_ECC_NONE; //NAND_ECC_SOFT;
然后需要在刚刚完成的配置单中添加上对NandFlash支持的配置选项,输入:#make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-,进入配置单选项,然后配置如下所示:
DeviceDrivers --->
<*>MemoryTechnologyDevice(MTD)support --->
[*] MTDpartitioningsupport
<> RedBootpartitiontableparsing
[] Commandlinepartitiontableparsing
<*> DirectchardeviceaccesstoMTDdevices
-*- CommoninterfacetoblocklayerforMTD'translationlayers
<*> CachingblockdeviceaccesstoMTDdevices
<*> NANDDeviceSupport --->
<*> NANDFlashsupportforS3C2410/S3C2440SoC
[] S3C2410NANDHardwareECC
配置完毕这些之后,保存配置单。
注:现在已经可以编译内核下载到板子里了,但是还不支持网卡,TQ2440上的网卡是dm9000.
四.dm9000网卡驱动移植
修改内核源码的“arch/arm/mach-s3c2440/mach-smdk2440.c”文件:
在50行添加头文件内容如下;
#include<linux/dm9000.h>
在154行添加如下内容所示:
staticstructs3c2410fb_mach_infotq2440_fb_info__initdata={
.displays =&tq2440_lcd_cfg,
.num_displays=1,
.default_display=0,
#if0
.gpccon =0xaa940659,
.gpccon_mask=0xffffffff,
.gpcup =0x0000ffff,
.gpcup_mask =0xffffffff,
.gpdcon =0xaa84aaa0,
.gpdcon_mask=0xffffffff,
.gpdup =0x0000faff,
.gpdup_mask =0xffffffff,
#endif
// .lpcsel =((0xCE6)&~7)|1<<4,
};
staticstructresources3c_dm9k_resource[]={
[0]={
.start=S3C2410_CS4,
.end =S3C2410_CS4+3,
.flags =IORESOURCE_MEM,
},
[1]={
.start=S3C2410_CS4+4,
.end =S3C2410_CS4+4+3,
.flags =IORESOURCE_MEM,
},
[2]={
.start=IRQ_EINT7,
.end =IRQ_EINT7,
.flags =IORESOURCE_IRQ|IRQF_TRIGGER_RISING,
}
};
staticstructdm9000_plat_datas3c_dm9k_platdata={
.flags =DM9000_PLATF_16BITONLY,
};
structplatform_devices3c_device_dm9000={
.name ="dm9000",
.id =0,
.num_resources =ARRAY_SIZE(s3c_dm9k_resource),
.resource =s3c_dm9k_resource,
.dev ={
.platform_data=&s3c_dm9k_platdata,
}
};
在191行添加如下内容所示:
staticstructplatform_device*smdk2440_devices[]__initdata={
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_dm9000,
};
在“drivers/net/dm9000.c”文件中修改如下:
在41行添加的头文件内容如下:
#ifdefined(CONFIG_ARCH_S3C2410)
#include<mach/regs-mem.h>
#endif
在1194行添加内容如下所示:
int i;
u32 id_val;
#ifdefined(CONFIG_ARCH_S3C2410)
unsignedintoldval_bwscon=*(volatileunsignedint*)S3C2410_BWSCON;
unsignedintoldval_bankcon4=*(volatileunsignedint*)S3C2410_BANKCON4;
#endif
在1209行添加如下内容:
dev_dbg(&pdev ->dev,"dm9000_probe()\n");
#ifdefined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16)) |
S3C2410_BWSCON_DW4_16|S3C2410_BWSCON_WS4|S3C2410_BWSCON_ST4;
*((volatileunsignedint*)S3C2410_BANKCON4)=0x1f7c;
#endif
修改1377行的内容如下所示:(主要是添加mac值)
#ifdefined(CONFIG_ARCH_S3C2410)
printk("NowusethedefaultMACaddress:10:23:45:67:89:ab\n");
mac_src="EmbedSky";
ndev->dev_addr[0]=0x10;
ndev->dev_addr[1]=0x23;
ndev->dev_addr[2]=0x45;
ndev->dev_addr[3]=0x67;
ndev->dev_addr[4]=0x89;
ndev->dev_addr[5]=0xab;
#else
mac_src="eeprom";
for(i=0;i<6;i+=2)
dm9000_read_eeprom(db,i/2,ndev->dev_addr+i);
if(!is_valid_ether_addr(ndev->dev_addr)&&pdata!=NULL){
mac_src="platformdata";
memcpy(ndev->dev_addr,pdata->dev_addr,6);
}
if(!is_valid_ether_addr(ndev->dev_addr)){
mac_src="chip";
for(i=0;i<6;i++)
ndev->dev_addr[i]=ior(db,i+DM9000_PAR);
}
if(!is_valid_ether_addr(ndev->dev_addr))
dev_warn(db->dev,"%s:InvalidethernetMACaddress.Please"
"setusingifconfig\n",ndev->name);
#endif
在1423行添加如下内容:
out:
#ifdefined(CONFIG_ARCH_S3C2410)
*(volatileunsignedint*)S3C2410_BWSCON =oldval_bwscon;
*(volatileunsignedint*)S3C2410_BANKCON4=oldval_bankcon4;
#endif
修改完以上的内容之后,进入配置单,然后添加上对DM9000网卡的配置:
[*]Networkingsupport --->
---Networkingsupport
Networkingoptions --->
<>Packetsocket
<*>Unixdomainsockets
<>PF_KEYsockets
[*]TCP/IPnetworking
[] IP:multicasting
[] IP:advancedrouter
[*] IP:kernellevelautoconfiguration
[*] IP:DHCPsupport
[] IP:BOOTPsupport
[] IP:RARPsupport
DeviceDrivers --->
[*]Networkdevicesupport --->
[*] Ethernet(10or100Mbit) --->
-*- GenericMediaIndependentInterfacedevicesupport
<*> DM9000support
(4) DM9000maximumdebuglevel
配置好后,保存配置单。
如果想要测试一下,编译内核,烧入开发版运行
#make uImage ARCH=arm CROSS_COMPILE=arm-linux-
编译完成后uImage在arch/arm/boot/里。
五.LCD(W43)驱动移植
修改drivers/video/s3c210fb.c的371行:
staticvoids3c2410fb_activate_var(structfb_info*info)
{
structs3c2410fb_info*fbi=info->par;
void__iomem*regs=fbi->io;
inttype=fbi->regs.lcdcon1&S3C2410_LCDCON1_TFT;
structfb_var_screeninfo*var=&info->var;
structs3c2410fb_mach_info*mach_info=fbi->dev->platform_data;
structs3c2410fb_display*default_display=mach_info->displays+
mach_info->default_display;
intclkdiv=s3c2410fb_calc_pixclk(fbi,var->pixclock)/2;
dprintk("%s:var->xres =%d\n",__FUNCTION__,var->xres);
dprintk("%s:var->yres =%d\n",__FUNCTION__,var->yres);
dprintk("%s:var->bpp =%d\n",__FUNCTION__,var->bits_per_pixel);
if(type==S3C2410_LCDCON1_TFT){
s3c2410fb_calculate_tft_lcd_regs(info,&fbi->regs);
--clkdiv;
if(clkdiv<0)
clkdiv=0;
}else{
s3c2410fb_calculate_stn_lcd_regs(info,&fbi->regs);
if(clkdiv<2)
clkdiv=2;
}
然后修改第393行:
// fbi->regs.lcdcon1|= S3C2410_LCDCON1_CLKVAL(clkdiv);
fbi->regs.lcdcon1|= S3C2410_LCDCON1_CLKVAL(default_display->setclkval);
下面在structs3c2410fb_display结构体中加入setclkval变量,修改arch/arm/mach-s3c2410/include/mach/fb.h文件(40行添加):
structs3c2410fb_display{
unsigned type;
unsigned shortwidth;
unsigned shortheight;
unsigned shortxres;
unsigned shortyres;
unsigned shortbpp;
unsigned pixclock;
unsigned setclkval;
unsigned shortleft_margin;
unsigned shortright_margin;
unsigned shorthsync_len;
unsigned shortupper_margin;
unsigned shortlower_margin;
unsigned shortvsync_len;
unsignedlong lcdcon5;
};
然后修改LCD各个参数的配置,该配置参数在“arch/arm/mach-s3c2440/mach-smdk2440.c”文件中的
由107行开始的结构体中:
staticstructs3c2410fb_displaysmdk2440_lcd_cfg__initdata={
.lcdcon5 =S3C2410_LCDCON5_FRM565|
S3C2410_LCDCON5_INVVLINE|
S3C2410_LCDCON5_INVVFRAME|
S3C2410_LCDCON5_PWREN|
S3C2410_LCDCON5_HWSWP,
.type =S3C2410_LCDCON1_TFT,
.width =480,
.height =272,
.pixclock =40000,
.setclkval =0x4,
.xres =480,
.yres =272,
.bpp =16,
.left_margin =19,
.right_margin =10,
.hsync_len =30,
.upper_margin=4,
.lower_margin=2,
.vsync_len =8,
};
staticstructs3c2410fb_mach_infosmdk2440_fb_info__initdata={
.displays =&smdk2440_lcd_cfg,
.num_displays=1,
.default_display=0,
#if0
.gpccon =0xaa940659,
.gpccon_mask=0xffffffff,
.gpcup =0x0000ffff,
.gpcup_mask =0xffffffff,
.gpdcon =0xaa84aaa0,
.gpdcon_mask=0xffffffff,
.gpdup =0x0000faff,
.gpdup_mask =0xffffffff,
#endif
// .lpcsel =((0xCE6)&~7)|1<<4,
然后配置内核#make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-:
Device Drivers --->
Graphics support --->
<*>Support for frame buffer devices --->
<*>S3C2410 LCD frame buffer support
保存后编译内核,烧入开发版运行。(注:启动后开发板的LCD为黑屏)
六.开机LOGO制作
找一张480x272的图片,然后用GIMP软件将其打开,右键单击图片弹出菜单选择 Image->mode->Indexed 将Maximum number of colors改为224.右击图片选择File->save as写完名称logo_linux_clut224.ppm后save,会弹出对话框,选择Ascii,然后save。这样ppm图像就做好了。
将做好的logo_linux_clut224.ppm图像复制到drivers/video/logo中,然后删除掉logo_linux_clut224.c和logo_linux_clut224.o
做好上面步骤以后配置内核#make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-:
Device Drivers --->
Graphics support --->
[*]Bootup logo --->
[*]Standart 224-color linux logo
保存后编译内核,烧入开发版运行。(启动开发板后你就能看到你的新logo图片了)
七.声卡驱动的移植
修改arch/arm/mach/mach-s3c2440/mach-smdk2440.c文件
添加头文件
#include<sound/s3c24xx_uda134x.h>
然后添加以下部分:
staticstructs3c24xx_uda134x_platform_datas3c24xx_uda134x_data={
.l3_clk=S3C2410_GPB4,
.l3_data=S3C2410_GPB3,
.l3_mode=S3C2410_GPB2,
.model=UDA134X_UDA1341,
};
staticstructplatform_devices3c_device_uda134x={
.name="s3c24xx_uda134x",
.dev={
.platform_data =&s3c24xx_uda134x_data,
}
};
staticstructplatform_device*smdk2440_devices[]__initdata={
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,
&s3c_device_uda134x,
};
然后配置内核:#make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-:
DeviceDrivers --->
<*>Soundcardsupport --->
---Soundcardsupport
<*> AdvancedLinuxSoundArchitecture --->
---AdvancedLinuxSoundArchitecture
<*> OSSMixerAPI
<*> OSSPCM(digitalaudio)API
[*] Verboseprocfscontents
<*> ALSAforSoCaudiosupport --->
---ALSAforSoCaudiosupport
<*> SoCAudiofortheSamsungS3CXXXXchips
<*> SoCI2SAudiosupportUDA134Xwiredt
<*> Open Sound System (DEPRECATED) --->
保存后编译内核,烧入开发版运行。可以copy一个MP3文件到NFS文件系统中,然后用
#cat xxx.mp3 > /dev/dsp
如果听到哗哗啦啦的声音,就说明移植成功了!
八.SD卡驱动移植在
Linux-2.6.29的内核中只需要添加SD设备到设备初始化列表中,修改内核源码的“arch/arm/plat-
s3c24xx/common-smdk.c”文件
staticstructplatform_device__initdata*smdk_devs[]={
&s3c_device_nand,
&s3c_device_sdi,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
};
修改Linux-2.6.29内核源码的“drivers/mmc/host/s3cmci.c”文件,添加和开发板相关的SD卡中断处
理,在1335行添加如下内容(即修改s3cmci_probe函数):
host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
host->irq_cd=IRQ_EINT16;
s3c2410_gpio_cfgpin(S3C2410_GPG8,S3C2410_GPG8_EINT16);
然后配置内核:
DeviceDrivers --->
<*>MMC/SD/SDIOcardsupport --->
---MMC/SD/SDIOcardsupport
***MMC/SD/SDIOCardDrivers***
<*> MMCblockdevicedriver
[*] Usebouncebufferforsimplehosts
***MMC/SD/SDIOHostControllerDrivers***
<*> SamsungS3CSD/MMCCardInterfacesupport
保存后编译内核,烧入开发版运行。
九.RTC驱动移植
在2.6.29上的实时时钟驱动是非常完善,这里只需要添加到RTC设备到设备初始化列表中就行了。
修改内核源码“arch/arm/mach-s3c2440/mach-smdk2440.c”文件,在行添加如下内容:staticstructplatform_device*smdk2440_devices[]__initdata={
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_rtc,
};
然后配置如下所示:
DeviceDrivers --->
<*>RealTimeClock --->
[*] SetsystemtimefromRTConstartupandresume
(rtc0) RTCusedtosetthesystemtime
[*] /sys/class/rtc/rtcN(sysfs)
[*] /proc/driver/rtc(procfsforrtc0)
[*] /dev/rtcN(characterdevices)
<*> SamsungS3CseriesSoCRTC
配置完毕后,编译内核烧写到开发板中,然后使用busybox自带的hwclock和date命令可以设置RTC,
$date -s 月日时分年 //其中月、日、时和分都是两位数,年是四位数。
//比如:020416102009就是2009年2月4日16点10分
$hwclock -w //保存刚刚设置的时钟。
设置好之后关闭电源,实时时钟依然会工作。为了让系统启动时能够同步设置好的RTC,需要在
文件系统的“/etc/init.d/rcS”文件中添加一条RTC同步的命令,启动后,系统就会自动同步RTC了。
下面是新的rcS文件的内容:
#! /bin/sh
/bin/mount -a
/bin/mount -t tmpfs mdev /dev
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
hwclock -s
十.USB驱动移植
其实2.6.29内核已经有完善的USB设备驱动,我们只需配置一下:
输入:#make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-,然后进入配置单,配置如下:
DeviceDrivers --->
SCSIdevicesupport --->
<*>SCSIdevicesupport
[*]legacy/proc/scsi/support
<*>SCSIdisksupport
<*>SCSICDROMsupport
[*]HIDDevices --->
<*> USBHumanInterfaceDevice(fullHID)support
[*] /dev/hiddevrawHIDdevicesupport
[*]USBsupport --->
<*> SupportforHost-sideUSB
[*] USBdevicefilesystem
[*] USBdeviceclass-devices(DEPRECATED)
<*> OHCIHCDsupport
<*> USBMassStoragesupport
然后编译内核,烧入开发板。输入命令:
#mount /dev/sda1 /mnt/udisk
#ls /mnt/udisk
来测试驱动。
出错
进入内核源码目录
vi arch/arm/include/asm/elf.h
修改
#define R_ARM_ABS32 2
#define R_ARM_CALL 28
#define R_ARM_JUMP24 29
#define R_ARM_V4BX 40
vi arch/arm/kernel/module.c
在apply_relocate函数中增加如下语句:
*(u32 *)loc |= offset & 0x00ffffff;
break;
+ case R_ARM_V4BX:
+
+ *(u32 *)loc &= 0xf000000f;
+ *(u32 *)loc |= 0x01a0f000;
+ break;
+
default:
printk(KERN_ERR "%s: unknown relocation: %u\n",
module->name, ELF32_R_TYPE(rel->r_info));
注:参考《天嵌科技出品-Linux移植之Step By Step_V4.5_20100605》,转载请注明出处!