天天看點

TQ2440成功移植linux-2.6.29核心

一.修改平台輸入時鐘和機器碼

    修改核心源碼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核心

然後配置各個平台如下所示

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));