Linux2.6内核移植系列教程

sunplusedu

贡献于2013-08-26

字数:0 关键词: Linux

http://emb.sunplusedu.com 第一:Linux 2.6内核在S3C2440平台上移植 此教程适合2.6.38之前的版本,其中2.6.35之前使用同一yaffs补丁包, 2.6.36--2.6.28 yaffs文件系统有所改变,2.6.39之后的暂时不支持,源码下载请到: http://www.kernel.org/ 1.解压linux-2.6.34.tar.bz2源码包 #tar jxvf linux-2.6.34.tar.bz2 2.修改linux-2.6.34/Makefile文件,在makefile中找到以下两条信息并做修改 ARCH ? =arm CROSS_COMPILE?=/usr/local/arm/4.3.2/bin/arm-linux- 注意: 交叉编译器的环境变量也需要改为4.3.2 #export PATH=/usr/local/arm/4.3.2/bin/:$PATH 其中ARCH变量用来决定:配置、编译时读取Linux源码arch目录下哪个体系结构的 文件 PATH 用来决定交叉编译器版本 3.修改机器类型ID号 Linux源码中支持多种平台的配置信息,内核会根据bootloader传进来的 mach-types决定那份平台的代码起作用,本人手里的板子是仿照三星公司官方给出的 demo板改版而来,所以采用arch/arm/mach-s3c2440/mach-smdk2440.c此配置文件,打 开此文件,翻到最后,有以下信息: MACHINE_START(S3C2440, "SMDK2440") /* Maintainer: Ben Dooks */ .phys_io= S3C2410_PA_UART, .io_pg_offst= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params= S3C2410_SDRAM_PA + 0x100, .init_irq= s3c24xx_init_irq, .map_io= smdk2440_map_io, .init_machine= smdk2440_machine_init, .timer= &s3c24xx_timer, MACHINE_END MACHINE_START(S3C2440, "SMDK2440")决定了此板子的mach-types,可以在以下文 件中找到S3C2440对应的具体数字,"arch/arm/tools/mach-types"文件查找 S3C2440,362,这里刚好与我们的bootloader相同,所以不用做修改,直接保存退出即 可,如果不同则根据bootloader的内容修改此文件,或根据此文件修改boorloader的内 容(在vivi中可通过param show查看,u-boot在 Y:\test\u-boot_src\u-boot_edu-2010.06\board\samsung\unsp2440\unsp2440.c文 件:gd->bd->bi_arch_number = MACH_TYPE_S3C2440;中决定)。 4.修改平台输入时钟 由于我们使用的开发板跟SMDK2440.c晶振不同,需要修改 修改平台的时钟频率, 修改内核源码“arch/arm/mach-s3c2440/mach-smdk2440.c”,把时钟初始化中 (S3C24XX_init_clocks(16934400 ))的16934400 改为12000000,因为我们的开发板上 为12M。 5.解压yaffs.tar.gz2源码包,进入yaffs2文件夹,给内核打上补丁使内核支持 yaffs2 Linux官方不支持yaffs文件系统,我们需要打上相应的补丁 2.6.35(含)之前的补丁从这里下载: http://www.rayfile.com/zh-cn/files/2dab2568-c59a-11e0-89da-0015c55db73d/ #./patch-ker.sh c /home/linux-2.6.34 2.6.36(含)之后的补丁从这里下载 http://www.rayfile.com/zh-cn/files/680097c0-c59a-11e0-943b-0015c55db73d/ #./patch-ker.sh c a /home/linux-2.6.34 6.修改内核mtd分区和bootloader(vivi)使其一致 使用vivi或U-boot烧写内核、根文件系统时,需要知道内核以及根文件系统的具体 物理地址,我们可以修改一下文件更改此信息,注必须保证这里的地址与vivi,u-boot 保持一致,否则出现烧写启动不一致的现象。 我的分区是: bootloader: 192k param: 128k (vivi和u-boot的参数保存区域,内核里没有表明,但地址 空间预留出来了) kernel: 3M rootfs: 60M 编辑文件arch/arm/plat-s3c24xx/common-smdk.c static struct mtd_partitionsmdk_default_nand_part[] = { [0]= { .name = "bootloader", .size = 0x00030000, .offset = 0, }, [1]= { .name = "kernel", .offset= 0x00050000, .size = 0x00300000, }, [2]= { .name = "rootfs", .offset= 0x00350000, .size = 0x03cac000, } }; 7.修改文件drivers/mtd/nand/s3c2410.c 内核中去掉对nand FLASH的ecc校验,由yaffs自己完成 将s3c2410_nand_init_chip函数里的NAND_ECC_SOFT改为NAND_ECC_NONE 8.到llinux-2.6.30目录下执行命令 找一个内核自带的与S3C2440比较接近的配置文件,修改得到我们的配置文件 #cp arch/arm/configs/s3c2410_defconfig .config 9.执行make menuconfig,并对选项进行配置 1)SystemType ---> S3C2440 and S3C2442 machines ---> 仅保留SMDK2440 与SMDK2440 whith S3C2440CPU module两个选项,将其他的选项全 部勾掉 2)Kernel Features ---> [*]Usethe arm EABI to compile the kernel(选中该选项,因为我们采用的编译 器是带EABI(软浮点运算)的编译器) 3)Filesystems ---> a、把与ext2 ext3 ext4相关的所有选项全部去掉(为了减小编译完内核的体积、可 选) b、Miscellaneous filesystems ---> <*>yaffs2file system support(选中此选项) 4)Device Drivers-----> Character devices---> [*]/dev/kmem virtual device support [*]Legacy(BSD) PTY support Block devices---> <>Loopback device support <>RAW block device support 5)保存退出 10.编译 make zImage,在arch/arm/boot下生成编译好的可执行程序:zImage vivi一般采 用此类型的内核 make uImage,在arch/arm/boot下生成编译好的可执行程序:UImage u-boot一般 采用此类型的内核 第二:Linux2.6.34下DM9000网卡驱动移植 DM9000是10/100M自适应的总线型网卡,Linux中对其支持已经非常完善,不同开发 板之间移植、修改主要集中在总线的选择及中断选择上 1)修改arch/arm/mach-s3c2440/mach-smdk2440.c文件,增加以下信息 /****add by dengwei*********************************/ #include static struct resource s3c_dm9k_resource[] = { [0] = { .start = S3C2410_CS3, //网卡连接在CS3总线上(此处跟据不同开发板进行 修改) .end = S3C2410_CS3 + 3, .flags = IORESOURCE_MEM, }, [1] = { .start = S3C2410_CS3 + 4, //同上 .end = S3C2410_CS3 + 4 + 3, .flags = IORESOURCE_MEM, }, [2] = { .start = IRQ_EINT7, //根据硬件外部中断管脚修改此数字 .end = IRQ_EINT7, .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, } }; static struct dm9000_plat_data s3c_dm9k_platdata = { .flags =DM9000_PLATF_16BITONLY, }; struct platform_device s3c_device_dm9k = { .name = "dm9000", .id = 0, .num_resources = ARRAY_SIZE(s3c_dm9k_resource), .resource = s3c_dm9k_resource, .dev = { .platform_data= &s3c_dm9k_platdata, } }; EXPORT_SYMBOL(s3c_device_dm9k); /*************************add by dengwei***************************/ 2)修改 arch/arm/mach-s3c2440/mach-smdk2440.c文件 修改struct platform_device *smdk2440_devices[]__initdata结构体增加以下代 码: static struct platform_device*smdk2440_devices[] __initdata = { &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, &s3c_device_dm9k, //for dm9000 add by dengwei }; 3)修改drivers/net/dm9000.c源码: 在头文件区增加头文件: #include 大约1365行左右增加以下代码: static int __devinit dm9000_probe(structplatform_device *pdev) { //add here 函数开始处 } /**********add by dengwei******************************************/ [cpp] view plaincopy #if defined(CONFIG_ARCH_S3C2440) int oldval_bwscon = *((volatile unsignedint *)S3C2410_BWSCON); *((volatileunsigned int *)S3C2410_BWSCON)=(oldval_bwscon&~(3<<16))|S3C2410_BWSCON_DW3_16|S3C2410_BW SCON_WS3|S3C2410_BWSCON_ST3; //设置BANK3:总线宽度为16,使能nWAIT *((volatile unsigned int *)S3C2410_BANKCON3) = 0x1f7c; //设置BANK3的时间 参数 #endif /**********add by dengwei****************/ 4)修改make menuconfig配置选项: Devices Drivers ---> Network device support---> Ethernet (10 or 100) ---> [*]DM9000support (4)DM9000maxinum debug level //仅保留这两个选项,其余的全部去掉 5)重新编译内核,烧入开发板中即可 6)第一次使用的开发板需使用ifconfig eth0 hw ether 12:34:56:78:32:65 设置 mac地址 (MAC地址可以随便设置) 使用ifconfigeth0 192.168.220.*设置开发板IP 使用ping命令ping主机即可 原文链接:http://emb.sunplusedu.com/answer/2013/0821/2116.html 第三:Linux2.6.34 下 USB 驱动(U 盘\USB 鼠标、键盘) 由于 Linux 中对 USB 的驱动已经非常完善,这里只需要按照以下配置 就可以 了,配置完后重新编译内核烧到开发板上 1、修改 make menuconfig System Type --> <*> S3C2410 USB function support <*> support for S3C2410 USB character device emulation Input core support --> <*>Input core support <*>keyboard support <*>Mouse support SCSI device support ---> < > RAID Transport Class <*> SCSI device support < > SCSI target support [*] legacy /proc/scsi/ support *** SCSI support type (disk, tape,CD-ROM) *** <*> SCSI disk support < > SCSI tape support < > SCSI OnStream SC-x0 tapesupport < > SCSI CDROM support <*> SCSI generic support < > SCSI media changer support [*] HID Devices ---> --- HID Devices -*- Generic HID support [ ] /dev/hidraw raw HID device support *** USB Input Devices *** <*> USB Human Interface Device(full HID) support [ ] PID device support [*] /dev/hiddev raw HID device support [*] USB support ---> {*} Support for Host-side USB [ ] USB verbose debug messages [ ] USB announce new devices *** Miscellaneous USB options *** [*] USB device filesystem [*] USB device class-devices (DEPRECATED) <*> OHCI HCD support <*> USB Mass Storage support --- USB Human Interface Devices(HID) <*> USB Human Interface Devices(full HID) support [*] /dev/hiddev raw HID device support(EXPERIMENTAL) 2、插入 U 盘。 当系统启动后插入 U 盘就会出现一些信息,可以看到 sda 就是 U 盘设备 了,sda1 是 U 盘的一个分区。 mount /dev/sda1 /mnt/ -o utf8 utf8 参数可以识别中文 3、插入鼠标键盘 会有相应提示 第四:Linux 2.6.34 下 LCD 驱动移植 Linux下的LCD设备被抽象成标准的framebuffer设备,我们只需要修改与LCD有 关的扫描时间及分辨率即可 1、修改 arch/arm/mach-s3c2440/mach-smdk2440.c 如下: /* LCD driver info */ 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 = 64000, /*HCLK 60 MHz, divisor 10 */ .xres = 320, .yres = 240, .bpp =16, .left_margin = 18, .right_margin = 38, .hsync_len = 30, .upper_margin = 18, .lower_margin = 18, .vsync_len = 3, }; static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = { .displays = &smdk2440_lcd_cfg, .num_displays = 1, .default_display= 0, #if 0 /*currently setup by downloader */ .gpccon = 0xaa940659, .gpccon_mask = 0xffffffff, .gpcup = 0x0000ffff, .gpcup_mask = 0xffffffff, .gpdcon = 0xaa84aaa0, .gpdcon_mask = 0xffffffff, .gpdup = 0x0000faff, .gpdup_mask = 0xffffffff, #endif .gpccon = 0xaa955699, //这是将GPC和GPD设置成功能引脚, 也可以不设置 .gpccon_mask = 0xffc003cc, .gpcup =0x0000ffff, .gpcup_mask = 0xffffffff, .gpdcon = 0xaa95aaa1, .gpdcon_mask = 0xffc0fff0, .gpdup =0x0000faff, .gpdup_mask = 0xffffffff, //.lpcsel = ((0xCE6) & ~7) | 1<<4, .lpcsel = 0xf82, //设置TCONSEL寄存器选择三星 240x320 }; static struct platform_device*smdk2440_devices[] __initdata = { &s3c_device_ohci, &s3c_device_lcd, //检查这里有没有加上 &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, }; 2.让系统启动起来看到 bootlogo 小企鹅,得在 make menuconfig 中进行配置 添加 在Device Drivers ---> Graphics support ---> Bootup logo下面可以 全部选中支持 第五:Linux2.6.34 开机启动图片修改 Linux启动时会在屏幕上显示一个默认的开机图片,我们可以修改成为自己的图片, 需要做以下工作 软件gimp下载地址: http://www.rayfile.com/zh-cn/files/0bb556bd-c5a0-11e0-9185-0015c55db73d/ 1、打开gimp号称 linux 下的 photoshop ,安装windows版 (gimp-2.6.9-i686-setup.exe) 打开任何格式的一张将要转换的图片 选择:图像--->模式--->索引颜色转换--->最大颜色数量设置为(224)--->转换 还可以通过:图像--->缩放图像--->设置想要的图像大小 最后:文件--->另存为--->选择ppm格式--->保存格式为ASCII 2、将转换好的图片拷贝到 drivers\video\logo 替换 logo_linux_clut224.ppm 删除 logo_linux_clut224.c和logo_linux_clut224.o 重新make zImage 注:如果内核编译过,并且按照前篇已经能显示小企鹅图像,则需要按照以上说明 删除文件,如果没有编译过,没有以上文件,直将图片拷贝过来即可 第六:Linux 下 LCD 10 分钟自动关屏的问题 Linux下的LCD驱动默认 10 分钟后会自动关闭屏幕,我们可以修改一下代码让其 不自动关屏 在有一个 drivers/char/vt.c 文件其中有一个变量(blankinterval)可以设置它来修 改自动关屏的时间,也可以在函数(blank_screen_t)开头直接返回,这样就永远不会关 屏了 第七:UDA1341声卡驱动 本人手中的开发板使用的是UDA1341音频芯片,走的标准的IIS总线,Linux中对IIS 及UDA1341的支持已经非常完善了,我们只需要将相应的IIS管脚设置为我们开发板的原 理图设计的管脚就可以了。 1、makemenuconfig 声卡的配置是: Device Drivers <*>Sound card support <*>Advanced Linux Sound Architecture <*>ALSA for Soc audiosupport-à <*>SoC Audiofor the Samsung S3C24XXchips <*>SoC I2SAudio support UDA134X wired to a S3C24XX 2、配置声卡驱动 下面是我在mach-smdk2440.c上修改的地方: … #include //加上这个头文件 … static struct s3c24xx_uda134x_platform_data s3c24xx_uda134x_data = { .l3_clk = S3C2410_GPG(10), //这三个引脚是跟据自己开发板的硬件连接决定的 .l3_data = S3C2410_GPG(11), //L3接口需要三个线:时钟、数据、模式选择线, 根据自己的 .l3_mode = S3C2410_GPG(9), .model = UDA134X_UDA1341, }; static struct platform_device s3c24xx_uda134x = { .name = "s3c24xx_uda134x", .dev = { .platform_data = &s3c24xx_uda134x_data, } }; 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, &s3c24xx_uda134x, }; 3、编译、下载 在内核目录下make zImage后将生成的内核文件烧写到开发板。 4、测试 启动开发板后将已经拷贝歌曲的U盘插入到开发板的USB接口,挂载U盘后,运行”cat 01.mp3 > /dev/dsp”命令后听到音频耳机输出哧哧的声音,证明声卡驱动配置成功。 第八:Linux下SD卡驱动移植 Linux中对SD卡的支持非常完善了,我们只需要按照以下修改即可完成SD卡的初始 化 1、arch/arm/mach-s3c2440/mach-smdk2440.c platform结构中增加 &s3c_device_sdi语句。 static struct platform_device*smdk2440_devices[] __initdata = { &s3c_device_usb, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c, &s3c_device_iis, &s3c_device_nand, &s3c_device_sdi, //add here }; 2、添加和开发板相关的 SD 卡插拔引发的中断: #vi drivers/mmc/host/s3cmci.c +1335 在1335行,添加如下内容: host->irq_cd = IRQ_EINT16; s3c2410_gpio_cfgpin(S3C2410_GPG8, S3C2410_GPG8_EINT16); 注:SD卡中断管脚需根据硬件连接图实际情况修改 3、在makemenuconfig时选上所有关于sd卡的信息,要想支持中文还得选上: Device Drivers ---> <*> MMC/SD/SDIO card support ---> --- MMC/SD/SDIO card support [ ] MMC debugging [ ] Allow unsafe resume (DANGEROUS) *** MMC/SD/SDIO Card Drivers *** <*> MMC block device driver [*] Use bounce buffer for simple hosts < > SDIO UART/GPS class support < > MMC host test driver *** MMC/SD/SDIO Host Controller Drivers *** < > Secure Digital Host Controller Interface support < > MMC/SD/SDIO over SPI <*> Samsung S3CSD/MMC Card Interface support File system--》 DOS/FAT/NT Filesystems--》 VFAT(Windows-95)fs support (437)Default codepage for FAT **把437改为936 Native language support --> [*]Simplified Chinese charset [*]NLS UTF-8 4、测试 这样就可直接挂载了 mount -t vfat /dev/mmcblk0 /mnt 如果sd卡分区了 mount -t vfat /dev/mmcblk0p1 /mnt 直接读写sd就可以了 第九:Linux 下 USB 从(USB gadget) 驱动配置与使用 S3C2440提供了一个USB从接口,我们可以使用它来把2440模拟为一个U盘,直接从 电脑上以盘符的形式访问2440 一、内核配置 USB SUPPORT <*>USB Gadget Support ---> USB Peripheral Controller (S3C2410 USB Device Controller) ---> S3C2410 USB Device Controller [] S3C2410 udc debug messages USB Gadget Drivers File-backed Storage Gadget 二、make zImage 生成z?Image文件烧入开发板 make modules 在driver/usb/Gadget目录下生成g_file_storage.ko文件,烤入开 发板中 三、开发板操作 1、建立一个镜像模拟U盘 #dd if=/dev/zero of=vfat.img bs=1M count=20//制作一个fat格式的镜像文件, 在主机上、开发板上做都可以 #losetup /dev/loop0 vfat.img//将镜像与loop0建立连接 #mkfs.vfat /dev/loop0//格式化做出的镜像 #mkdir vfat_mount_point//创建挂载点 #mount /dev/loop0 vfat_mount_point/挂载挂载点 #insmod g_file_storage.ko file=/dev/loop0 stall=0 removable=1//插入脚本 (如果根文件系统有其它分区,可以直接指定相应的分区,不过需格式化为fat方 可使用) 插上开发板的usb从接口,即可从PC机段看到vfat_mount_point下的内容 四、存在问题: 1、在PC机下看开发板,永远显示空间已用满,无法从PC机将程序拷到开发板中 2、从开发板往PC机烤东西时,要先挂载vfat_mount_point目录,将东西拷入 vfat_mount_point目录 再敲入以下命令后insmod g_file_storage.ko file=/dev/loop0 stall=0 removable=1 最后插入USB从口 原文链接:http://emb.sunplusedu.com/answer/2013/0821/2123.html 第十:Linux 下 S3C2440 RTC 实时时钟驱动配置与修改 Linux下对S3C2440 RTC的支持非常完善,我们只需要做简单的修改,即可使用RTC 1、vi 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, //这里我们添加上RTC平台设备,默认是没添加的 }; 2、make zImage 3、使用与测试 Linux下的时间分为两种,系统时间与硬件时间。 我们一般看到的时间就是系统时间,比如现在是11:45 am。 硬件时间指的是主板上CMOS中的时间或RTC中的时间,这两个时间并不是总是同步 的,一般情况下大约11分钟同步一次。 linux系统开机时,从CMOS/rtc中读取当前时间,作为系统时间,从此以后系统时 间独立tick,此时如果你用date命令修改了系统时间,硬件时间是不受影响的,就是说 如果此时关机,下次的系统时间还是不对。要想将系统时间保存到硬件时间,可以是用 hwclock 或者clock命令,hwclock就是hardware clock的意思。 一个完整的修改linux系统时间的过程如下所示 a)设置系统时间 #date -s 2010.12.11-8:5:24 b)将当前系统时间保存到硬件时间 #hwclock --systohc #clock --systohc c)读取硬件时间为系统时间 #hwclock –s 第十一:S3C2440 UART2被配置为CTS问题解决 Linux内核默认把uart2的功能设置为nRTS1、nTCTS1,没有作为正常串口使用,如 果我们想要将uart2作为串口,需要做以下修改:linux2.6内核将GPHCON寄存器的值置 为0x16faaa就是说GPH6被设置为nRTS1,GPH7被设置为nCTS1,此时,串口2是无法收发 数据的。 1、修改arch/arm/mach-s3c2440/mach-smdk2440.c中的uart2的配置,修改后如下: static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = { [0] = { .hwport = 0, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, }, [1] = { .hwport = 1, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, }, /* IR port */ [2] = { .hwport = 2, .flags = 0, .ucon = 0x3c5, .ulcon = 0x03,/*old0x43*/ .ufcon = 0x51, } }; 2、vi drivers/serial/samsung.c //增加以下头文件 #include #include 在static int s3c24xx_serial_startup(struct uart_port *port)函数最后,添 加 s3c2410_gpio_cfgpin(S3C2410_GPH(6), S3C2410_GPH6_TXD2); s3c2410_gpio_pullup(S3C2410_GPH(6), 1); s3c2410_gpio_cfgpin(S3C2410_GPH(7), S3C2410_GPH7_RXD2); s3c2410_gpio_pullup(S3C2410_GPH(7), 1); 3、重新编译zImage下载进开发板即可 原文链接:http://emb.sunplusedu.com/answer/2013/0821/2125.html 以上资料来自凌阳教育嵌入式培训网,更多嵌入式linux学习资料免费下载: http://emb.sunplusedu.com

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档

相关文档