根文件系統(tǒng)
根文件系統(tǒng)的構(gòu)建,是 Linux移植三大組成部分的最后一步,根文件系統(tǒng)構(gòu)建好后,就構(gòu)成了一個(gè)基礎(chǔ)的、可以運(yùn)行的嵌入式 Linux最小系統(tǒng)
1. 根文件系統(tǒng)簡(jiǎn)介
Linux的根文件系統(tǒng)一般也叫做 rootfs,根文件系統(tǒng)更像是一個(gè)文件夾或者叫做目錄,在這個(gè)目錄里面會(huì)有很多的子目錄。 根目錄下和子目錄中會(huì)有很多的文件,這些文件是Linux運(yùn)行所必須的,比如庫(kù)、常用的軟件和命令、設(shè)備文件、配置文件等等
根文件系統(tǒng)的“根”字就說(shuō)明了該文件系統(tǒng)的重要性,它是其他文件系統(tǒng)的根,沒有這個(gè)“根” ,其他文件系統(tǒng)或者軟件就不能工作。 比如常用的 ls、mv、ifconfig 等命令其實(shí)就是一個(gè)個(gè)小軟件,只是這些軟件沒有圖形界面,且需要輸入命令來(lái)運(yùn)行。 這些小軟件就保存在根文件系統(tǒng)中
在構(gòu)建根文件系統(tǒng)之前,先來(lái)看一下根文件系統(tǒng)里面都有些什么內(nèi)容,根文件系統(tǒng)的目錄名字為‘/’ ,是一個(gè)斜杠。 下面以Ubuntu為例,來(lái)看看根文件系統(tǒng)里都有些什么內(nèi)容
一些常用的子目錄介紹如下表示
/bin :此目錄下存放著系統(tǒng)需要的可執(zhí)行文件,一般都是一些命令,比如 ls、mv 等命令
/dev :device的縮寫,此目錄下的文件都是和設(shè)備有關(guān)的。 在Linux下一切皆文件,即使是硬件設(shè)備,也是以文件的形式存在的,比如/dev/ttymxc0就表示串口0
/etc :此目錄下存放著各種配置文件
/lib :library的簡(jiǎn)稱,也就是庫(kù),此目錄下存放著Linux所必須的庫(kù)文件
/mnt :臨時(shí)掛載目錄,一般是空目錄,可在此目錄下創(chuàng)建空的子目錄,比如/mnt/sd、/mnt/usb,這樣就可以將SD卡或者U盤掛載到/mnt/sd 或者/mnt/usb 目錄中
/proc :此目錄一般是空的,當(dāng)Linux系統(tǒng)啟動(dòng)以后會(huì)將此目錄作為proc文件系統(tǒng)的掛載點(diǎn),proc是個(gè)虛擬文件系統(tǒng),沒有實(shí)際的存儲(chǔ)設(shè)備。 proc里面的文件都是臨時(shí)存在的,一般用來(lái)存儲(chǔ)系統(tǒng)運(yùn)行信息文件
/usr :不是user的縮寫,而是Unix Software Resource的縮寫,即Unix操作系統(tǒng)軟件資源目錄。 此目錄下也存放著很多軟件,一般系統(tǒng)安裝完成以后此目錄占用的空間最多
/var :此目錄存放一些可以改變的數(shù)據(jù)
/sbin :此目錄下存放一些可執(zhí)行文件,但此目錄下的文件或命令只有管理員才能使用,主要用于系統(tǒng)管理
/sys :系統(tǒng)啟動(dòng)以后此目錄作為 sysfs文件系統(tǒng)的掛載點(diǎn),sysfs是一個(gè)類似于 proc文件系統(tǒng)的特殊文件系統(tǒng),sysfs也是基于RAM的文件系統(tǒng),也就是說(shuō)它也沒有實(shí)際的存儲(chǔ)設(shè)備。 此目錄是系統(tǒng)設(shè)備管理的重要目錄
/opt :可選的文件、軟件存放區(qū),由用戶選擇將哪些文件或軟件放到此目錄中
2. BusyBox構(gòu)建根文件系統(tǒng)
2.1 BusyBox簡(jiǎn)介
BusyBox是一個(gè)集成了大量的Linux命令(如ls、mv、ifconfig 等命令)和工具的軟件。 借助BusyBox,進(jìn)行配置和編譯,就可以方便的構(gòu)建一個(gè)嵌入Linux平臺(tái)所需要的根文件系統(tǒng)
可在BusyBox官網(wǎng):https://busybox.net/ 下載源碼,如下圖
左側(cè)的“Get BusyBox”欄有一行“Download Source” ,點(diǎn)擊“Download Source”即可打開 BusyBox 的下載頁(yè)
目前最新版本是1.35.0,本文使用1.29.0版本(busybox-1.29.0.tar.bz2)來(lái)做講解
2.2 編譯BusyBox構(gòu)件根文件系統(tǒng)
一般在Linux驅(qū)動(dòng)開發(fā)的時(shí)候都是通過(guò)NFS掛載根文件系統(tǒng)的,當(dāng)調(diào)試好之后再將根文件系統(tǒng)燒寫到 EMMC或者NAND中,因此需要先在ubuntu虛擬機(jī)中構(gòu)建NFS服務(wù)。 在nfs服務(wù)器目錄中創(chuàng)建名為rootfs的子目錄,用來(lái)存放我們的根文件系統(tǒng)
將busybox-1.29.0.tar.bz2發(fā)送到Ubuntu中的合適位置解壓:
tar -vxjf busybox-1.29.0.tar.bz2
解壓后的文件如下:
修改Makefile添加編譯器
#為了在編譯時(shí),可以不用再指定編譯器的架構(gòu),從而縮短手動(dòng)輸入指令的長(zhǎng)度
CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
......
ARCH ?= arm
# CORSS_COMPILE使用了絕對(duì)路徑!是為了防止編譯出錯(cuò)
busybox中文字符支持:若直接編譯busybox,使用串口工具時(shí)是不支持中文顯示的,會(huì)顯示為“?” ,可修改源碼,取消 busybox對(duì)中文顯示的限制
打開文件busybox-1.29.0/libbb/printable_string.c,將函數(shù)printable_string()中的部分程序注釋掉,修改后的函數(shù)內(nèi)容如下:
/********** printable_string.c代碼段 **********/
constchar* FAST_FUNC printable_string(uni_stat_t*stats,constchar*str)
{
char*dst;
constchar*s;
s = str;
while(1){
......
if(c <' ')
break;
/* 注釋掉下面這個(gè)兩行代碼,禁止字符大于0X7F以后 break */
// if (c >= 0x7f)
// break;
s++;
}
#if ENABLE_UNICODE_SUPPORT
dst =unicode_conv_to_printable(stats, str);
#else
{
char*d = dst =xstrdup(str);
while(1){
unsignedchar c =*d;
if(c =='\\0')
break;
/* 修改下面代碼,禁止字符大于0X7F以后輸出‘?’ */
// if (c < ' ' || c >= 0x7f)
if( c <' ')
*d ='?';
d++;
} ......
}
#endif
returnauto_string(dst);
}
打開文件busybox-1.29.0/libbb/unicode.c,修改如下內(nèi)容:
/********** unicode.c代碼段 **********/
staticchar* FAST_FUNC unicode_conv_to_printable2(uni_stat_t*stats,constchar*src,unsigned width,int flags)
{
char*dst;
unsigned dst_len;
unsigned uni_count;
unsigned uni_width;
if(unicode_status != UNICODE_ON){
char*d;
if(flags & UNI_FLAG_PAD){
d = dst =xmalloc(width +1);
......
/* 修改下面一行代碼 */
// *d++ = (c >= ' ' && c < 0x7f) ? c : '?';
*d++=(c >=' ')? c :'?';
src++;
}
*d ='\\0';
}else{
d = dst =xstrndup(src, width);
while(*d){
unsignedchar c =*d;
/* 修改下面一行代碼 */
// if (c < ' ' || c >= 0x7f)
if(c <' ')
*d ='?';
d++;
}
}
......
return dst;
}
配置busybox:有以下幾種配置選項(xiàng)
- defconfig:缺省配置,也就是默認(rèn)配置選項(xiàng)
- allyesconfi:全選配置,即選中busybox所有功能
- allnoconfig:最小配置
make defconfig #使用默認(rèn)配置
make menuconfig #打開圖形化配置界面
設(shè)置Settings -> Build static binary (no shared libs),用于選擇是靜態(tài)編譯還是動(dòng)態(tài)編譯,靜態(tài)編譯不需要庫(kù)文件,編譯出來(lái)的庫(kù)很大; 動(dòng)態(tài)編譯要求根文件系統(tǒng)中有庫(kù)文件,編譯出來(lái)的 busybox 小很多。 這里不使用靜態(tài)編譯,保持默認(rèn)不選
設(shè)置設(shè)置 -> vi 樣式的行編輯命令
配置Linux Module Utilities -> Simplified modutils(不需選中)
配置Linux System Utilities -> mdev (16 kb)(確保全選)
設(shè)置Settings -> Support Unicode,使能busybox的unicode編碼以支持中文
編譯busybox:配置好busybox以后就可以編譯了,輸入如下命令
make
make install CONFIG_PREFIX=/home/andyxi/linux/nfs/rootfs
#CONFIG_PREFIX指定編譯結(jié)果的存放目錄
編譯完成以后,busybox的所有工具和文件會(huì)被安裝到 rootfs目錄中,如下圖示:rootfs目錄下有bin、sbin和usr三個(gè)目錄,以及l(fā)inuxrc文件。 Linux內(nèi)核 init進(jìn)程會(huì)查找用戶空間的 init程序,找到后就會(huì)運(yùn)行這個(gè)用戶空間的init程序,從而切換到用戶態(tài)。 如果 bootargs設(shè)置 init=/linuxrc,那么 linuxrc就可作為用戶空間的init程序
2.3 向根文件系統(tǒng)添加lib庫(kù)
busybox編譯完成后的根文件系統(tǒng)還不能使用, 還需要一些其他的文件
向rootfs/lib中添加庫(kù)文件:上面 busybox使用的動(dòng)態(tài)庫(kù)編譯,所以還需要向根文件系統(tǒng)中添加動(dòng)態(tài)庫(kù)
先在rootfs中創(chuàng)建一個(gè)名為“l(fā)ib”的文件夾。
lib庫(kù)文件從交叉編譯器中獲取,筆者的交叉編譯器存放在“/usr/local/arm/”目錄中,進(jìn)入交叉編譯器的"libc/lib"目錄:
cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib
此目錄下有很多的so和.a 文件,這些就是庫(kù)文件,將此目錄下所有的so和.a文件都拷貝到 rootfs/lib 目錄中:
cp *so* *.a /home/andyxi/linux/nfs/rootfs/lib/ -d #-d表示拷貝符號(hào)鏈接
### 特殊庫(kù)文件:ld-linux-armhf.so.3(軟連接文件,即快捷方式) 的處理
rm ld-linux-armhf.so.3 #先刪除rootfs/lib中的這個(gè)軟鏈接
# 然后重新拷貝ld-linux-armhf.so.3
cp /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3 .
進(jìn)入交叉編譯器的"lib"目錄,將此目錄下所有的so和.a 庫(kù)文件拷貝到 rootfs/lib 目錄中
cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/lib
cp *so* *.a /home/andyxi/linux/nfs/rootfs/lib/ -d #-d表示拷貝符號(hào)鏈接
向rootfs/usr/lib中添加庫(kù)文件
在rootfs/usr目錄下創(chuàng)建一個(gè)名為lib的目錄。
將交叉編譯器的"libc/usr/lib"目錄中的so和.a 庫(kù)文件拷貝到rootfs/usr/lib目錄中
cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib
cp *so* *.a /home/andyxi/linux/nfs/rootfs/usr/lib/ -d
至此,根文件系統(tǒng)的庫(kù)文件就全部添加好了,可以在rootfs目錄下使用 du 命令來(lái)查看 /lib和 /usr/lib這兩個(gè)目錄的大小:
du ./lib ./usr/lib/ -sh
2.4 創(chuàng)建其他文件夾
在根文件系統(tǒng)中創(chuàng)建其他文件夾,如 dev、proc、mnt、sys、tmp 和 root 等,創(chuàng)建完后的效果:
3. 根文件系統(tǒng)初步測(cè)試
使用NFS掛載的方式來(lái)測(cè)試上面創(chuàng)建好的根文件系統(tǒng)rootfs。 uboot里面的bootargs環(huán)境變量會(huì)設(shè)置root的值,需要將root的值改為NFS掛載,設(shè)置格式如為:
root=/dev/nfs nfsroot=
- server-ip:服務(wù)器IP,存放根文件系統(tǒng)的Ubuntu的IP地址
- root-dir:根文件系統(tǒng)的存放路徑
- nfs-options:NFS的其他可選選項(xiàng),一般不設(shè)置
- client-ip>:客戶端IP,開發(fā)板IP地址,內(nèi)核啟動(dòng)后會(huì)使用此IP地址來(lái)配置開發(fā)板
- gw-ip:網(wǎng)關(guān)地址
- netmask:子網(wǎng)掩碼,255.255.255.0
- hostname:客戶機(jī)的名字,一般不設(shè)置
- device:設(shè)備名,也就是網(wǎng)卡名,一般是 eth0,eth1….
- autoconf:自動(dòng)配置,一般不使用,設(shè)置為 off
- dns0-ip:DNS0服務(wù)器 IP地址,不使用
- dns1-ip:DNS1服務(wù)器 IP地址,不使用
根據(jù)上面的格式bootargs環(huán)境變量的root值如下:
root=/dev/nfs nfsroot=192.168.10.100:/home/andyxi/linux/nfs/rootfs,proto=tcp rw ip=192.168.10.50:192.168.10.100:192.168.10.1:255.255.255.0::eth1:off
啟動(dòng)開發(fā)板,串口連接開發(fā)板,進(jìn)入uboot命令行模式,然后設(shè)置bootargs環(huán)境變量,命令如下:
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.10.100:/home/andyxi/linux/nfs/rootfs,proto=tcp rw ip=192.168.10.50:192.168.10.100:192.168.10.1:255.255.255.0::eth1:off'
saveenv
設(shè)置好以后使用“boot”命令啟動(dòng)Linux內(nèi)核,進(jìn)入根文件系統(tǒng),結(jié)果如下圖示
輸入“l(fā)s”命令進(jìn)行測(cè)試,發(fā)現(xiàn)ls命令正常工作。 但是此時(shí)rootfs并沒有制作成功,注意上圖中的錯(cuò)誤提示:can't run '/etc/init.d/rcS' 這個(gè)文件,說(shuō)明rootfs仍然不夠完善
篇幅所限,關(guān)于 rootfs根文件系統(tǒng)的完善將會(huì)在后續(xù)文章中介紹!
-
Linux
+關(guān)注
關(guān)注
87文章
11123瀏覽量
207891 -
Ubuntu
+關(guān)注
關(guān)注
5文章
552瀏覽量
29294 -
busybox
+關(guān)注
關(guān)注
0文章
21瀏覽量
11243 -
根文件系統(tǒng)
+關(guān)注
關(guān)注
0文章
25瀏覽量
11938 -
rootfs
+關(guān)注
關(guān)注
0文章
19瀏覽量
4644
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論