嵌入式開發通常使用主機-開發板的開發模式,在裸板開發中,我們通常使用串口調試工具傳遞文件,比如windows平台的超級終端,SecuCRT以及Linux平台的ckermit(題外話:ckermit比windows的那兩個快多了)。但在OS的開發環境中,由於程序復雜,規模巨大,串口的低速和易錯就不再適合我們開發了,而在這種環境下,基於網絡的開發環境由於高速和准確受到了大家的青睐。
在有OS的嵌入式系統中,SoC的啟動過程有3個加載。
在開發過程中,由於bootloader通常都具有網絡功能,而linux內核,設備樹dts和文件系統fs都是不斷迭代的,所以我們自然希望通過配置bootloader的網絡功能使其直接通過服務器(開發主機)下載內核並進一步下載設備樹文件(tftp),甚至直接掛接網絡上的文件系統(nfs)。整個開發環境的結構框圖如下:
tftp即tiny ftp,是一種輕型的ftp協議,Ubuntu下可以使用下面這個小腳本安裝並配置。
#!/bin/bash
echo "Please input tftpdir"
read tftpdir
sudo mkdir $tftpdir #創建用於傳輸文件的目錄
sudo chmod 0777 $tftpdir
sudo apt-get install tftp-hpa tftpd-hpa xinetd -y
#sudo vi /etc/default/tftp-hpa
sudo touch /etc/default/tftpd-hpa
sudo chmod 0777 /etc/default/tftpd-hpa
sudo echo "TFTP_USERNAME=\"tftp\"" > /etc/default/tftpd-hpa
sudo echo "TFTP_DIRECTORY=\"$tftpdir\"" >> /etc/default/tftpd-hpa #tftpd-hpa的服務目錄,這個想建立在哪裡都行
sudo echo "TFTP_ADDRESS=\"0.0.0.0:69\"" >> /etc/default/tftpd-hpa #指定開發板地址,需要和主機的ip在同一個網段
sudo echo "TFTP_OPTIONS=\"-l -c -s\"" >> /etc/default/tftpd-hpa #-c是可以上傳文件的參數,-s是指定tftpd-hpa服務目錄,上面已指定
sudo service tftpd-hpa restart
echo -e '\n'
nfs即network filesystem,可以使客戶端直接從服務器掛接文件系統,方便開發板直接訪問我們的程序或文件。nfs的安裝和配置腳本
#!/bin/bash
echo "nfs service"
echo "Please input nfs dir"
read nfsdir
sudo mkdir $nfsdir
sudo apt-get install nfs-kernel-server nfs-common portmap -y
#sudo vi /etc/exports
sudo touch /etc/exports
sudo chmod 0777 /etc/exports
sudo echo "$nfsdir *(rw,sync,no_subtree_check,no_root_squash)" > /etc/exports
sudo service nfs-kernel-server restart
echo -e '\n'
export文件的屬性選項
ro 只讀訪問
rw 讀寫訪問
sync 所有數據在請求時寫入共享
async nfs在寫入數據前可以響應請求
secure nfs通過1024以下的安全TCP/IP端口發送
insecure nfs通過1024以上的端口發送
wdelay 如果多個用戶要寫入nfs目錄,則歸組寫入(默認)
no_wdelay 如果多個用戶要寫入nfs目錄,則立即寫入,當使用async時,無需此設置
hide 在nfs共享目錄中不共享其子目錄
no_hide 共享nfs目錄的子目錄
subtree_check 如果共享/usr/bin之類的子目錄時,強制nfs檢查父目錄的權限(默認)
no_subtree_check 不檢查父目錄權限
all_squash 共享文件的UID和GID映射匿名用戶anonymous,適合公用目錄
no_all_squash 保留共享文件的UID和GID(默認)
root_squash 用戶的所有請求映射成如anonymous用戶一樣的權限(默認)
no_root_squash root用戶具有根目錄的完全管理訪問權限
anonuid=xxx 指定nfs服務器/etc/passwd文件中匿名用戶的UID
anongid=xxx 指定nfs服務器/etc/passwd文件中匿名用戶的GID
安裝完畢可以使用下面的命令測試一下
$sudo mount -t nfs localhost:/home/jiang/nfs /mnt/ #localhost後面接的是nfs共享目錄
$ls /mnt/
1.txt #如果能看到nfs裡面的1.txt就表示掛接成功了,nfs服務器沒有問題
$sudo unmount /mnt/
通過配置uboot讓它在啟動過程中從tftp獲取內核和設備樹,並從在加載內核之後把通過啟動參數將"從nfs掛載根文件系統"傳入內核。這個配置主要是通過uboot內建的"set 變量名 變量值
+save
"設置環境變量的方式進行配置,下面是我采用的uboot的環境變量,下面是我用的環境變量設置:
#pri #即printenv
baudrate=115200
bootargs=root=/dev/nfs nfsroot=192.168.0.50:/nfs rw console=ttySAC2,115200n8 init=/linuxrc ip=192.168.0.55 loglevel=7 clk_ignore_unused
bootcmd=tftp 41000000 uImage;tftp 42000000 exynos4412-origen.dtb;bootm 41000000 - 42000000
bootdelay=4
ethact=dm9000
ethaddr=11:22:33:44:55:66
fileaddr=41000000
filesize=26D213
gatewayip=192.168.2.1
ipaddr=192.168.0.55
netmask=255.255.255.0
serverip=192.168.0.50
stderr=serial
stdin=serial
stdout=serial
baudrate
就是波特率,習慣上就設成115200,根據硬件的不同可以相應的修改
bootargs
啟動參數,這個參數除了uboot要用,啟動內核之後還會傳入內核。
其中,root=/dev/nfs
表示開發板的根文件系統從nfs網絡設備中加載,nfsroot=192.168.0.55:/nfs
表示從網絡中的ip是192.168.0.55的主機中的/nfs目錄加載根文件系統,rw
表示可讀可寫,console=ttySAC2
表示使用的中端,115200
表示波特率,init=/linuxrc
表示啟動的祖先進程的位置,顯然這是給linux內核用的,ip=192.168.0.55
是開發板的ip,需要和主機在同一個網段,loglevel=7
就是登錄等級,這個不設也行,clk_ignore_unused
忽略時鐘
bootcmd
啟動命令,tftp 41000000 uImage
表示從tftp網絡中下載uImage內核鏡像到41000000地址處,tftp 42000000 exynos4412-origen.dtb
表示下載從tftp網絡中下載設備樹文件到42000000地址處,bootm 41000000 - 42000000
表示從41000000啟動內核,我這沒有randisk,用-
代替,不是從41000000到42000000的意思!!!,最後從42000000掛載根文件系統。
注意:多個命令之間用;
分隔,所以為了在設置變量的時候不立即執行,應該寫成set bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-origen.dtb\;bootm 41000000 - 42000000
bootdelay
啟動倒計時的秒數
gatewayip
表示網關
ipaddr
表示開發板的ip
serverip
表示主機的ip
netmask
表示子網掩碼
stderr
,stdin
,stdout
表示標准輸入輸出錯誤設備,基本都填串口serial
搭建開發環境的細節很多,如有纰漏歡迎批評^-^交流