<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    嵌入式 hi3518平臺uboot引導nfs文件系統

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    首先貼出來我的bootargs的設置(注沒有換行符!!!):

    setenv bootargs noinitrd mem=64M root=/dev/nfs init=/linuxrc rw nfsroot=10.10.2.59:/opt/rootfs/ ip=10.10.1.156:10.10.2.59:10.10.1.1:255.255.255.0:skdkjzz:eth0:off console=ttyAMA0,115200

     

    Linux編譯生成zImage,但是uboot不能識別,uboot只能識別uImage的文件格式,uImage與zImage文件的區別是uImage比zImage多個文件頭,我們現在利用uboot的mkimage工具來生成uImage文件。

     

     

    通常,u-boot為kernel提供一些kernel無法知道的信息,比如ramdisk在RAM中的地址。Kernel也必須為U-boot提供必要的信息,如通過mkimage這個工具(在u-boot代碼的tools目錄中)可以給zImage添加一個header,也就是使得通常編譯的內核zImage添加一個數據頭,把添加頭后的image通常叫uImage,uImage是可以被U-boot直接引導的內核鏡像。那么如何使用mkimage工具而產生uImage的呢?下面將具體介紹mkimage工具的使用:
     
    1.首先進入u-boot目錄下tools文件夾下,查看mkimage的命令參數
    [root@localhost tools]# ./mkimage 
    Usage: ./mkimage -l image
              -l ==> list image header information
           ./mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file

    [:data_file...] image
              -A ==> set architecture to 'arch'   //用于指定CPU類型,比如ARM
              -O ==> set operating system to 'os'  //用于指定操作系統,比如Linux
              -T ==> set image type to 'type'      //用于指定image類型,比如Kernel
              -C ==> set compression type 'comp'   //指定壓縮類型
              -a ==> set load address to 'addr' (hex)  //指定image的載入地址
              -e ==> set entry point to 'ep' (hex)     //內核的入口地址,一般是:image的載入地址+0x40(信息頭的大小)
              -n ==> set image name to 'name'          //image在頭結構中的命名
              -d ==> use image data from 'datafile'    //無頭信息的image文件名
              -x ==> set XIP (execute in place)        //設置執行位置

    -a參數后是內核的運行地址,-e參數后是入口地址。

    1)如果我們沒用mkimage對內核進行處理的話,那直接把內核下載到0x40008000再運行就行,內核會自解壓運行(不過內核運行需要一個tag來傳遞參數,而這個tag建議是由bootloader提供的,在u-boot下默認是由bootm命令建立的)。

    2)如果使用mkimage生成內核鏡像文件的話,會在內核的前頭加上了64byte的信息,供建立tag之用。bootm命令會首先判斷bootm xxxx 這個指定的地址xxxx是否與-a指定的加載地址相同。
    (1)如果不同的話會從這個地址開始提取出這個64byte的頭部,對其進行分析,然后把去掉頭部的內核復制到-a指定的load地址中去運行之
    (2)如果相同的話那就讓其原封不同的放在那,但-e指定的入口地址會推后64byte,以跳過這64byte的頭部。

    執行:./mkimage -A arm -O linux -T kernel -C none -a 40008000 -e 40008040 -n linux-2.6.31 -d zImage uImage

     

    生成文件之后,根據所要選擇啟動的文件系統,設置uboot的參數:

    1、啟動ramdisk文件系統

    setenv bootargs console=ttyAM0,115200 initrd=0x40400000,0x800000 root=/dev/ram0

    setenv bootcmd tftp 0x40008000 uImage;bootm 0x40008000

    setenv serverip 192.167.10.24

    setenv ipaddr 192.167.10.2

    2、啟動nfs文件系統

    x86 Linux主機開啟nfs服務,步驟如下:

     

    1、軟硬件環境

    VMware 7.0.0,Ubuntu 9.04

    2、ubuntu安裝后默認是沒有帶nfs的,使用如下命令安裝:

    我直接進的root帳戶。

    apt-get install nfs-kernel-server

    apt-get install nfs-common 

    3、虛擬機配置選項里網卡使用的是橋接,IP地址為192.168.0.1,和主機的192.168.0.11在同一網段,主機是連到路由器的。

    4、修改配置文件

    在設置配置文件之前,先建立共享目錄/home/lah/nfs,nfs共享目錄。修改nfs配置文件/etc/exports,添加如下一行:

    /home/lah/nfs   *(rw,sync,no_root_squash)

    第一個參數是nfs共享目錄,第二個是你允許的主機IP,這里設置成所有客戶機都可共享該目錄,括號里面的rw表示掛接此目錄的客戶機對該目錄有讀寫的權限,no_root_squash  表示允許掛接此目錄的客戶機享有該主機的root 身份。

    5、啟動NFS服務并測試

    /etc/init.d/portmap start

    /etc/init.d/nfs-kernel-server start

    現在roo_fs目錄下放入一些文件,然后通過nfs掛載mnt目錄測試。

    mount localhost:/home/lah/nfs /mnt

           如果mnt下有/home/lah/nfs目錄下的文件,則證明nfs服務已經配置好了。

     

    將nfs作為根文件系統時,開啟的nfs服務的文件夾不能為空,應該放busybox制作的根文件系統。

     

    uboot設置bootargs命令的方法

    示例:

     

    setenv bootargs console=ttyAM0,115200 noinitrd root=/dev/nfs nfsroot=192.167.10.6:/home/lah/nfs ip=192.167.10.2:192.167.10.6:::forlinux:eth0:

     

     

     

     

     

     

    #setenv bootargs noinitrd console=ttySAC0,115200 init=/linuxrc mem=64M root=/dev/nfs nfsroot=192.168.2.125:/home/hufei/nfsrootip=192.168.2.6:192.168.2.125:192.168.2.125:255.255.255.0:hufei.cublog.cn:eth0:off

     

    initrd, noinitrd:
    當你沒有使用ramdisk啟動系統的時候,你需要使用noinitrd這個參數,但是如果使用了的話,就需要指定initrd=r_addr,size, r_addr表示initrd在內存中的位置,size表示initrd的大小。

     

    console:

    console=tty  使用虛擬串口終端設備 .
    console=ttyS[,options] 使用特定的串口,options可以是這樣的形式bbbbpnx,這里bbbb是指串口的波特率,p是奇偶位(從來沒有看過使用過),n是指的bits。
    console=ttySAC[,options] 同上面。

    看你當前的環境,有時用ttyS,有時用ttySAC,網上有人說,這是跟內核的版本有關,2.4用ttyS,2.6用ttySAC,但實際情況是官方文檔中也是使用ttyS,所以應該是跟內核版本沒有關聯的。可以查看Documentation/serial-console.txt找到相關描述。

     

    init:

    init指定的是內核啟起來后,進入系統中運行的第一個腳本,一般init=/linuxrc, 或者init=/etc/preinit,preinit的內容一般是創建console,null設備節點,運行init程序,掛載一些文件系統等等操作。請注意,很多初學者以為init=/linuxrc是固定寫法,其實不然,/linuxrc指的是/目錄下面的linuxrc腳本,一般是一個連接罷了。如果內核找不到linurc文件,將會依次搜索/sbin/init,/etc/init,/bin/init,/bin/sh.

     

    mem:

    指定內存大小,不是必須的

     

    root:

    用來指定rootfs的位置, 常見的情況有: 
        root=/dev/ram rw   
        root=/dev/ram0 rw
    請注意上面的這兩種設置情況是通用的,我做過測試甚至root=/dev/ram1 rw和root=/dev/ram2 rw也是可以的,網上有人說在某些情況下是不通用的,即必須設置成ram或者ram0,但是目前還沒有遇到,還需要進一步確認,遇到不行的時候可以逐一嘗試。

        root=/dev/mtdx rw
        root=/dev/mtdblockx rw
        root=/dev/mtdblock/x rw
        root=31:0x

    上面的這幾個在一定情況下是通用的,當然這要看你當前的系統是否支持,不過mtd是字符設備,而mtdblock是塊設備,有時候你的挨個的試到底當前的系統支持上面那種情況下,不過root=/dev/mtdblockx rw比較通用。此外,如果直接指定設備名可以的話,那么使用此設備的設備號也是可以的。

    root=/dev/nfs,并非真的設備,而是一個告訴內核經由網絡取得根文件系統的旗標。 
    在文件系統為基于nfs的文件系統的時候使用。當然指定root=/dev/nfs之后,還需要指定nfsroot,

    nfsroot這個參數告訴內核以哪一臺機器,哪個目錄以及哪個網絡文件系統選項作為根文件系統使用。參數的格式如下:

    nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]

    如果指令列上沒有給定 nfsroot 參數,則將使用‘/tftpboot/%s’預設值。其它選項如下:

    <server-ip> --指定網絡文件系統服務端的互聯網地址(IP address)。如果沒有給定此欄位,則使用由 nfsaddrs 變量(見下面)所決定的值。此參數的用途之一是允許使用不同機器作為反向地址解析協議(RARP) 及網絡文件系統服務端。通常你可以不管它(設為空白)。

    <root-dir> -- 服務端上要作為根掛入的目錄名稱。如果字串中有個‘%s’ 符記(token),此符記將代換為客戶端互聯網地址之ASCII表示法。

    <nfs-options> -- 標準的網絡文件系統選項。所有選項都以逗號分開。如果沒有給定此選項欄位則使用下列的預設值:

            port            = as given by server portmap daemon

            rsize           = 1024

            wsize           = 1024

            timeo           = 7

            retrans         = 3

            acregmin        = 3

            acregmax        = 60

            acdirmin        = 30

            acdirmax        = 60

            flags           = hard, nointr, noposix, cto, ac

    參數nfsaddrs設定網絡通訊所需的各種網絡接口地址。如果沒有給定這個參數,則內核核會試著使用反向地址解析協議以及/或是啟動協議(BOOTP)以找出這些參數。其格式如下:

    ip:

    下面是U-boot官方文檔提供的IP參數解析:

    setenv bootargs ${bootargs}

    ip=${ipaddr}:${serverip}:/

    ${gatewayip}:${netmask}:/

    ${hostname:${netdev}:off

     

    注意,上面換行的地方均有空格。其中 192.168.2.6是開發板的IP,192.168.2.125

    是PC端(或虛擬機)的 IP,上面的IP根據自己的實際情況修改,不要弄錯了。

     

    nfsaddrs=<my-ip>:<serv-ip>:<gw-ip>:<netmask>:<name>:<dev>:<auto>

    <my-ip> -- 客戶端的互聯網地址。如果沒設,此地址將由反向地址解析協議(RARP)或啟動協議來決定。使用何種協議端視配置核心時打開的選項以及 參數而定。如果設定此參數,就不會使用反向地址解析協議或啟動協議。

    <serv-ip> -- 網絡文件系統服務端之互聯網地址。如果使用反向地址解析協議來決定客戶端地址并且設定此參數,則只接受從指定之服務端傳來的回應。要使用不同的機器作為反向地址解析與網絡文件系統服務端的話,在此指定你的反向地址解析協議服務端(保持空白)并在 nfsroot 參數(見上述)中指定你的網絡文件系統服務端。如果此項目空白則使用回答反向地址解析協議或啟動協議之服務端的地址。

    <gw-ip> -- 網關(gateway)之互聯網地址,若服務端位於不同的子網絡上時。如果此項目空白則不使用任何網關并假設服務端在本地的(local)網絡上,除非由啟動協議接收到值。

    <netmask> -- 本地網絡界面的網絡掩碼。如果為空白,則網絡掩碼由客戶端的互聯網地址導出,除非由啟動協議接收到值。

    <name> -- 客戶端的名稱。如果空白,則使用客戶端互聯網地址之 ASCII-標記法,或由啟動協議接收的值。

    <dev> -- 要使用的網絡設備名稱。如果為空白,所有設備都會用來發出反向地址解析請求,啟動協議請求由最先找到的設備發出。網絡文件系統使用接收到反向地址解析協議或啟動協議回應的設備。如果你只有一個設備那你可以不管它。

    <auto> -- 用以作為自動配置的方法。如果是 `rarp' 或是 `bootp' 則使用所指示的協議。如果此值為`both' 或空白,若配置核心時有打開這兩種協議則都使用。 `none' 表示不使用自動配置。這種情況下你必須指定前述欄位中所有必要的值。

    此參數可以作為 nfsaddrs 的參數單獨使用(前面沒有任何 `:` 字符),這種情況下會使用自動配置。然而,此種情況不能使用`none'作為值。

     

    ===========================================================================================================================

     

    主機說明:
    主機guest 為虛擬機redhat9: IP: 59.64.155.122  網關 59.64.155.1
    redhat9上已經配置好NFS服務
    也已經配置好TFTP服務
    NFS服務, TFTP服務都已經啟動
    終端采用主機host XP的超級終端

    實驗板說明:
    MPC8349itx開發板: IP: 59.64.155.244  網關 59.64.155.1
    開發板eth0為vsc8201芯片,uboot支持驅動,另一芯片為交換交換芯片vsc7385,單獨模塊驅動。
    U-Boot-1.1.3 ;    Linux kernel-2.6.13
    內核支持NFS分區(即編譯時在File system中選中[*] Root file system on NFS), 以及支持內核IP_PNP(即編譯時在Networking中選中[*] IP: kernel level autoconfiguration)
        File systems  ---> 
            Network File Systems  ---> 
                <*> NFS file system support                        ## 必選
                    [*]   Provide NFSv3 client support             ## 可選
                [*] Root file system on NFS                        ## 必選
        Networking  ---> 
            [*] Networking support 
                Networking options  ---> 
                    [*]   IP: kernel level autoconfiguration       ## 必選

    ***************************************************************************

    A: NFS啟動掛載根文件系統

    主機上操作:
    $ cd /usr/local/mpc8349/
    $ ./ltib --preconfig config/platform/mpc8349itx/defconfig-min-fs -f
        ## 依次進入如下選項選擇(X) NFS only, 根據情況決定是否選擇[ ] read-only root filesystem 
        --- Target Image Generation
            Options  --->
            --- Choose your root filesystem image type 
                 Target image: (ext2.gz ramdisk)  --->         ## 改ramdisk文件系統為NFS
                (X) NFS only 
                [ ] read-only root filesystem
        ## 其他情況參考LTIB使用說明()
        ## 編譯結束后生成的根文件系統是位于當前安裝目錄下的rootfs (/usr/local/mpc8349/small/rootfs)

    $ ln -s /usr/local/mpc8349/small/rootfs  /home/liuby/rootfsln    ## 建立NFS服務目錄軟連接
    $ su - root        ## 切換到root用戶,需要密碼
    # echo "/usr/local/mpc8349/small/rootfs  59.64.155.244(rw,sync,no_root_squash)" > /etc/exports     ## NFS 服務配置
    # service portmap restart
    # service nfs restart
    # exportfs -arv        ## 修改的NFS配置生效(exportfs參數順序不一樣,顯示有所不同,此順序顯示結果明了)
    # exit


    實驗板上操作:
    uboot啟動后按鍵進入uboot命令行環境:
    => cp.b fef50000 40000 20000; go 40004        ## 驅動vsc7385芯片
    => set serverip 59.64.155.122          ## 主機地址
    => set ipaddr 59.64.155.244            ## 實驗板地址
    => set netmask 255.255.255.0
    => set netdev eth0                     ## eth0
    => ping 59.64.155.122                  ## 測試連通
    => set hostname PowerQUICC
    => set kernaddr fe810000            ## flash中內核起始地址
    => set rootpath /usr/local/mpc8349/small/rootfs        ## NFS服務根目錄
    => setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=ttyS0,115200
    => bootm $kernaddr
                ## 如果一切正常,內核啟動后會啟動NFS文件系統作根文件系統。
                ## 測試: 在開發板上創建一個文件,在主機上會看到這個文件生成
    同樣可以簡化操作(測試nfs服務軟連接目錄):
    => cp.b fef50000 40000 20000; go 40004        ## 驅動vsc7385芯片
    => setenv ipaddr 59.64.155.244
    => setenv bootargs root=/dev/nfs rw nfsroot=59.64.155.122:/home/liuby/rootfsln ip=59.64.155.244:59.64.155.122:255.255.255.0 console=ttyS0,115200 
    => bootm fe810000            ## 內核鏡像uImage在FLASH中的存儲地址

    ************************

    實驗中遇到一個問題,就是bootm之后內核啟動,NFS啟動掛載文件系統快完成時出現下面這個錯誤提示
    RPC: sendmsg returned error 101
    nfs: RPC call returned error 101
    后來才發現是文件系統中的啟動腳本在啟動過程中修改了eth0的ip地址,導致連接不上NFS server
    后來再測試又發現試圖掛載非NFS文件系統目錄時也會出現此問題,并且在主機上執行# showmount 命令結果會顯示有ip地址(實驗板ip地址)掛載。即: 在ltib編譯文件系統時選擇ext2.gz ramdisk (非NFS only), 最后使用rootfs目錄,出現同樣的問題。

    還有遇到過一個問題,根本無法掛載文件系統,在啟動時出現下述提示
    Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
     <0>Rebooting in 180 seconds..
    后來發現是 /etc/exports 只有如下一句
     /home/liuby/rootfs  59.64.155.244(rw,sync,no_root_squash)
    而沒有像下面這樣指定根目錄的訪問權限:
     /usr/local/mpc8349/small/rootfs  59.64.155.244(rw,sync,no_root_squash)
    結論: 必須指定NFS文件系統所在目錄或其對應的軟連接做NFS服務根目錄(見下分析)

    在NFS文件系統中編譯busybox時可以不選擇編譯mount命令(不建議如此)

    nfs總結:
    如上 /home/liuby/rootfsln是指向/usr/local/mpc8349/small/rootfs的軟連接
    # echo "/home/liuby/rootfsln 59.64.155.244(rw,sync,no_root_squash)" > /etc/exports
    # exportfs -arv             ## 會彈出下面的提示
    exporting 59.64.155.244:/usr/local/mpc8349/small/rootfs
    可見 /etc/exports 中語句 /home/liuby/rootfsln 59.64.155.244(rw,sync,no_root_squash) 和 /usr/local/mpc8349/small/rootfs  59.64.155.244(rw,sync,no_root_squash) 是等效的.
    故: 如果想用不同的文件系統,可以改變這個軟連接指向新的文件系統,這比復制文件系統或者修改u-boot環境變量方便多了,并且還不用重新配置/etc/exports。
    # echo "/home/liuby/rootfsln 59.64.155.244(rw, sync, no_root_squash)" > /etc/exports
    $ rm -f /home/liuby/rootfsln
    $ ln -s nfs_rootfs_dir_path  /home/liuby/rootfsln            ## 只需要建立和修改這個軟連接即可
    # exportfs -arv            ## 配置生效(必須)
    在uboot環境變量中只需設置一次rootpath=/home/liuby/rootfsln, 每次只需在主機上修改此軟連接的指向,即可
    注意權限
    ***************************************************************************

    B: TFTP下載內核和文件系統鏡像到ram中啟動

    主機上操作:
    在主機上TFTP根目錄為/home/liuby/tftpboot/
    $ mkdir /home/liuby/tftpboot/image_dir
    $ cd /usr/local/mpc8349/small/
    $ ./ltib --preconfig config/platform/mpc8349itx/defconfig-min-fs-modified -f --batch          ## 編譯內核和文件系統鏡像
    $ cp -f rootfs/boot/uImage  rootfs.ext2.gz.uboot  ~/tftpboot/image_dir/        ## 復制內核鏡像和文件系統鏡像到~/tftpboot/image_dir
    $ cd ~/tftpboot/
    $ ln -s image_dir/ bootln


    實驗板上操作:
    => set serverip 59.64.155.122          ## 主機地址
    => set ipaddr 59.64.155.244            ## 實驗板地址
    => set netmask 255.255.255.0 
    => set tftp_path bootln
    => ping $serverip                      ## 測試連通
    => cp.b fef50000 40000 20000; go 40004        ## 驅動vsc7385芯片
    => setenv loadkernaddr 1000000
    => setenv loadramdaddr 1200000
    => tftpboot $loadkernaddr image_dir/uImage    ## 下載內核鏡像到ram
    => tftp $loadramdaddr $tftp_path/rootfs.ext2.gz.uboot    ## 下載文件系統鏡像到ram
    => bootm $loadkernaddr $loadramdaddr    ## 啟動ram中內核和文件系統鏡像

    下載不暢時,用CTRL+C來終止回到提示符


    tftp總結:
    在TFTP服務根目錄下建立目錄存儲鏡像文件,然后創建軟連接指向需要下載的鏡像目錄,這樣可以通過修改連接文件即可,而不用每次修改uboot環境變量了

    ***************************************************************************

    C: TFTP下載內核鏡像到ram,NFS掛載根文件系統(target image: NFS only)

    主機上利用上面操作的結果,不進行配置。
    實驗板上操作:
    => set serverip 59.64.155.122          ## 主機地址
    => set ipaddr 59.64.155.244            ## 實驗板地址
    => set netmask 255.255.255.0 
    => set bootargs root=/dev/nfs rw nfsroot=$serverip:/home/liuby/rootfsln ip=$ipaddr:$serverip:$netmask console=ttyS0,115200 
    => tftp 1000000 bootln/uImage          ## 下載內核鏡像到ram 地址1000000
    => bootm 1000000
                    ## 測試發現內核啟動,NFS掛載成功

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    簡便方法:
    將下面附錄的文件存儲為.txt文件,例如取名mpc8349itx_uboot_env.txt
    用linux命令unix2dos進行轉換,然后打開windows XP 超級終端,啟動實驗板進入uboot命令行環境:
    點擊超級終端界面 "文件"->"屬性",彈出屬性對話框,點擊"設置"->"ASCII碼設置",設置行延遲20ms,字符延遲1ms;然后點擊"發送"->"發送文本文件",選擇"mpc8349itx_uboot_env.txt"發送。
    此操作相當于在uboot命令行輸入uboot環境設置參數
    執行完操作后保存了這些設置,以后每次在uboot啟動時不用再敲入一行行的設置參數.

    在uboot命令行下執行
    => run flashnfsboot
    相當于 A 操作

    在uboot命令行執行
    => run tftpramboot
    相當于執行 B 操作

    在uboot命令行執行
    => run tftpnfsboot
    相當于執行 C 操作

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全