热度 19
2013-8-26 14:58
3894 次阅读|
0 个评论
s3c2440 移植 Linux2.6.29.6 总结 Iyoyoo@2013/8/24 在xilinx zc702开发板上移植完linux和android后,闲来折腾已经发霉的samsung2440,arm移植网上的帖子满天飞,随便搜一个来参考就可跑的很流畅。这里也是参考网上的资料,只mark一下我移植的过程和遇到的一些问题,以便后边查看。 开发板:蓝海微星LJD-E2440,64MB flash上有个坏块。 Linux kernel:Linux2.6.29.6 gcc : arm-linux-gcc 3.4.1 busybox: busybox-1.00-pre10 bootloader: 官方提供,带有uart和usb下载功能 os:i686,Ubuntu12.10,linux3.10.1,gcc 4.7.2 仿真器:mutliICE2.3 移植过程可以分为以下几个部分: 1. 移植环境配置 2. Bootloader修改和烧写 3. Linux kernel 移植 4. cramfs文件系统移植 1.移植环境配置 在安装好Ubuntu后,设置网络和共享文件夹,也可以安装VMware tools,方便和win7拖拉文件。 Sharefolder: /home/yoyo/vmshare Workspace:/work/arm 安装linux2.6.29.6,arm-linux-gcc 3.4.1 $ cd /work/arm $ cp –rf /home/yoyo/vmshare/linux-2.6.29.6.tar.gz . / $ tar –xzf linux-2.6.29.6.tar.gz $ cp –rf /home/yoyo/vmshare/arm-linux-gcc-3.4.1.tar.bz2 . / $ bzip2 -d–xzf arm-linux-gcc-3.4.1.tar.bz2 $ tar -xvf arm-linux-gcc-3.4.1.tar 设置环境变量 $ gedit /etc/environment 添加gcc路径/work/arm/arm-linux-gcc/3.4.1/bin,用$ arm-linux-gcc –v 检查是否设置对。Thread model: posix ; gcc version 3.4.1 2. Bootloader修改和烧写 这部分折腾挺长时间,开始不知道坏块的位置,试了几次,后来发现启动linux时,会自动检查坏块,并且报告位置Bad eraseblock 733 at 0x00b74000。用bootloader烧写到坏块处会暂停一下。 原bootloader的nandflash分区如下; {0, 0x00030000, "boot"}, //192K for bootloader {0x00030000, 0x001d0000, "kernel"}, //1856k for linux kernel zImage {0x00200000, 0x01e00000, "rootfs"}, //30M for file system {0x02000000, 0x0157c000, "NK.bin"}, //22M for wince {0x0357c000, 0x009c4000, "nandflash"}, //10M for external nandflash 修改后绕开坏块: {0, 0x00030000, "boot"}, //192K {0x00030000, 0x001d0000, "kernel"}, //1856k {0x00c00000, 0x01e00000, "rootfs"}, //30M {0x02a00000, 0x0157c000, "NK.bin"}, //22M {0x03f7c000, 0x00084000, "nandflash"}, //2M rootfs分区有坏块时,启动总是提示文件系统解压失败。板子上的flash已经烧有bootloader程序,能在DNW下擦除和下载程序。 开发板自带的烧写程序是基于并口的SJF2440.exe,本没有并口,这里用自带的bootloader和mutliICE烧写boot分区。 用MutliIce烧写bootloader 先在DNW下用自带的bootloader擦除nandflash第0分区bootloader,再用AXD全速debug跑bootloader程序,小等一段时间,插上usb,选择菜单1,将bootloader.bin下载到sdram的0x32000000,选择菜单4,烧写到nandflash的第0分区,写完断电,从开发板端拔掉MutliIce,重新上电,bootloader烧写成功。 这里需注意,断电后拔掉mutliICE,要从开发板端拔掉,mutliICE用jtag下载,jtag的优先级最高。 3. Linux kernel 移植 Linux kernel 下也需要修改nandflash分区表,对于S3C24XX CPU,NANDFLASH这样的平台设备设置在arch/arm/plat-s3c24xx/common-smdk.c里,打开common-smdk.c修改相应分区为: static struct mtd_partition smdk_default_nand_part = { .name = "boot", .offset = 0x00000000, .size = 0x00030000, }, = { .name = "kernel", .offset = 0x00030000, .size = 0x001d0000, }, = { .name = "rootfs", .offset = 0x00c00000, .size = 0x01e00000, } }; 配置linux kernel S3c2440的配置完全继承s3c2410,可以用$ make s3c2410_defconfig来配置。或者 $ cp arch/arm/configs/s3c2410_defconfig ./.config ,重新配置可以用 $ make menuconfig 修改boot options (root=/dev/mtdblock2 ro noinitrd init=/linuxrc console=ttySAC0,115200 rootfstype=cramfs mem=64m 其他可保持默认配置。 这里遇到的一些问题: a ,问题: FAT: unable to read boot sector VFS: Cannot open root device "mtdblock2" or unknown-block(31,2) Please append a correct "root=" boot option; here are the available 内核代码ECC校验和nandflash里都用hw_ecc 修改nand Flash的校验方式, ECC_HW校验。 在drivers/mtd/nand/s3c2410.c 第669行 将chip-ecc.mode = NAND_ECC_SOFT; 改为 chip-ecc.mode = NAND_ECC_HW; 在内核配置中添加: Device Drivers --- * Memory Technology Device (MTD) support ---- *NAND DECIVE SUPPORT --- S3C2410 NAND Hardware ECC //这个要勾上 在2440中要添加NAND_ECC_HW硬件支持才行。 b , /linuxrc linux启动后自动加载设置,在/linuxrc里添加 /bin/insmod /usr/usbfor2440.ko /bin/mknod ..... /bin/mount .... /etc/profile 设置export一些路径,设置usrname /etc/inittab 设置系统启动首先执行的一些命令,设置shell环境,重启关机命令 /etc/init.d/rcSd定义hostname,在/etc/inittab 中调用首先执行/.bashrc c , 问题: clk: version magic '2.6.12-h1940 ARMv4 gcc-3.4' should be '2.6.29.6 mod_unlo 添加了usrname和hostname就没了。 d , 问题 Failed to execute /linuxrc. Attempting defaults... Kernel panic - not syncing: No init found. Try passing init= option to kernel. busybox的动态链接库没拷到/lib下 e , 问题 FATAL: kernel too old Kernel panic - not syncing: Attempted to kill init! 交叉编译版本高,其动态库有最低版本限制。 4. cramfs文件系统移植 安装busybox: $ cd /work/arm $ cp –rf /home/yoyo/vmshare/busybox-1.00-pre10.tar.bz2 . / $ bzip2 -d–xzf busybox-1.00-pre10.tar.bz2 $ tar -xvf busybox-1.00-pre10.tar $ make menuconfig a ,执行make menuconfig,然后进行设置,这里借助网上的一片博文: http://blog.chinaunix.net/uid-20734916-id-1882739.html ,这几张图就是在进行配置时需要重点注意的地方: (1)在General Configuration中,一定要选择“Support for devfs”选项,现在的Busybox新版本去掉了这个选项,不过应该可以通过修改配置文件加入。 (2)在Build Options选项中,选择使用“静态库”以及设置交叉编译工具的PREFIX。 (3)在Linux System Utilities选项中,“Support loopback mounts”和“Support for the old /etc/mtab file”2个选项应该选中。 (4)在Init Utilities选项中,“Support reading an inittab file”应该选中,这样可以根据自己编写的inittab文件初始化;“Support running commands with a controlling-tty”应该选中,否则会提示非常困扰的“/bin/sh: can't access tty; job control turned off”的提示,尽管可以进入控制台命令行。 (4)在Shell选项中,应该选中默认shell:ash,否则不会生成sh,导致不能解释脚本文件。 (5)其他的选项根据自己的需要设置。 b , 配置完成后,退出保存(最好备份.config文件以供后用),然后开始生成,执行make TARGET_ARCH=arm;此处的TARGET_ARCH是必须的。生成完成后使用qemu-arm测试:qemu-arm ./busybox ls,如果没有错误的话,会显示出 当前目录下的文件列表。 说明:在生成的过程中,提示了“/mnt/extdisk/embedded/busybox-1.1.3/include/bbconfigopts.h:28 hmm, untermina”错误,分析相应的文件,发现应该是一个配置包含文件,在配置后保存在.config文件中,因此这个文件中的内容应该不是关键内容,因此我将此文件清空保存,然后重新执行上面的生成命令,成功。 c , 生成结束后,执行make install,生成一个_install文件夹,内有一个linuxrc文件和bin、sbin、usr三个文件夹,删除linuxrc,将三个文件夹打包。 d , 准备生成cramfs文件系统: (1)创建一个文件夹,比如rootfs,转到rootfs,执行命令mkdir bin dev etc home lib mnt proc sbin sys tmp var usr,建立相应的文件夹,再建立etc下的init.d文件夹。 (2)准备启动所需的文件:linuxrc、rcS、inittab、fstab四个文件; linuxrc文件: ---------------------------------- #!/bin/sh echo "mount /etc as ramfs" /bin/mount -f -t cramfs -o remount,ro /dev/bon/2 / /bin/mount -t ramfs ramfs /var /bin/mkdir -p /var/tmp /bin/mkdir -p /var/run /bin/mkdir -p /var/log /bin/mkdir -p /var/lock /bin/mkdir -p /var/empty #/bin/mount -t usbdevfs none /proc/bus/usb exec /sbin/init ---------------------------------- Linuxrc文件,内核加载后执行的第一个文件,设置内核执行的初始化进程,/bin/mount -t ramfs ramfs /var这句话的作用加载一个ramfs作为/var目录。Ramfs是一个存在于内存中的文件系统,当重启系统后内存上保留的信息就会被擦除。这样/var就被挂载为ramfs文件系统。这样/var就是一个可写目录。cramfs根文件系统,是一个只读文件系统中,这样/var可保存临时文件, linuxrc第一件事情就是将一个ramfs mount 到/var只读目录中,使得/var/*可写。 exec /sbin/init执行根文件系统中的init执行程序,使其成为1号进程。shell正式运行。 rcS文件:(/etc/init.d目录下),在/etc/inittab 脚本中被调用。 ----------------------------------------------------------------------------------- #!/bin/sh /bin/mount –a #挂载/etc/fstab中指定要挂载的文件系统 ----------------------------------------------------------------------------------- 这两个文件生成后,应该使其具有执行的权限,可使用chmod 775 linuxrc rcS来修改,linuxrc应该放在rootfs根目录,rcS应该放在rootfs/etc/init.d/目录。 inittab文件:(/etc目录下),用于控制init进程。 --------------------------------- # This is run first except when booting 系统启动后最先执行 ::sysinit:/etc/init.d/rcS#表示rcS只执行一次,而且init进程等待它结束才继续执行其他#动作 # Start an "askfirst" shell on the console #::askfirst:-/bin/bash ::askfirst:-/bin/sh #“-”表示这个程序是交互的,init进程先输出” 等用户输入回车后才启动子程序。 # Stuff to do when restarting the init process ::restart:/sbin/init #先重新读取、解析/etc/inittab文件,再执行restart程序 ::once:/usr/etc/rc.local #once表示只执行一次,init进程不等它结束 # Stuff to do before rebooting ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ----------------------------------- fstab文件:(/etc目录下),用于指定要挂载的文件系统,在rcS中被调用。 ----------------------------------- none /proc proc defaults 0 0 none /dev/pts devpts mode=0622 0 0 tmpfs /dev/shm tmpfs defaults 0 0 proc 文件系统表示 process information pseudo文件系统,内核用它来提供系统状态信息。 tmpfs是一种虚拟内存文件系统 devpts 文件系统是一个支持Unix98 PTYs的虚拟伪终端文件系统,/dev/pts,即伪终端,逻辑上的终端设备,多用于模拟终端设备。/pts目录下,系统会根据需要自动生成1、2、3等设备文件,这些设备文件是临时的。 -------------------------------- Inittab和fstab这两个文件应该放在rootfs/etc/目录,应该注意其权限问题。 (3)如果使用linux 2.6.xx内核,应该实现创建节点console、null。转到rootfs/dev/目录来创建: sudo mknod console c 5 1 sudo mknod null c 1 3 否则就会提示“Warning: unable to open an initial console. Kernel panic - not syncing: Attempted to kill init!”的类似错误。 (4)将刚才在busybox的_install下的三个文件夹的打包文件复制到rootfs目录,解压后删除打包文件。 (5)也可以将一些常用的lib文件复制到rootfs/lib/目录下,比如:ld-2.5.so libc-2.5.so libcrypt.so.1 libgcc_s.so.1 libm.so.6 ld-linux.so.3 libcrypt-2.5.so libc.so.6 libm-2.5.so等文件或符号连接,在复制时应该注意采用图形化的界面复制活打包后解包方式复制。 (6)转到rootfs的上一级目录,使用mkcramfs制作文件系统:./mkcramfs rootfs xxxxx.cramfs,然后下载、少录、启动,成功启动。 遇到的问题; 编译busybox1.00pe10 mconf.c:477: warning: ignoring return value of 'write', declared with attribute warn_unused_result 解决办法: $ gedit scripts/config/mconf.c static char filename = ".config"; static int indent = 0; static struct termios ios_org; static int rows, cols; //static struct menu *current_menu; //将此行注释即可 static int child_count; static int single_menu_mode; 5. 总结 (a), 本版搭配,这里搭配如下 Linux kernel:Linux2.6.29.6 gcc : arm-linux-gcc 3.4.1 busybox: busybox-1.00-pre10 由于在移植xilinx zynq时用到linux3.10.1,arm-linux-gcc-4.4.3.tar.gz,busybox-1.20.2.tar开始想直接用这两个arm-linux-gcc-4.4.3.tar.gz,busybox-1.20.2.tar搭配Linux2.6.29.6,结果提示FATAL: kernel too old Kernel panic - not syncing: Attempted to kill init! gcc对内核有最低版本限制,用file查看gcc目录下的lib库文件可知。以后有时间,再试试linux3.10.1,arm-linux-gcc-4.4.3.tar.gz,busybox-1.20.2.tar这个组合。 (b)file system启动/linuxrc文件 这个文件是启动文件系统的关键,可以用busybox生成的,也可以自己配置,暂时参考上边网上写的,由于对内核启动后一些系统配置不清楚,这个地方还有很多不理解的。Cramfs是只读文件系统,需要挂在ram才能读写,由于flash有坏块,容量不够,以后有时间,把坏块前边的空间分出来试试。