arm-linux-gcc-4.4.1+Linux-2.6.31.6+busybox-1.15.1在TQ2440的移植

来源:互联网 发布:下载录制屏幕软件 编辑:程序博客网 时间:2024/06/13 04:08

 

源文来自http://bbs.embedsky.net/viewthread.php?tid=1690&extra=page%3D1&page=1

针对最新的交叉编译环境和最新的Linux内核以及最新的busybox,我用最新的交叉编译器arm-linux-gcc-4.4.1编译且移植linux-2.6.31.6和busybox-1.15.1到TQ2440开发板上。使用的u-boot是天嵌光盘中带的u-boot-1.1.6,但是我把其中的s3c2440的机器码修改为默认值,即:362,这样就不用修改Linux内核中的s3c2440的机器码了。下面是具体的移植步骤(今天我只移植了NAND、RTC、SD卡和DM9000,明天接着移植其他部分):

移植Linux-2.6.31.6到2440
1。从www.kernel.org下载目前Linux最新源代码包,linux-2.6.31.6.tar.bz2
2。解压缩linux-2.6.31.6.tar.bz2到指定的目录下,如:kernel/目录下;
3。进入kernel目录(#cd kernel);
4。修改系统时钟。Linux内核默认系统时钟为16MHz,我的板子使用的时钟是12MHz的,因此需要调整系统时钟参数。打开文件arch/arm/mach-s3c2440/mach-smdk2440.c,修改smdk2440_map_io()函数中的s3c24xx_init_clocks()中的参数为12000000;
5。添加NAND分区表到内核。
        1)#vim arch/arm/plat-s3c24xx/common-smdk.c;
        2)修改结构smdk_default_nand_part,添加自己的分区表信息。如下是我的分区表:
        static struct mtd_partition smdk_default_nand_part[] = {                                                        
                [0] = {                                                                                                
                        .name   = "bootloader",                                                                        
                        .size   = 0x00040000,                                                                           
                        .offset = 0x0,                                                                                 
                },                                                                                                      
                [1] = {                                                                                                
                        .name   = "kernel",                                                                             
                        .size   = 0x00200000,                                                                           
                        .offset = 0x00200000,                                                                           
                },                                                                                                      
                [2] = {                                                                                                
                        .name   = "yaffs2",                                                                             
                        .size   = 0x0FB80000,                                                                           
                        .offset = 0x00400000,                                                                           
                }                                                                                                      
        }
        3)在内核配置选项中,选择Device Drivers->MTD support->NAND DeviceSupport->NAND Flash support for Samsung S3C SoCs和Samsung S3C NANDHardware ECC;同时需要在MTD support中选择MTD partitioning support(支持分区)、Commandline partition table parsing、Direct char device access to MTDdevices和Caching block device access to MTD devices。MTDsupport选择项中只需要选择这些就可以了,别的都可以去掉。
6。添加yaffs2文件系统到内核。
        1)从http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/网站上下载最新的yaffs源代码包;
        2)解开yaffs源码包后,有两个目录分别为yaffs和yaffs2。之后进入yaffs2,执行如下命令:#patch-ker.sh c <path_of_kernel>
        3)在内核配置选项中,选择File Systems->Miscellaneous filesystems->YAFFS2 file system support
7。修改串口名称(该步骤可以省略,前提是你的根文件系统中/etc/inittab文件中的串口名称与内核中的串口名称一致)。由于我的根文件系统中/etc/inittab中的串口名称为s3c2440_serial0,因此需要修改内核中的串口名称。
        1)#vim drivers/serial/samsung.c
        2)修改该文件中s3c24xx_uart_drv变量的dev_name成员为s3c2440_serial即可
8。RTC驱动移植。2.6.31.5内核已经完全实现了RTC驱动。因此不需要修改任何代码,只需要在系统开机时能加载RTC驱动即可。
        1) 编辑arch/arm/mach-s3c2440/mach-smdk2440.c文件中的smdk2440_devices数组,添加s3c_device_rtc;
        2) 在内核配置选项中,选择Device Drivers->Real Time Clock选项中的Set systemtime from RTC on startup and resume、/sys/class/rtc/rtcN(sysfs)、/proc/driver/rtc (procfs for rtc0)、/dev/rtcN (characterdevices)和Samsung S3C series SoC RTC。其中Samsung S3C series SoCRTC为必选项,/sys/class/rtc/rtcN (sysfs)、/proc/driver/rtc (procfs forrtc0)、/dev/rtcN (character devices)为可选项,根据个人的需要进行选择;

9。DM9000网卡驱动的移植。2.6.31.5中自带的dm9000.c可以满足TQ2440开发板上的DM9000网卡的要求,因此可以以2.6.31.5自带的dm9000为基础进行移植。下面是具体的移植步骤:
        1) 添加网卡驱动的平台数据信息,包括:网卡的资源(地址资源、数据资源以及中断号等)、数据位数、网卡名称等。编辑文件arch/arm/plat-s3c24xx/devs.c,具体添加内容如下:
        #include <linux/dm9000.h>        //在引用头文件处添加dm9000.h头文件,该文件包含S3C2410_CS4等定义
        /* DM9000 */                                                                                                   
        static struct resource s3c_dm9000_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,                                                                       
                }                                                                                                      
        };                                                                                                              
        static struct dm9000_plat_data dm9k_plat_data = {                                                               
                .flags  = DM9000_PLATF_16BITONLY,                                                                       
        };                                                                                                              
                                                                                                               
        struct platform_device s3c_device_dm9k = {                                                                     
                .name           = "dm9000",               //这里的name一定要和drivers/net/dm9000.c中的dm9000_driver.driver.name一致,否则系统会找不到网卡驱动
                .id             = -1,                                                                                   
                .num_resources  = ARRAY_SIZE(s3c_dm9000_resource),                                                      
                .resource       = s3c_dm9000_resource,                                                                  
                .dev            = {                                                                                    
                        .platform_data  = &dm9k_plat_data,                                                              
                }                                                                                                      
        };                                                                                                              
        EXPORT_SYMBOL(s3c_device_dm9k);         
        2) 导出s3c_device_dm9k变量。编辑arch/arm/plat-s3c/include/plat/devs.h文件,具体添加内容如下:
        extern struct platform_device s3c_device_dm9k;
        3) 添加s3c_device_dm9k到平台设备数组。编辑arch/arm/mach-s3c2440/mach-smdk2440.c文件,具体添加内容如下:
        static struct platform_device *smdk2440_devices[] __initdata = {
                &s3c_device_usb,
                &s3c_device_lcd,
                &s3c_device_wdt,
                &s3c_device_i2c0,
                &s3c_device_iis,
                &s3c_device_rtc,
                &s3c_device_dm9k,        //添加dm9000到平台设备数组       
        }       
       4)修改dm9000.c文件。由于在common-smdk.c中设置了dm9000使用的系统资源是CS4,因此需要根据dm9000的芯片手册来设置BWSCON和BANKCON4寄存器。另外由于dm9000网卡中断信号为上升沿,因此需要在网卡注册中断前设置中断信号为上升沿有效。具体修改内容如下:
        /*添加处理s3c2440寄存器头文件*/
        #if defined(CONFIG_ARCH_S3C2410)
        #include <mach/regs-mem.h>       
        #endif

        dm9000_open()函数中添加对中断类型的处理
#ifdef CONFIG_ARCH_S3C2410
        irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING;
#else
        if (irqflags == IRQF_TRIGGER_NONE)
                dev_warn(db->dev, "WARNING: no IRQ resource flags set./n");
        irqflags |= IRQF_SHARED;
#endif

        dm9000_probe()函数中添加对BWSCON和BANKCON4寄存器的处理,具体的数值请查阅s3c2440A芯片手册
#if defined(CONFIG_ARCH_S3C2410)
        unsigned int oldval_bwscon;
        unsigned int oldval_bankcon4;
#endif
        /* Init network device */
        ndev = alloc_etherdev(sizeof(struct board_info));

        SET_NETDEV_DEV(ndev, &pdev->dev);
        /*保存旧的bwscon和bankcon4的值,之后设置新值*/
