構建基本的嵌入式Linux根檔案系統

來源:互聯網
上載者:User

構建基本的嵌入式Linux根檔案系統

來源: ChinaUnix部落格 日期: 2010.01.13 15:53 (共有0條評論) 我要評論

製作根檔案系統。
編譯busybox之前需要弄懂的幾個概念。
1、Build BusyBox as a static binary (no shared libs)。也就是busybox 是編譯成共用庫的形式還是靜態形式,他們有什麼區別?
  編譯成靜態(這時我們一般不把工具鏈裡的庫拷貝到我們製作的檔案系統系統的lib下面):
那麼產生的/bin/busybox就可以單獨執行,不以來其他的庫,原因是在編譯時間把它運行時需要的庫(如libc)也編譯到該可執行檔/bin/busybox裡了。
          由busybox編譯處理的命令如mount,ls,cat等也可以單獨執行了,原因也是一樣,就是在編譯時間把它運行時需要的庫也編譯到該各自的可執行檔了。
     這樣就產生一個問題,由於每個可執行檔讀包含了庫,這樣就導編譯出來的可執行檔比較大,而且可能每個可執行檔都包含同一個庫(如libc),浪費很大的空間。
  另外比如我想運行一個helloword,用arm-linx-gcc -o helloword helloword.c。把helloword放到一個靜態編譯的busybox裡,是執行不了的。因為arm-linx-gcc -o helloword helloword.c沒人是編譯成動態,而這時沒它運行時需要的庫(libc),是執行不行了的。你是在要執行的話,就加-static編譯成靜態庫的形式arm-linx-gcc -o helloword helloword.c -static,讓它包含了需要的庫。這樣編譯出來的helloword可以執行了。
