原创 s3c2440移植Linux2.6.29.6总结

2013-8-26 14:58 3892 19 19 分类: MCU/ 嵌入式 文集: ARM

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[] = {

         [0] = {

                   .name     = "boot",

                   .offset = 0x00000000,

                   .size         = 0x00030000,

         },

         [1] = {

                   .name     = "kernel",

                   .offset = 0x00030000,

                   .size         = 0x001d0000,

         },

         [2] = {

                   .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[PATH_MAX+1] = ".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有坏块,容量不够,以后有时间,把坏块前边的空间分出来试试。

     

  • 文章评论0条评论)

    登录后参与讨论
    我要评论
    0
    19
    关闭 站长推荐上一条 /2 下一条