#if defined(CONFIG_ARCH_S3C2410)
        oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
        *((volatile unsigned int*)S3C2410_BWSCON)=(oldval_bwscon&~(3<<16)) |S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;//16bits data && WAIT enable && Using UB/LB
        oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4);
        *((volatile  unsigned int *)S3C2410_BANKCON4) = 0x1f7c; //config time seq
#endif
        dev_dbg(&pdev->dev, "dm9000_probe()/n");

        /*退出时恢复bwscon和bankcon4的原始值*/
out:
        dev_err(db->dev, "not found (%d)./n", ret);
#if defined(CONFIG_ARCH_S3C2410)
        *((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
        *((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif
        dm9000_release_board(pdev, db);
        free_netdev(ndev);
注:由于s3c2440不能很好的从eeprom中读取网卡的MAC地址,因此需要在probe函数中手动设置网卡的MAC地址,即:在设置网卡MAC地址出屏蔽掉原来代码,手动添加自己的MAC
#ifdef CONFIG_ARCH_S3C2410
        mac_src = "handy";
        ndev->dev_addr[0] = 0x01;
        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";

        /* try reading the node address from the attached 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 = "platform data";
                memcpy(ndev->dev_addr, pdata->dev_addr, 6);
        }

        if (!is_valid_ether_addr(ndev->dev_addr)) {
                /* try reading from mac */

                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: Invalid ethernet MAC address. Please "
                         "set using ifconfig/n", ndev->name);
#endif
10。SD卡移植。2.6.31.5内核对SD卡的支持已经很好了,因此只需要简单的修改以及配置必要的内核选项即可。
        1)修改mmc驱动。drivers/mmc/host/s3cmci.c文件的s3cmci_probe()函数中需要修改CardDetect中断号,根据开发板的设置此中断号为EINT16,对应s3c2440为GPG8引脚。具体添加内容如下:
        //host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);                 
        //添加irq_cd的中断号为IRQ_EINT16且设置GPG8脚为16号中断的输入引脚               
        host->irq_cd = IRQ_EINT16;                                                      
        s3c2410_gpio_cfgpin(S3C2410_GPG(8),S3C2410_GPG8_EINT16);   
        2)修改系统初始化硬件设备列表。arch/arm/plat-s3c24xx/common-smdk.c的smdk_devs数组中需要添加s3c_device_sdi设备。使得MMC/SD设备在系统开机时能正确加载。
        3)在内核配置中添加对S3C MMC/SD的支持。

