arm内核移植过程
arm内核移植过程
转自:
http://student.csdn.net/space.php?uid=366890&do=blog&id=28865
1 内核移植过程 ? 1.1 下载linux 内核 ? ??? 从http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.14.1.tar.bz2 下载linux-2.6.14.1 内核至home/arm/dev_home/kernel. [root@localhost ~]#su arm [arm@localhost ~]#cd $KERNEL [arm@localhost kernel]#tar -xzvf linux-2.6.14.1.tar.gz [arm@localhost kernel]# pwd /home/arm/dev_home/kernel [arm@localhost kernel]# cd linux-2.6.14 ?????? 进入内核解压后的目录,以后示例中,只要是相对路径全部是相对于 ?????? /home/arm/dev_home/kernel/linux-2.6.14/此目录 ? 1.2 修改 Makefile ? 修改内核目录树根下的的Makefile,指明交叉编译器 [arm@localhost linux-2.6.14]# vi Makefile 找到ARCH 和CROSS_COMPILE ,修改 ARCH?????? ?= arm CROSS_COMPILE??? ?= arm-linux- ? 然后设置你的PATH 环境变量,使其可以找到你的交叉编译工具链 [arm@localhost linux-2.6.14]# echo $PATH /usr/local/arm/3.4.4/bin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/ly/bin 如果/usr/local/arm/3.4.4/bin 搜索路径,加入下面语句在~/.bashrc 中 [arm@localhost linux-2.6.14]# vi ~/.bashrc export PATH=/usr/local/arm/3.4.4/bin:$PATH ? 再重新登陆. [arm@localhost linux-2.6.14]#su arm ? 1.3 设置flash 分区 ? 此处一共要修改 3个文件,分别是: ? 1.3.1指明分区信息 ? 在arch/arm/mach-s3c2410/devs.c 文件中: ? [arm@localhost linux-2.6.14]$ vi arch/arm/mach-s3c2410/devs.c ? 添加如下内容: #include <linux/mtd/partitions.h> #include <linux/mtd/nand.h> #include <asm/arch/nand.h> ... /* NAND Controller */ ? 1.建立Nand Flash 分区表 /* 一个Nand Flash 总共64MB,按如下大小进行分区 */ static struct mtd_partition partition_info[] ={ ??????? { /* 1MB? */ ???????????????? name: "bootloader", ???????????????? size:? 0x00100000, ???????????????? offset: 0x0, ??????? },{ /* 3MB */ ???????????????? name: "kernel", ???????????????? size:? 0x00300000, ???????????????? offset: 0x00100000,{ /* 40MB */ ???????????????? name: "root", ???????????????? size:? 0x02800000, ???????????????? offset: 0x00400000,{ /* 20MB */ ???????????????? name: "user", ???????????????? size: 0x00f00000, ???????????????? offset: 0x02d00000, ??????? } }; ? name: 代表分区名字 size: 代表flash 分区大小(单位:字节) offset: 代表flash 分区的起始地址(相对于0x0 的偏移) ? ?目标板计划分4 个区,分别存放bootloader,kernel,rootfs 以及以便以后扩展使用的用户文件系统空间。 各分区在Nand flash 中起始地址. 分区大小. 记录如下: ?bootloader: ??????? start: 0x00000000 ??????? len:??? 0x00100000 ??????? 1MB ?kernel: ??????? start: 0x00100000 ??????? len:??? 0x00300000 ??????? 3MB ?rootfs: ??????? start: 0x00400000 ??????? len:??? 0x02800000 ??????? 40MB ?User: ??????? start: 0x02c00000 ??????? len:??? 0x01400000 ??????? 20MB ? 2. 加入Nand Flash 分区 struct s3c2410_nand_set nandset ={ ??????? nr_partitions: 4,?????????? /* the number of partitions */ ??????? partitions: partition_info,/* partition table????????? */ }; nr_partitions: 指明partition_info 中定义的分区数目 partitions: 分区信息表 ? 3. 建立Nand Flash 芯片支持 struct s3c2410_platform_nand superlpplatform={ ??????? tacls:0, ??????? twrph0:30, ??????? twrph1:0, ??????? sets: &nandset, ??????? nr_sets: 1, }; tacls,twrph0,twrph1 的意思见S3C2410 手册的6-3,这3 个值最后会被设置到NFCONF 中,见S3C2410 手册6-6. sets: 支持的分区集 nr_set:分区集的个数 ? 4. 加入Nand Flash 芯片支持到Nand Flash 驱动 另外,还要修改此文件中的s3c_device_nand 结构体变量,添加对dev 成员的赋值 struct platform_device s3c_device_nand = { ??????? .name??????????? = "s3c2410-nand",???? /* Device name */ ??????? .id????????????? = -1,???????????????? /* Device ID??? */ ??????? .num_resources?????? = ARRAY_SIZE(s3c_nand_resource), ??????? .resource??????? = s3c_nand_resource,/* Nand Flash Controller Registers */ ? ??????? /* Add the Nand Flash device */ ??????? .dev = { ????????????????? .platform_data = &superlpplatform ????????? } }; name:? 设备名称 id: 有效设备编号,如果只有唯一的一个设备为-1,有多个设备从0 开始计数. num_resource: 有几个寄存器区 resource: 寄存器区数组首地址 dev: 支持的Nand Flash 设备 ? 1.3.2 指定启动时初始化 ? kernel 启动时依据我们对分区的设置进行初始配置? 修改arch/arm/mach-s3c2410/mach-smdk2410.c 文件 [arm@localhost linux-2.6.14]$ vi arch/arm/mach-s3c2410/mach-smdk2410.c 修改smdk2410_devices[].指明初始化时包括我们在前面所设置的flash 分区信息 static struct platform_device *smdk2410_devices[] __initdata = { ??????? &s3c_device_usb, ??????? &s3c_device_lcd, ??????? &s3c_device_wdt, ??????? &s3c_device_i2c, ??????? &s3c_device_iis, ? ??????? /* 添加如下语句即可 */ ??????? &s3c_device_nand, }; 保存,退出。 ? 1.3.3 禁止 Flash ECC校验? ? ??? 我们的内核都是通过UBOOT 写到Nand Flash 的,UBOOT 通过的软件ECC 算法产生ECC 校验码,这与内核 校验的ECC 码不一样,内核中的ECC 码是由S3C2410 中Nand Flash 控制器产生的. 所以,我们在这里选择禁止 内核ECC 校验. 修改drivers/mtd/nand/s3c2410.c 文件: [arm@localhost linux-2.6.14]$ vi drivers/mtd/nand/s3c2410.c 找到s3c2410_nand_init_chip()函数,在该函数体最后加上一条语句: chip->eccmode = NAND_ECC_NONE; 保存,退出。 ? OK.我们的关于flash 分区的设置全部完工. ? 1.4 配置内核 ? 1.4.1 支持启动时挂载 devfs ? 为了我们的内核支持devfs 以及在启动时并在/sbin/init 运???????????????? 之前能自动挂载/dev 为devfs 文件系统,修改 fs/Kconfig 文件 [arm@localhost linux-2.6.14]$ vi fs/Kconfig 找到menu "Pseudo filesystems" 添加如下语句: config DEVFS_FS ??????? bool "/dev file system support (OBSOLETE)" ??????? default y ? config DEVFS_MOUNT ??????? bool "Automatically mount at boot" ??????? default y ??????? depends on DEVFS_FS ? 1.4.2 配置内核产生.config 文件 ? [arm@localhost linux-2.6.14]$ cp arch/arm/configs/smdk2410_defconfig .config [arm@localhost linux-2.6.14]$ make menuconfig ? 在smdk2410_defconfig 基础上,我所增删的内核配置项如下: ? Loadable module support? ---> ????????????????????????? [*] Enable loadable module support ?????????????????????????????????? [*] Automatic kernel module loading ? System Type? ---> [*] S3C2410 DMA support ? Boot options? ---> Default kernel command string: ???????? noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200 ? ???????? #说明:mtdblock2 代表我的第3 个flash 分区,它是我的rootfs ???????? #?? console=ttySAC0,115200 使kernel 启动期间的信息全部输出到串口0 上. ???????? #?? 2.6 内核对于串口的命名改为ttySAC0 ,但这不影响用户空间的串口编程。 ???????? #?? 用户空间的串口编程针对的仍是/dev/ttyS0 等 ? Floating point emulation ---> ????????????????????????? [*] NWFPE math emulation ??????????????????????????? This is necessary to run most binaries!!! ? #接下来要做的是对内核MTD 子系统的设置 Device Drivers? ---> ???????? Memory Technology Devices (MTD)? ---> ????????????????????????? [*] MTD partitioning support ??????????????????????????? #支持MTD 分区,这样我们在前面设置的分区才有意义 ????????????????????????? [*] Command line partition table parsing ??????????????????????????? #支持从命令行设置flash 分区信息,灵活 ?????????????????????????????????? RAM/ROM/Flash chip drivers? ---> ??????????????????????????????????? <*> Detect flash chips by Common Flash ???????????????????????????????????? Interface (CFI) probe ??????????????????????????????????? <*> Detect non-CFI AMD/JEDEC-compatible flash chips ??????????????????????????????????? <*> Support for Intel/Sharp flash chips ??????????????????????????????????? <*> Support for AMD/Fujitsu flash chips ??????????????????????????????????? <*> Support for ROM chips in bus mapping ?????????????????????????????????? NAND Flash Device Drivers? ---> ??????????????????????????????????? <*> NAND Device Support ??????????????????????????????????? <*> NAND Flash support for S3C2410/S3C2440 SoC ? ???????? Character devices? ---> ????????????????????????? [*] Non-standard serial port support ????????????????????????? [*] S3C2410 RTC Driver ? #接下来做的是针对文件系统的设置,本人实验时目标板上要上的文件系统是cramfs,故做如下配置 File systems? ---> ????????????????????????? <> Second extended fs support? #去除对ext2 的支持 ???????????????? Pseudo filesystems? ---> ????????????????????????? [*] /proc file system support ????????????????????????? [*] Virtual memory file system support (former shm fs) ????????????????????????? [*] /dev file system support (OBSOLETE) ????????????????????????? [*] Automatically mount at boot (NEW) ??????????????????????????? #这里会看到我们前先修改fs/Kconfig 的成果,devfs 已经被支持上了 ???????????????? Miscellaneous filesystems? ---> ????????????????????????? <*> Compressed ROM file system support (cramfs) ??????????????????????????? #支持cramfs ???????????????? Network File Systems? ---> ????????????????????????? <*> NFS file system support ? 保存退出,产生.config 文件. .config 文件能从提供的2.4.14.1 的内核包中找到,文件名为config.back. ? 1.4.3编译内核 ? [arm@localhost linux-2.6.14]$ make zImage 注意:若编译内核出现如下情况 ? LD???? .tmp_vmlinux1 ? arm-linux-ld:arch/arm/kernel/vmlinux.lds:1439: parse error ? make: *** [.tmp_vmlinux1] Error 1 ? 解决方法:修改arch/arm/kernel/vmlinux.lds [arm@localhost linux-2.6.14]$ vi arch/arm/kernel/vmlinux.lds 将文件尾2 条的ASSERT 注释掉 (1439??????????????????? ) /* ASSERT((__proc_info_end - __proc_info_begin),"missing CPU support") */ /* ASSERT((__arch_info_end - __arch_info_begin),"no machine record defined") */ ? 然后重新make zImage 即可 ? 1.4.4 下载zImage到开发板 ? CRANE2410 # tftp 0x30008000 zImage TFTP from server 192.168.1.6; our IP address is 192.168.1.5 Filename 'zImage'. Load address: 0x30008000 Loading: ################################################################# ???????? ################################################################# ???????? ################################################################# ???????? ############################# done Bytes transferred = 1142856 (117048 hex) CRANE2410 # bootm 0x30008000 ? 1.4.5 目标板启动信息如下 IRQ Stack: 33fc149c FIQ Stack: 33fc249c 1 1 DRAM Configuration: Bank #0: 30000000 64 MB 1 NAND:64 MB In:?? serial Out:?? serial Err:? serial Hit any key to stop autoboot:? 0 zImage magic = 0x016f2818 NOW,Booting Linux...... Uncompressing Linux............................................................................ don.Linux version 2.6.14.1 (arm@dozec) (gcc version 3.3.2) #15 Thu Jul 6 14:26:29 CST 2006 CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T) Machine: SMDK2410 Warning: bad configuration page,trying to continue Memory policy: ECC disabled,Data cache writeback CPU S3C2410A (id 0x32410002) S3C2410: core 202.800 MHz,memory 101.400 MHz,peripheral 50.700 MHz S3C2410 Clocks,(c) 2004 Simtec Electronics CLOCK: Slow mode (1.500 MHz),fast,MPLL on,UPLL on CPU0: D VIVT write-back cache CPU0: I cache: 16384 bytes,associativity 64,32 byte lines,8 sets CPU0: D cache: 16384 bytes,8 sets Built 1 zonelists Kernel command line: noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200 irq: clearing subpending status 00000002 PID hash table entries: 128 (order: 7,2048 bytes) timer tcon=00500000,tcnt a509,tcfg 00000200,00000000,usec 00001e4c Console: colour dummy device 80x30 Dentry cache hash table entries: 4096 (order: 2,16384 bytes) Inode-cache hash table entries: 2048 (order: 1,8192 bytes) Memory: 16MB = 16MB total Memory: 13712KB available (1927K code,422K data,104K init) Mount-cache hash table entries: 512 CPU: Testing write buffer coherency: ok softlockup thread 0 started up. NET: Registered protocol family 16 S3C2410: Initialising architecture SCSI subsystem initialized usbcore: registered new driver usbfs usbcore: registered new driver hub S3C2410 DMA Driver,(c) 2003-2004 Simtec Electronics DMA channel 0 at c1800000,irq 33 DMA channel 1 at c1800040,irq 34 DMA channel 2 at c1800080,irq 35 DMA channel 3 at c18000c0,irq 36 NetWinder Floating Point Emulator V0.97 (double precision) devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au) devfs: boot_options: 0x1 Console: switching to colour frame buffer device 80x25 fb0: Virtual frame buffer device,using 1024K of video memory S3C2410 RTC,(c) 2004 Simtec Electronics s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410 s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410 s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410 io scheduler noop registered io scheduler anticipatory registered io scheduler deadline registered io scheduler cfq registered RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize Cirrus Logic CS8900A driver for Linux (Modified for SMDK2410) eth0: CS8900A rev E at 0xe0000300 irq=53,no eeprom,addr: 08: 0:3E:26:0A:5B S3C24XX NAND Driver,(c) 2004 Simtec Electronics s3c2410-nand: mapped registers at c1980000 s3c2410-nand: timing: Tacls 10ns,Twrph0 30ns,Twrph1 10ns NAND device: Manufacturer ID: 0xec,Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit) NAND_ECC_NONE selected by board driver. This is not recommended !! Scanning device for bad blocks Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit": 0x00000000-0x00100000 : "bootloader" 0x00100000-0x00500000 : "kernel" 0x00500000-0x02d00000 : "root" 0x02d00000-0x03c00000 : "User" usbmon: debugfs is not available 116x: driver isp116x-hcd,05 Aug 2005 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: Product: S3C24XX OHCI usb usb1: Manufacturer: Linux 2.6.14.1 ohci_hcd usb usb1: SerialNumber: s3c24xx hub 1-0:1.0: USB hub found hub 1-0:1.0: 2 ports detected sl811: driver sl811-hcd,19 May 2005 usbcore: registered new driver cdc_acm drivers/usb/class/cdc-acm.c: v0.23:USB Abstract Control Model driver for USB modems and ISDN adaptesdrivers/usb/class/bluetty.c: USB Bluetooth support registered usbcore: registered new driver bluetty drivers/usb/class/bluetty.c: USB Bluetooth tty driver v0.13 usbcore: registered new driver usblp drivers/usb/class/usblp.c: v0.13: USB Printer Device Class driver Initializing USB Mass Storage driver... usbcore: registered new driver usb-storage USB Mass Storage support registered. mice: PS/2 mouse device common for all mice NET: Registered protocol family 2 IP route cache hash table entries: 256 (order: -2,1024 bytes) TCP established hash table entries: 1024 (order: 0,4096 bytes) TCP bind hash table entries: 1024 (order: 0,4096 bytes) TCP: Hash tables configured (established 1024 bind 1024) TCP reno registered TCP bic registered NET: Registered protocol family 1 NET: Registered protocol family 17 Reading data from NAND FLASH without ECC is not recommended VFS: Mounted root (cramfs filesystem) readonly. Mounted devfs on /dev Freeing init memory: 104K Reading data from NAND FLASH without ECC is not recommended mount /etc as ramfs re-create the /etc/mtab entries ------------mount /dev/shm as tmpfs ------------mount /proc as proc ------------mount /sys as sysfs init started:? BusyBox v1.1.3 (2006.07.03-03:43+0000) multi-call binary Starting pid 28,console /dev/tts/0: '/etc/init.d/rcS' in /etc/init.d/rcS -------------/sbin/ifconfig eth0 192.168.1.5 ? Please press Enter to activate this console. # ? 1.5 Linux 下cs8900a 的移植说明 ? 1.5.1 为 cs8900a建立编译菜单 ? 1. 拷贝到文件 把cs8900a 的压缩包拷贝到arm 用户下的dev_home/localapps/ [arm@localhost localapps]$ tar -xzvf cs8900a.tar.gz [arm@localhost localapps]$cd cs8900a [arm@localhost cs8900a]$cp???? cs8900a.c $KERNEL/linux-2.6.14.1/drivers/net/ [arm@localhost cs8900a]$cp cs8900.h $KERNEL/linux-2.6.14.1/drivers/net/ ? 2. 修改Kconfig 文件 [arm@localhost cs8900a]$vi $KERNEL/linux-2.6.14.1/drivers/net/Kconfig #加入如下内容 ? ??????? config CS8900a ??????? tristate "CS8900a support" ??????? depends on NET_ETHERNET && ARM && ARCH_SMDK2410 ??????? ---help--- ???????? Support for CS8900A chipset based Ethernet cards. If you have a network (Ether ???????? net) card of this type,say Y and read the? Ethernet-HOWTO,available from? as ???????? well as. ???????? To compile this driver as a module,choose M here and read. ???????? The module will be called cs8900.o. ? 3. 修改Makefile 文件 [arm@localhost cs8900a]$vi $KERNEL/linux-2.6.14.1/drivers/net/Makefile #加入如下内容 ???????? obj-$(CONFIG_CS8900a)??????????? += cs8900a.o ? 1.5.2 修改 S3C2410相关信息 ? 1. 加入CS8900A 在内存中的起始位置 [arm@localhost cs8900a]$cp reg-cs8900.h $KERNEL/linux-2.6.14.1/include/asm-arm/arch-s3c2410/ cs8900.h 的内容如下: #ifndef _INCLUDE_CS8900A_H_ #define _INCLUDE_CS8900A_H_ ? #include <linux/config.h> ? #define pSMDK2410_ETH_IO?????????? 0x19000000 /* S3C2410_CS3 0x18000000 */ #define vSMDK2410_ETH_IO?????????? 0xE0000000 #define SMDK2410_ETH_IRQ?????????? IRQ_EINT9 ? #endif ? 2. 加入cs8900A 的物理地址到虚拟地址的映射 [arm@localhost cs8900a]$vi $KERNEL/linux-2.6.14.1/arch/arm/mach-s3c2410/mach-smdk2410.c /* 加入如下内容 */ static struct map_desc smdk2410_iodesc[] __initdata = { ? {vSMDK2410_ETH_IO,0x19000000,SZ_1M,MT_DEVICE} /* Add this line */ }; ? 2 创建 uImage ? 2.1 相关技术背景介绍 ? ??? 前面已经介绍了内核编译后,生成zImage 的内核镜像文件。该镜像文件可以通过U-BOOT 提供的go 命令, 跳转执行,引导内核。同时在u-boot-1.1.4 的tools? 目录下,提供了生成uImage 的工具mkimage 命令,在生成 u-boot 的二进制镜像文件的同时,mkimage 命令会同时编译生成,无需另外编译。通过mkimage 命令,在 zImage 中加入头文件 (镜像头长0x40,真正的内核入口向后偏移了0x40 大小),生成uImage 镜像文件,该文 件就是执?????? bootm 所需的内核镜像文件。 ? 2.2 在内核中创建 uImage 的方法 ? 2.2.1 获取 mkimage工具 ? ?? 2.6 内核树的Makefile 提供了创建uImage 的方法,但需要我们提供相应的mkimage 命令。 ?? 所以首先拷贝u-boot 中tools? 目录下编译后生成的mkimage 到/usr/bin/下,然后便可以在内核根目录下通过 make uImage ?? 来创建uImage 文件。该文件生成在arch/arm/boot/下。 ? 2.2.2 修改内核的 Makefile文件 ? [arm@localhost linux-2.6.14.1]$ vi arch/arm/boot/Makefile ? #MKIMAGE 变量记录mkimage 命令的路径mkuboot.sh 脚本文件可以scripts? 目录中找到 MKIMAGE??????? := $(srctree)/scripts/mkuboot.sh ? #zreladdr-y 与params_phys-y 可以在arch/arm/mach-s3c2410/Makefile.boot 当中找到 ZRELADDR???? := $(zreladdr-y) PARAMS_PHYS := $(params_phys-y) INITRD_PHYS := $(initrd_phys-y) #生成uImage 的mkImage 命令行,其中需要关注的就是-a 与 -e 参数。 #参数-a:指明uImage 加载的SDRAM 地址,内核默认指定加载地址为0x30008000 。 #?????? u-boot 引导时,bootm 命令跳到与上相同位置执行,检查完镜像头后,它会跳到内核真正的入口点开 始执??? 。 #参数-e:指明uImage 中刨去镜像头后真正的内核入口地址。 #??? 镜像头为0x40 长,故此处指定为0x30008040 。 #?????? u-boot 引导时,go 命令可以直接指定此位置。go 命令不检查镜像头。 quiet_cmd_uimage = UIMAGE? $@ ????? cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel / ????????????????? -C none -a $(ZRELADDR) -e 0x30008040 / ????????????????? -n 'Linux-$(KERNELRELEASE)' -d $< $@ ? 3追加实验记录 ? 以同样方式移植其他2.6 主线内核,出现问题如下: ? 3.1移植 linux-2.6.15.7 ? ??? 编译通过,启动时显示: ?????? VFS: Cannot open root device "mtdblock2" or unknown-block(31,2) ?????? Please append a correct "root=" boot option ?????? Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2) ? 3.2 移植 linux-2.6.16.21 ? ???? 编译通过,启动时显示: ?????? VFS: Cannot open root device "mtdblock2" or unknown-block(31,2) ? 3.3 移植 linux-2.6.17 ? ?????? 编译失败 ? 4 参考资料 ? 1. Porting kernel 2.6.11.7 to S3C2410 ???????http://superlp.blogchina.com/1391393.html ?????? 非常感谢此篇文档的作者 ? 2. devfs 介绍 ???????http://www-128.ibm.com/developerworks/cn/linux/filesystem/l-fs4/index.html#resources ? 3. <<BUILDING EMBEDDED LINUX SYSTEMS>> ??? 中文名:<<构建嵌入式Linux 系统>> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |