TQ2440成功移植linux-2.6.29…

来源:互联网 发布:淘宝9块9包邮 编辑:程序博客网 时间:2024/06/03 13:34
原文地址:TQ2440成功移植linux-2.6.29内核作者:wyd2011

一.修改平台输入时钟和机器码

   修改内核源码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 ConfigurationFile”回车,输入arch/arm/configs/s3c2410_defconfig,点OK

然后返回到配置界面,进入到“SystemType”选项下的配置单:

 
[转载]TQ2440成功移植linux-2.6.29内核

然后配置各个平台如下所示

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)
   []HighMemorySupport(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支持的配置选项,输入:#makemenuconfig ARCH=armCROSS_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:abn");
    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"
                "setusingifconfign",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=%dn",__FUNCTION__,var->xres);
   dprintk("%s:var->yres=%dn",__FUNCTION__,var->yres);
   dprintk("%s:var->bpp =%dn",__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;

    unsignedpixclock;         
    unsignedsetclkval;        
    unsigned shortleft_margin;
    unsigned shortright_margin;
    unsignedshorthsync_len;         
    unsigned shortupper_margin;
    unsigned shortlower_margin;
    unsignedshortvsync_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=armCROSS_COMPILE=arm-linux-:

Device Drivers--->

   Graphics support --->

       <*>Support for frame buffer devices--->

              <*>S3C2410 LCD frame buffersupport

保存后编译内核,烧入开发版运行。(注:启动后开发板的LCD为黑屏)

 

六.开机LOGO制作

   找一张480x272的图片,然后用GIMP软件将其打开,右键单击图片弹出菜单选择Image->mode->Indexed 将Maximum numberof colors改为224.右击图片选择File->saveas写完名称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=armCROSS_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 SoundSystem (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 menuconfigARCH=armCROSS_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

来测试驱动。

出错

进入内核源码目录

viarch/arm/include/asm/elf.h

修改

   #define R_ARM_ABS32 2
    #defineR_ARM_CALL 28
    #defineR_ARM_JUMP24 29
    #defineR_ARM_V4BX 40

viarch/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: %un",
          module->name,ELF32_R_TYPE(rel->r_info));

 

注:参考《天嵌科技出品-Linux移植之Step ByStep_V4.5_20100605》,转载请注明出处!