开发板开机串口输出信息如下:
##### EmbedSky BIOS for SKY2440/TQ2440 #####
Press Space key to Download Mode !
Booting Linux ...
Copy linux kernel from 0x00200000 to 0x30008000, size = 0x00200000 ... Copy Kernel to SDRAM done,NOW, Booting Linux......
UncompressingLinux...................................................................................................done, booting the kerne.
Linux version 2.6.31.6 (david@localhost.localdomain) (gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67) ) #9 Wed Nov 25 22:24:23 GMT 2009
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: SMDK2440
ATAG_INITRD is deprecated; please update your bootloader.
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, (c) 2004 Simtec Electronics
S3C244X: core 400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
Kernel command line: noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0
PID hash table entries: 256 (order: 8, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 61620KB available (2836K code, 296K data, 92K init, 0K highmem)
SLUB: Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:85
irq: clearing pending ext status 00080000
irq: clearing subpending status 00000002
Console: colour dummy device 80x30
console [ttySAC0] enabled
Calibrating delay loop... 199.47 BogoMIPS (lpj=498688)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at c4808000, irq 33
DMA channel 1 at c4808040, irq 34
DMA channel 2 at c4808080, irq 35
DMA channel 3 at c48080c0, irq 36
S3C244X: Clock Support, DVS off
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
s3c-i2c s3c2440-i2c: slave address 0x10
s3c-i2c s3c2440-i2c: bus frequency set to 97 KHz
s3c-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (extended precision)
yaffs Nov 25 2009 20:58:21 Installing.
msgmni has been set to 120
io scheduler noop registered
io scheduler deadline registered (default)
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
s3c2440-uart.0: s3c2440_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440
s3c2440-uart.1: s3c2440_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440
s3c2440-uart.2: s3c2440_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440
loop: module loaded
dm9000 Ethernet Driver, V1.31
eth0: dm9000e at c4810000,c4814004 IRQ 51 MAC: 01:23:45:67:89:ab (handy)
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns
s3c24xx-nand s3c2440-nand: NAND hardware ECC
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 1543 at 0x00000c0e0000
Creating 3 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x000000000000-0x000000040000 : "bootloader"
0x000000200000-0x000000400000 : "kernel"
0x000000400000-0x00000ff80000 : "yaffs2"
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver libusual
mice: PS/2 mouse device common for all mice
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling
s3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc0
i2c /dev entries driver
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
mapped channel 0 to 0
s3c2440-sdi s3c2440-sdi: powered down.
s3c2440-sdi s3c2440-sdi: initialisation done.
s3c2440-sdi s3c2440-sdi: running at 0kHz (requested: 0kHz).
Advanced Linux Sound Architecture Driver Version 1.0.20.
s3c2440-sdi s3c2440-sdi: running at 400kHz (requested: 400kHz).
No device for DAI UDA134X
No device for DAI s3c24xx-i2s
ALSA device list:
  No soundcards found.
TCP cubic registered
Initializing XFRM netlink socket
NET: Registered protocol family 17
NET: Registered protocol family 15
s3c2440-sdi s3c2440-sdi: running at 400kHz (requested: 400kHz).
s3c2440-sdi s3c2440-sdi: running at 400kHz (requested: 400kHz).
s3c2440-sdi s3c2440-sdi: powered down.
s3c2410-rtc s3c2410-rtc: setting system clock to 2009-11-25 22:26:42 UTC (1259188002)
end_request: I/O error, dev mtdblock2, sector 256
isofs_fill_super: bread failed, dev=mtdblock2, iso_blknum=64, block=128
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
yaffs: auto selecting yaffs2
block 1512 is bad
yaffs_read_super: isCheckpointed 0
VFS: Mounted root (yaffs filesystem) on device 31:2.
Freeing init memory: 92K
Try to bring eth0 interface up ...
eth0: link down
[root@david /]# eth0: link up, 100Mbps, full-duplex, lpa 0x45E1

[root@david /]#

今天接着移植其他部分,包括:watchdog、UDA134x声卡以及USB设备驱动,其中包括USB Gadget的驱动。具体移植细节如下:
11。watchdog移植。2.6.31.6已经完成了watchdog驱动的开发,因此该部分的移植相对简单。具体移植步骤如下:
        1) 启动watchdog功能。编辑drivers/watchdog/s3c2410_wdt.c文件且修改#defineCONFIG_S3C2410_WATCHDOG_ATBOOT         (1),系统默认为0。watchdog默认超时时间也可以设定,内核默认为15秒;
        2) 内核配置中添加对watchdog的支持Device Drivers->Watchdog Timer Support->S3C2410 Watchdog;
        3) 编写用户态喂狗程序,否则开发板会在启动15秒后自动重启。喂狗程序比较简单,核心就是通过ioctl系统调用向内核写入WDIOC_KEEPALIVE命令来保持watchdog有效;
12。UDA134x声卡移植。2.6.31.6已经完成了UDA134x驱动的开发,因此该部分的移植主要是填写platform_data数据结构。具体移植步骤如下:
        1)填写UDA134x使用的platform_data结构,编辑arm/arch/plat-s3c24xx/devs.c文件,添加如下内容:
        #include <sound/s3c24xx_uda134x.h>
        #include <mach/regs-gpio.h>

        /* UDA134x */
        static struct s3c24xx_uda134x_platform_data uda_platform_data = {
                .l3_clk  = S3C2410_GPB(4),
                .l3_mode = S3C2410_GPB(3),
                .l3_data = S3C2410_GPB(2),
                .model   = UDA134X_UDA1341,
        };
        struct platform_device s3c_device_uda134x = {
                .name   = "s3c24xx_uda134x",
                .dev    = {
                        .platform_data = &uda_platform_data,
                }
        };
        EXPORT_SYMBOL(s3c_device_uda134x);
        2)导出s3c_device_uda134x变量。编辑arch/arm/plat-s3c/include/plat/devs.h文件,添加如下内容:
        extern struct platform_device s3c_device_uda134x;
        3)添加s3c_device_uda134x变量到platform_data数组中,编辑arch/arm/mach-s3c2440/mach-smdk2440.c文件,添加如下内容:
        static struct platform_device *smdk2440_devices[] __initdata = {
        &s3c_device_usb,
        &s3c_device_lcd,
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
        &s3c_device_rtc,
        &s3c_device_sdi,
        &s3c_device_dm9k,
        &s3c_device_uda134x,
        };
        4)内核配置文件中添加对uda134x的支持Device Drivers->Sound cardsupport->Advanced Linux SoundArchitecture->OSS相关部分、procfs相关部分和ALSA for SoC audio support->SoCAudio for the Samsung S3CXXXX chips和SoC I2S Audio support UDA134X wiredto a S3C24XX;
13。USB驱动移植
        1)支持U盘。2.6.31.6内核已经对USB设备进行了很好的支持,不需要修改任何代码,只需要在配置内核的时候注意选择必须的选项即可。除了device driver中USB模块外还需要对SCSI和HID部分进行特殊处理。具体设置如下:
        SCSI:SCSI support、SCSI disk和SCSI CDROM
        HID:full HID和raw HID
        2)USB从设备。2.6.31.6内核已经支持USB从设备,需要在配置内核时选择device driver->USBsupport->USB Gadget support(编译进内核),以及其下的USB片上外设控制器为S3C2410、USBGadget driver和File-backed Storagesupport(这两项编译成模块,需要动态加载)。除了内核配置外,还需要对USBGadget平台设备进行必要的设置。编辑arch/arm/mach-s3c2440/mach-smdk2440.c文件,添加如下内容:
/*添加必要的头文件*/
#include <plat/udc.h>
#include <linux/gpio.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>

/*设置udc回调函数udc_pullup()用于使能/禁止UDC上拉电阻*/
/*udc*/
static void udc_pullup(enum s3c2410_udc_cmd_e cmd)
{
        switch(cmd)
        {
                case S3C2410_UDC_P_ENABLE:
                        s3c2410_gpio_setpin(S3C2410_GPG(12),1);
                        break;
                case S3C2410_UDC_P_DISABLE:
                        s3c2410_gpio_setpin(S3C2410_GPG(12),0);
                        break;
                case S3C2410_UDC_P_RESET:
                        break;
                default:
                        break;
        }
}
static struct s3c2410_udc_mach_info udc_machine = {
        .udc_command    = udc_pullup,
};
static struct platform_device *smdk2440_devices[] __initdata = {
        &s3c_device_usb,
        &s3c_device_lcd,
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
        &s3c_device_usbgadget, /*添加s3c_device_usbgadget(usb gadget设备),即:初始化usb gadget到内核*/
};


static void __init smdk2440_machine_init(void)
{
        s3c24xx_fb_set_platdata(&smdk2440_fb_info);
        s3c_i2c0_set_platdata(NULL);
        /*开机禁止UDC上拉电阻、设置GPG12管脚为输出、完善s3c_device_usbgadget结构*/
        s3c2410_gpio_setpin(S3C2410_GPG(12),0);
        s3c2410_gpio_cfgpin(S3C2410_GPG(12),S3C2410_GPIO_OUTPUT);
        s3c24xx_udc_set_platdata(&udc_machine);

        platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
        smdk_machine_init();
}
今天就先移植这么些吧,明天准备移植LCD驱动。