編譯成共用庫的形式:/bin/busybox是不可以單獨執行的,必須把它需要的庫包含進來,我們需要把工具鏈裡的庫拷貝到我們製作的檔案系統系統的lib下面。這是就可以通過共用該庫了,應用程式(如helloword,cat命令)不必編譯到各自的可執行檔了,節省了空間。
在嵌入式中一般編譯成共用庫的形式。除非你只是進行一些非常簡單的形式。
2、啟動。
當選擇CONFIG_BLK_DEV_INITRD=y。我們把作好的檔案系統放在目錄myrootfs_shared下(目錄下是bin,etc,lib等),再把該檔案夾放在核心時的頂層目錄,編譯時間選上。

  • Initial RAM filesystem and RAM disk (initramfs/initrd) support                                                    │ │  
      │ │                                                (myrootfs_shared) Initramfs source file(s)  
    如果這樣,就可以認為是ramdisk啟動了。
    如果沒選,就根據CONFIG_CMDLINE決定了,CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/rootfs,rsize=1024,wsize=1024 ip=192.168.1.101:192.168.1.100:192.168.1.100:255.255.255.0::usb0:on console=ttyS1,115200 mem=128M init=/init android uart_dma=1"。
    其中root=... , 該參數告訴核心啟動時使用哪個裝置作為根檔案系統。比如可以指定根檔案為hda8:root=/dev/hda8。
    但不管採用何種方式啟動,核心執行的初始化進程名都由init=決定的(核心中啟動的起一個使用者進程是init).如果該項沒有設定,核心會按順序嘗試/etc/init,
    /bin/init,/sbin/init, /bin/sh,如果所有的都沒找到,核心會拋出 kernel panic:的錯誤。
      如init=/linuxrc,那麼執行的第一個進程就是跟目錄下的linuxrc。
    我們編譯好的busybox有bin,sbin目錄和linuxrc檔案。而linuxrc -> bin/busybox,可見勁兒會執行bin/busybox。而busybox最終會執行/etc/init.d/rcS這個shell指令碼。我們一般在rcS完成我們自己想要的工作。
    由次可見,在建檔案系統時,linuxrc這個名字是無所謂的,只需保證第一個運行我們bin/busybox(這樣就可以保證運行rcS這個shell檔案了)。這就需要CMDLINE和建檔案系統時鏈向bin/busybox的檔案同時配合了。
    例如:在CONFIG_CMDLINE裡我們指定了init=/test_init,那麼我們在建檔案系統時,我們這時只需要在檔案系統的根目錄執行ln -s bin/busybox test_init即可。(之前要把編譯busybox產生的bin/busybox拷貝到檔案系統的bin目錄下)
    注意:需要保證test_init,rcS是可以執行的。為了省事,在完成後,我把整個rootfs目錄sudo chmod 777 rootfs -R
    1、1)建立根檔案系統的基本目錄結構。
    我把這個過程做成了shell指令碼(檔案名稱為mkroot)
    #! /bin/sh
        echo "creatint rootfs dir......"
        mkdir rootfs
        cd rootfs
        echo "making dir : bin dev etc lib proc sbin sys usr"
        mkdir bin dev etc lib proc sbin sys usr #必備的8個目錄
        mkdir usr/bin usr/lib usr/sbin lib/modules
    # Don't use mknod ,unless you run this Script as root !
      sudo mknod -m 600 dev/console c 5 1 #必須的裝置
      sudo  mknod -m 666 dev/null c 1 3 #必須的裝置
        echo "making dir : mnt tmp var"
        mkdir mnt tmp var
        chmod 1777 tmp
        mkdir mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp
        mkdir var/lib var/lock var/log var/run var/tmp
        chmod 1777 var/tmp
        echo "making dir : home root boot"
        mkdir home root boot
        echo "done"
    賦予該shell可執行檔許可權。sudo chmod 777 mkroot
    然後執行./mkroot,中間在產生裝置時需要輸入密碼。這樣基本的目錄就有了。
    (2)配置、編譯和安裝Busybox
    最好去官網下,去別的哪裡下可能有時存在編譯不過的情況。我用的是官網下的busybox-1.15.2.tar.bz2。然後修改Makefile.
    把這部分屏蔽(185行左右)
    #SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
    #                 -e s/arm.*/arm/ -e s/sa110/arm/ \
    #                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
    #                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
    下面的2處
    #ARCH        ?= $(SUBARCH)
    #CROSS_COMPILE    ?=
    改成
    ARCH         = arm
    CROSS_COMPILE = arm-linux-
    註:由於我把工具鏈的位置添加到了環境變數裡,故CROSS_COMPILE = arm-linux-,否則要給出完整的路徑。CROSS_COMPILE = /home/mxzh/smartphone/ww21/pxalinux/toolchain/arm-linux-4.1.1/arm-linux-
    # make menuconfig
    Busybox Settings --->
        Build Options --->
            [] Build BusyBox as a static binary (no shared libs) //(1)
        Installation Options --->
  • Don't use /usr               //(2)
    Linux System Utilities --->
  • mdev                             //(3)
  • Support /etc/mdev.conf
  • Support command execution at device addition/removal
    (1) 這個選項是一定要選擇的,這樣才能把busybox編譯成靜態連結的可執行檔,運行時才獨立於其他函數庫.否則必需要其他庫檔案才能運行,在單一個linux核心不能使他正常工作。如果選中就是靜態編譯,如果沒選中,那麼就要拷貝工具鏈裡的庫過來,我們這裡不選中。
    (2) 這個選項也一定要選,否則make install後,busybox將安裝在原系統的/usr下,這將覆蓋掉系統原有的命令.選擇這個選項後,make install後會在busybox目錄下產生一個叫_install的目錄,裡面有busybox和指向他的連結.
    (3) 如果沒有啟動
    udev
    ,造成/dev下沒有裝置檔案。也就是說所有的裝置都沒有掛接進來。最新的busybox已經包含了udev的簡化版本即mdev,且使用非常簡單。 要使用mdev還需要在rootfs中做適當配置。
    同時還要注意把sh命令選上。
    再加一些基本的命令就可以了,其餘大可不選,用到時再說。
    執行make &&make install。
    (3)把工具鏈裡的庫拷貝到檔案系統的lib下
    如果是編譯成靜態,這一步可以不做。
    [email=mxzh@mxzh:~/work_test/mkrootfs/busybox-1.15.2$]mxzh@mxzh:~/work_test/mkrootfs/busybox-1.15.2$[/email]
    /home/mxzh/smartphone/ww21/pxalinux/toolchain/arm-linux-4.1.1/bin/arm-iwmmxt-linux-gnueabi-readelf -d busybox
    這樣就可以查看busybox需要的庫
    Dynamic section at offset 0x3700c contains 24 entries:
      Tag        Type                         Name/Value
    0x00000001 (NEEDED)                     Shared library: [libc.so.6]
    0x0000000c (INIT)                       0xa56c
    0x0000000d (FINI)                       0x33700
    0x00000019 (INIT_ARRAY)                 0x47000
    0x0000001b (INIT_ARRAYSZ)               4 (bytes)
    0x0000001a (FINI_ARRAY)                 0x47004
    0x0000001c (FINI_ARRAYSZ)               4 (bytes)
    0x00000004 (HASH)                       0x80e8
    0x00000005 (STRTAB)                     0x95e8
    0x00000006 (SYMTAB)                     0x8798
    0x0000000a (STRSZ)                      1761 (bytes)
    0x0000000b (SYMENT)                     16 (bytes)
    0x00000015 (DEBUG)                      0x0
    0x00000003 (PLTGOT)                     0x470f4
    0x00000002 (PLTRELSZ)                   1664 (bytes)
    0x00000014 (PLTREL)                     REL
    0x00000017 (JMPREL)                     0x9eec
    0x00000011 (REL)                        0x9eb4
    0x00000012 (RELSZ)                      56 (bytes)
    0x00000013 (RELENT)                     8 (bytes)
    0x6ffffffe (VERNEED)                    0x9e94
    0x6fffffff (VERNEEDNUM)                 1
    0x6ffffff0 (VERSYM)                     0x9cca
    0x00000000 (NULL)                       0x0
    如上,需要libc庫,拷貝庫到檔案系統的lib目錄下。
    $ cd ~/work_test/mkrootfs/rootfs/lib
    $ cp -d /home/mxzh/smartphone/ww21/pxalinux/toolchain/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/lib/ld*  ./
    $ cp /home/mxzh/smartphone/ww21/pxalinux/toolchain/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/lib/libc.so.6  ./
    這樣就可以了。
    (4)添加命令和初始化指令碼
    把編譯busybox的 產生的_install下的bin,sbin目錄拷貝到到檔案系統的跟目錄下。至於linuxrc,可不作拷貝,只是個連結。
    添加 /etc/init.d/rcS 檔案 添加自動執行部分
    #! /bin/sh
    PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/lib:
    runlevel=S
    prevlevel=N
    umask 022
    export PATH runlevel prevlevel
    #
    #Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
    #
    /bin/mount -t proc  none  /proc
    /bin/mount -t tmpfs none  /root
    /bin/mount -t tmpfs none  /tmp
    /bin/mount -t tmpfs none  /var
    /bin/mount -t tmpfs none  /dev
    /bin/mount -t sysfs none  /sys
    /bin/mkdir -p /var/lib
    /bin/mkdir -p /var/run
    /bin/mkdir -p /var/log
    /bin/mknod -m 660 /dev/console c 5 1
    /bin/mknod -m 660 /dev/null    c 1 3
    /bin/mknod -m 666 /dev/ptmx    c 5 2
    /bin/mkdir  /dev/shm
    /bin/mkdir  /dev/pts
    echo  "Starting mdev ..."
    /sbin/mdev -s
    echo /sbin/mdev > /proc/sys/kernel/hotplug
    然後在檔案系統的跟目錄執行ln -s bin/busybox test_init。
    為了保證可執行,sudo chmod 777 rootfs -R
    這樣,整個檔案檔案系統rootfs就做成了。
    可以把1、rootfs作為nfs目錄供小板掛載了,
    2、或者是把rootfs整個目錄拷貝到核心目錄的頂層,配置核心做ramdis檔案系統了。具體配置如下 General setup  --->    
  • Initial RAM filesystem and RAM disk (initramfs/initrd) support                                                    │ │  
      │ │                                                (rootfs) Initramfs source file(s)
    這是,還需要在CMDLINE裡指定init=/test_init,與上面的ln -s bin/busybox test_init對應。
    如果是ln -s bin/busybox linxurc,那麼CMDLINE裡指定init=/linxurc。
    如果是ln -s bin/busybox init,那麼CMDLINE裡指定init=/init。
    具體可參考:
    http://blog.chinaunix.net/u1/34474/showart_485837.html
    http://blog.chinaunix.net/u3/90973/showart_1834111.html
    http://blog.chinaunix.net/u3/100239/showart_2036548.html

    本文來自ChinaUnix部落格,如果查看原文請點:http://blog.chinaunix.net/u2/66024/showart_2147649.html
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.