源文来自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 Device Support->NAND Flash support for Samsung S3C SoCs和Samsung S3C NAND Hardware ECC;同时需要在MTD support中选择MTD partitioning support(支持分区)、Command line partition table parsing、Direct char device access to MTD devices和Caching block device access to MTD devices。MTD support选择项中只需要选择这些就可以了,别的都可以去掉。 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 system time from RTC on startup and resume、/sys/class/rtc/rtcN (sysfs)、/proc/driver/rtc (procfs for rtc0)、/dev/rtcN (character devices)和Samsung S3C series SoC RTC。其中Samsung S3C series SoC RTC为必选项,/sys/class/rtc/rtcN (sysfs)、/proc/driver/rtc (procfs for rtc0)、/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...... Uncompressing Linux................................................................................................... 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文件且修改#define CONFIG_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 card support->Advanced Linux Sound Architecture->OSS相关部分、procfs相关部分和ALSA for SoC audio support->SoC Audio for the Samsung S3CXXXX chips和SoC I2S Audio support UDA134X wired to 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->USB support->USB Gadget support(编译进内核),以及其下的USB片上外设控制器为S3C2410、USB Gadget driver和File-backed Storage support(这两项编译成模块,需要动态加载)。除了内核配置外,还需要对USB Gadget平台设备进行必要的设置。编辑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->Support for frame buffer devices->Enable firmware EDID、Enable Video Mode Handling Helpers和S3C2410 LCD framebuffer support,同时在Graphics support选项中还要选择Console display driver support->Framebuffer Console support; 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已经可以在开发板上运行了。 |