今天移植TQ2440的LCD驱动部分,具体移植过程如下:
14。LCD驱动移植。2.6.31.6已经包含了s3c2440的frame buffer LCD驱动了,我们要做的就是传递正确的platform_data给内核就可以了。具体移植过程如下:
        1)根据实际的LCD屏的物理尺寸大小,修改platform_data结构中的s3c2410fb_display结构变量。具体内容如下:
        static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {

        .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       = 100000, /* HCLK 60 MHz, divisor 10 */
        .setclkval      = 0x03,        /* 新加入的项,目的是减少计算pixclock的复杂度*/
        .xres           = 320,
        .yres           = 240,
        .bpp            = 16,
        .left_margin    = 33,
        .right_margin   = 22,
        .hsync_len      = 44,
        .upper_margin   = 9,
        .lower_margin   = 3,
        .vsync_len      = 15,
        };
        2)修改s3c2410fb_display结构定义,添加setclkval成员。编辑arch/arm/mach-s3c2410/include/mach/fb.h文件,具体修改内容如下:
        /* LCD description */   
struct s3c2410fb_display {
        /* LCD type */  
        unsigned type;  

        /* Screen size */
        unsigned short width;
        unsigned short height;

        /* Screen info */
        unsigned short xres;
        unsigned short yres;
        unsigned short bpp;

        unsigned pixclock;              /* pixclock in picoseconds */
        unsigned setclkval;             /* set clock value */
        unsigned short left_margin;  /* value in pixels (TFT) or HCLKs (STN) */
        unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
        unsigned short hsync_len;    /* value in pixels (TFT) or HCLKs (STN) */
        unsigned short upper_margin;    /* value in lines (TFT) or 0 (STN) */
        unsigned short lower_margin;    /* value in lines (TFT) or 0 (STN) */
        unsigned short vsync_len;       /* value in lines (TFT) or 0 (STN) */

        /* lcd configuration registers */
        unsigned long   lcdcon5;
        };
        3)修改s3c2410 frame buffer驱动,使得计算pixclock更加简洁。编辑drivers/video/s3c2410fb.c,具体修改内容如下:
        static void s3c2410fb_activate_var(struct fb_info *info)
        {
                ......
                struct s3c2410fb_mach_info *platform_dev = fbi->dev->platform_data;
                struct s3c2410fb_display *default_display = platform_dev->displays+platform_dev->default_display;
                ......
                //fbi->regs.lcdcon1 |=  S3C2410_LCDCON1_CLKVAL(clkdiv);
                fbi->regs.lcdcon1 |=  S3C2410_LCDCON1_CLKVAL(default_display->setclkval);
                ......
        }
        4)LCD驱动内核配置选项如下:Device Drivers->Graphics support->Supportfor frame buffer devices->Enable firmware EDID、Enable Video ModeHandling Helpers和S3C2410 LCD framebuffer support,同时在Graphicssupport选项中还要选择Console display driver support->Framebuffer Consolesupport;
        5)添加开机Logo。具体Logo图片可以自行选择,我用的是Linux内核自带的logo图标,具体路径如下:drivers/video/logo/logo_linux_clut224.ppm。
                A)使用gimp工具修改该logo图标为224色且保存为ascii码形式。之后将修改后的logo图片文件放回到原位置。
                B)内核配置选项如下:Device Drivers->Graphics support->Bootup logo->Standard 224-color Linux logo
        6)添加自己的LCD backlight控制模块。这部分实际上是可以放在s3c2440 LCD驱动里面的,但是我将LCD backlight驱动部分单独作成一个模块进行加载。backlight模块的内核部分如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <mach/regs-gpio.h>

#define DEVICE_NAME "backlight"

static int s3c2440_backlight_ioctl(struct inode *inode,struct file *filp,unsigned cmd,unsigned long args)
{
        switch(cmd) {
                case 0:
                        s3c2410_gpio_setpin(S3C2410_GPG(4),0);
                        printk("<1> %s Turn OFF./n",DEVICE_NAME);
                        break;
                case 1:
                        s3c2410_gpio_setpin(S3C2410_GPG(4),1);
                        printk("<1> %s Turn ON./n",DEVICE_NAME);
                        break;
                default:
                        printk("<1> cmd error./n");
                        break;
        }
        return 0;
}

static struct file_operations f_ops = {
        .owner        = THIS_MODULE,
        .ioctl        = s3c2440_backlight_ioctl,
};

static struct miscdevice misc = {
        .minor        = MISC_DYNAMIC_MINOR,
        .name        = DEVICE_NAME,
        .fops        = &f_ops,
};

static int s3c2440_backlight_init(void)
{
        int ret;
        ret = misc_register(&misc);
        printk("<1> %s registered./n",DEVICE_NAME);
        s3c2410_gpio_cfgpin(S3C2410_GPG(4),(0x01 << 8));
        return ret;
}

static void s3c2440_backlight_exit(void)
{
        misc_deregister(&misc);
}

module_init(s3c2440_backlight_init);
module_exit(s3c2440_backlight_exit);
MODULE_LICENSE("GPL");
        backlight用户态测试程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>

int main(int argc,char **argv)
{
        int fd,on=0;
        if (argc != 2) {
                printf("%s [on|off]/n",argv[0]);
                return -1;
        }
        if ((fd = open("/dev/backlight",O_RDWR)) < 0) {
                printf("open /dev/backlight error./n");
                return -2;
        }
        if (!strncmp(argv[1],"on",2))
                on = 1;
        else if (!strncmp(argv[1],"off",3))
                on = 0;
        else {
                printf("%s [on|off]/n",argv[0]);
                close(fd);
                return -3;
        }
        ioctl(fd,on);
        close(fd);
        return 0;
}

补充的说明一下,SD卡驱动的移植,在修改drivers/mmc/host/s3cmci.c文件中的s3cmci_probe()函数中的CardDetect中断号时可以这样修改:
host->pdata->gpio_detect = S3C2410_GPG(8);
host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);                              
s3c2410_gpio_cfgpin(S3C2410_GPG(8),S3C2410_GPG8_EINT16);                                   
这样修改利用函数s3c2410_gpio_getirq()的返回值获取到CardDetect的中断号,而不是手动设置该中断号为EINT16。根据开发板的具体连线设置s3c24xx_mci_pdata结构中的gpio_detect为指定的GPIO管脚(TQ2440为G8),SD卡驱动程序就是使用这个结构成员获取其中断号的。之后再设置G8为EINT16功能。这样的结构更加清晰。

15。移植tcpdump工具到2440开发板。
        1)从sourceforge.net上下载最新的tcpdump-4.0.0源代码以及libpcap-1.0.0源代码,其中libpcap编译成静态库由tcpdump使用。因此需要首先编译libpcap,之后再编译tcpdump。
        2)编译libpcap-1.0.0:
                A) #tar -zxvf libpcap-1.0.0.tar.gz
                B) #cd libpcap-1.0.0
                C) 修改configure文件,注释掉下面几行代码:(具体原因是进行交叉编译configure时会出现错误,无法完成configure)
#if test -z "$with_pcap" && test "$cross_compiling" = yes; then
#       { { echo "$as_meLINENO: error: pcap type not determined when cross-compiling; use --with-pcap=..." >&5
#echo "$as_me: error: pcap type not determined when cross-compiling; use --with-pcap=..." >&2;}
#   { (exit 1); exit 1; }; }
#fi

#if test $ac_cv_linux_vers = unknown ; then
#       { { echo "$as_meLINENO: error: cannot determine linux version when cross-compiling" >&5
#echo "$as_me: error: cannot determine linux version when cross-compiling" >&2;}
# { (exit 1); exit 1; }; }
#       fi
                D) #./configure --host=arm-linux (指定--host参数为arm-linux,这样在configure完成后的Makefile中CC=arm-linux-gcc)
                E) #./make
                在libpcap-1.0.0目录下就会存在libpcap.a这个静态库;
        3)编译tcpdump-4.0.0:
                A) #tar -zxvf tcpdump-4.0.0.tar.gz
                B) #cd tcpdump-4.0.0
                C) 修改configure文件,注释掉下面几行代码:(具体原因是进行交叉编译configure时会出现错误,无法完成configure)
#       if test $ac_cv_linux_vers = unknown ; then
#               { { echo "$as_meLINENO: error: cannot determine linux version when cross-compiling" >&5
#echo "$as_me: error: cannot determine linux version when cross-compiling" >&2;}
#   { (exit 1); exit 1; }; }
#       fi
                D)修改Makefile文件,去掉INCLS、DEFS中/usr/include以及LDFLAGS(若不去掉会提示/usr/include不是合法的交叉编译头文件路径。或者修改为/usr/local/include和/usr/local/lib也可以)
                E) #make
                在tcpdump-4.0.0目录下就会存在tcpdump这个可执行的二进制文件
        4)下载tcpdump可执行文件到开发板上监听eth0端口,之后在主机上ping开发板,开发板串口部分输出如下:
[root@david /root]# ./tcpdump -i eth0
device eth0 entered promiscuous mode
tcpdump: WARNING: can't create rx ring on packet socket 3: 92-Protocol not available               
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 68 bytes
21:49:10.984128 IP 192.168.1.100 > 192.168.1.6: ICMP echo request, id 59697, seq 1, length 64
21:49:31.037904 IP 192.168.1.6 > 192.168.1.100: ICMP echo reply, id 59697, seq 1, length 64
21:49:11.001236 ARP, Request who-has 192.168.1.1 tell 192.168.1.6, length 28
21:49:11.001948 ARP, Reply 192.168.1.1 is-at 00:1d:0f:37:fb:12 (oui Unknown), length 50
21:49:11.002123 IP 192.168.1.6.34646 > 202.96.128.166.53: 18536+[|domain]
21:49:11.984183 IP 192.168.1.100 > 192.168.1.6: ICMP echo request, id 59697, seq 2, length 64
21:49:11.984499 IP 192.168.1.6 > 192.168.1.100: ICMP echo reply, id 59697, seq 2, length 64
21:49:12.985217 IP 192.168.1.100 > 192.168.1.6: ICMP echo request, id 59697, seq 3, length 64
21:49:12.985515 IP 192.168.1.6 > 192.168.1.100: ICMP echo reply, id 59697, seq 3, length 64
21:49:13.986275 IP 192.168.1.100 > 192.168.1.6: ICMP echo request, id 59697, seq 4, length 64
21:49:13.986568 IP 192.168.1.6 > 192.168.1.100: ICMP echo reply, id 59697, seq 4, length 64
        那个警告可能是在配置内核的时候少配了某个网络选项造成的。

16。移植sqlite-3.6.20到TQ2440开发板
        1)从sqlite官方网站上下载目前最新的sqlite源代码包,我下载的源代码是sqlite-amalgamation-3.6.20.tar.gz;
        2)解压缩源代码包且在源代码同级目录上建立编译目录build以及安装目录build/_install(编译目录和安装目录根据个人的喜好自行设置);
        3)进入编译目录build,之后执行#../configure --host=arm-linux --prefix=xxxx/build/_install
        4)修改Makefile中的CC = arm-none-linux-gnueabi-gcc、CPP =arm-none-linux-gnueabi-gcc -E、CXX = arm-none-linux-gnueabi-g++、CXXCPP =arm-none-linux-gnueabi-g++ -E(因为使用arm-linux-gcc会出现编译不过去的问题,具体原因我还没有调查清楚)
        5)#make;make install
       在build/_install/目录下可以看到bin,include,lib三个目录,其中bin中包含编译好的可执行二进制文件sqlite3,lib中包含执行sqlite3时需要的动态库,include目录包含编写C代码时使用的头文件说明。需要将bin/sqlite3以及lib目录下的动态库下载到开发板上(我将sqlite3放在开发板的/bin目录下,动态库放在/lib目录下。这样不用修改环境变量)
        6)在开发板上测试sqlite3,串口输入如下:
[root@david /]# sqlite3
SQLite version 3.6.20
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .quit
[root@david /]#
        说明sqlite3已经可以在开发板上运行了。

 

原创粉丝点击