嵌入式 linux 根文件系統(tǒng)原理和制作方法
[導(dǎo)讀]關(guān)注、星標(biāo)嵌入式云IOT技術(shù)圈,精彩及時(shí)送達(dá)來源|Github-EmbeddedSystem1.根文件系統(tǒng)原理1.1為什么需要根文件系統(tǒng)init進(jìn)程的應(yīng)用程序在根文件系統(tǒng)上根文件系統(tǒng)提供了根目錄/內(nèi)核啟動(dòng)后的應(yīng)用層配置(etc目錄)在根文件系統(tǒng)上。幾乎可以認(rèn)為:發(fā)行版=內(nèi)核roo...
關(guān)注、星標(biāo)嵌入式云IOT技術(shù)圈,精彩及時(shí)送達(dá)
來源 | Github-EmbeddedSystem
1. 根文件系統(tǒng)原理
1.1 為什么需要根文件系統(tǒng)
- init進(jìn)程的應(yīng)用程序在根文件系統(tǒng)上
- 根文件系統(tǒng)提供了根目錄 /
- 內(nèi)核啟動(dòng)后的應(yīng)用層配置( etc 目錄)在根文件系統(tǒng)上。幾乎可以認(rèn)為:發(fā)行版=內(nèi)核 rootfs
- shell命令程序在根文件系統(tǒng)上,比如 ls、cd 等命令
1.2 根文件系統(tǒng)的實(shí)質(zhì)
- 根文件系統(tǒng)是特殊用途的文件系統(tǒng)。
- 根文件系統(tǒng)也必須屬于某種文件系統(tǒng)格式。rootfstype=
1.3 根文件系統(tǒng)的形式
- 使用專用工具軟件制作的可供燒錄的鏡像文件
- 鏡像中包含了根文件系統(tǒng)中的所有文件
- 燒錄此鏡像類似于對(duì)相應(yīng)分區(qū)格式化。
- 鏡像文件系統(tǒng)具有一定的格式,格式是內(nèi)化的,跟文件名后綴是無關(guān)的。
- 根文件系統(tǒng)其實(shí)就是一個(gè)包含特定內(nèi)容的文件夾
- 根文件系統(tǒng)可由任何一個(gè)空文件夾添加必要文件構(gòu)成而成
- 根文件系統(tǒng)的雛形就是在開發(fā)主機(jī)中構(gòu)造的文件夾形式的
1.4 自己制作簡(jiǎn)單的根文件系統(tǒng)
1.4.1 動(dòng)手制作ext3格式的根文件系統(tǒng)
- mke2fs介紹
- 創(chuàng)建rootfs.ext2文件并且將之掛載到一個(gè)目錄下方便訪問它 《參考資料:http://blog.csdn.net/zhengmeifu/article/details/24174513》
dd?if=/dev/zero?of=rootfs.ext2?bs=1024?count=2048
losetup??/dev/loop1?rootfs.ext2
mke2fs?-m?0?/dev/loop1?2048
mount?-t?ext2?/dev/loop1?./rootfs/
- 我們向鏡像中寫入一個(gè)普通文件linuxrc。這個(gè)文件就會(huì)成為我們制作的鏡像中的/linuxrc。內(nèi)核掛載了這個(gè)鏡像后就會(huì)嘗試去執(zhí)行/linuxrc。然后執(zhí)行時(shí)必然會(huì)失敗。我們將來實(shí)驗(yàn)看到的現(xiàn)象就應(yīng)該是:掛載成功,執(zhí)行/linuxrc失敗。
- 將來真正去做有用的rootfs時(shí),就要在這一步添加真正可以執(zhí)行的 linuxrc 程序,然后還要添加別的 /lib 目錄下的庫文件,/etc目錄下的配置文件等。
- 卸載掉,然后鏡像就做好了。
umount?/dev/loop1
losetup?-d?/dev/loop1
1.4.2 nfs 方式啟動(dòng) rootfs
- 什么是 nfs?
- 搭建nfs服務(wù)器
- 總結(jié)
- uboot 中的啟動(dòng)參數(shù)設(shè)置
setenv?bootargs?root=/dev/nfs?nfsroot=192.168.1.104:/home/SummerGift/work/samsung_kernel/rootfs/rootfs?ip=192.168.1.88:192.168.1.104:192.168.1.1:255.255.255.0::eth0:off??init=/linuxrc?console=ttySAC2,115200?
- 測(cè)試 nfs 掛載
mount?-t?nfs?-o?nolock?192.168.1.104:/home/SummerGift/work/samsung_kernel/rootfs/rootfs??/opt
1.4.3 關(guān)于 linuxrc
- /linuxrc 是一個(gè)可執(zhí)行的應(yīng)用程序 /linuxrc 是應(yīng)用層的,和內(nèi)核源碼一點(diǎn)關(guān)系都沒有,/linuxrc 在開發(fā)板當(dāng)前內(nèi)核系統(tǒng)下是可執(zhí)行的。因此在 ARM SoC 的 linux 系統(tǒng)下,這個(gè)應(yīng)用程序就是用 arm-linux-gcc 編譯鏈接的;如果是在 PC 機(jī) linux 系統(tǒng)下,那么這個(gè)程序就是用 gcc 編譯連接的。
- /linuxrc執(zhí)行時(shí)引出用戶界面 操作系統(tǒng)啟動(dòng)后在一系列的自己運(yùn)行配置之后,最終會(huì)給用戶一個(gè)操作界面(也許是 cmdline,也許是 GUI),這個(gè)用戶操作界面就是由 /linuxrc 帶出來的。
- /linuxrc 負(fù)責(zé)系統(tǒng)啟動(dòng)后的配置 就好像一個(gè)房子建好之后不能直接住,還要裝修一樣;操作系統(tǒng)啟動(dòng)起來后也不能直接用,要配置下。操作系統(tǒng)啟動(dòng)后的應(yīng)用層的配置(一般叫運(yùn)行時(shí)配置,英文簡(jiǎn)寫 etc)是為了讓我們的操作系統(tǒng)用起來更方便,更適合我個(gè)人的愛好或者實(shí)用性。
- /linuxrc在嵌入式linux中一般就是busybox busybox 是一個(gè) C 語言寫出來的項(xiàng)目,里面包含了很多 .c 文件和 .h 文件。這個(gè)項(xiàng)目可以被配置編譯成各個(gè)平臺(tái)下面可以運(yùn)行的應(yīng)用程序。我們?nèi)绻?arm-linux-gcc 來編譯busybox就會(huì)得到一個(gè)可以在我們開發(fā)板 linux 內(nèi)核上運(yùn)行的應(yīng)用程序。
1.4.4 rootfs 中的其他目錄
- /linuxrc
- dev目錄下的設(shè)備文件
- sys和proc目錄
- usr是系統(tǒng)的用戶所有的一些文件的存放地,這個(gè)東西將來 busybox 安裝時(shí)會(huì)自動(dòng)生成。
- etc 目錄中的所有文件全部都是運(yùn)行時(shí)配置文件。/etc 目錄下的所有配置文件會(huì)直接或者間接的被 /linuxrc 所調(diào)用執(zhí)行,完成操作系統(tǒng)的運(yùn)行時(shí)配置。etc 目錄是制作 rootfs 的關(guān)鍵,所以后面下一個(gè)課程專門講這個(gè) etc 目錄。
- lib 目錄也是 rootfs 中很關(guān)鍵的一個(gè),不能省略的一個(gè)。lib目錄下放的是當(dāng)前操作系統(tǒng)中的動(dòng)態(tài)和靜態(tài)鏈接庫文件。我們主要是為了其中的動(dòng)態(tài)鏈接庫。
2. 用 busybox 制作一個(gè)簡(jiǎn)單的 rootfs
2.1 移植 busybox 到開發(fā)板
- busybox源碼下載
- 修改Makefile
ARCH?=?arm
CROSS_COMPILE?=?/usr/local/arm/arm-2009q3/bin//arm-none-linux-gnueabi-
- make menuconfig 進(jìn)行配置
Busybox?Settings--->
?Build?Options--->
??[*]Build?BusyBox?as?a?static?binary(no?shared?libs)
Busybox?Library?Tuning--->
?[*]vi-style?line?editing?commands
?[*]Fancy?shell?prompts
Linux?Module?Utilities--->
?[?]Simplified?modutils
?[*]insmod
?[*]rmmod
?[*]lsmod
?[*]modprobe
?[*]depmod
Linux?System?Utilities--->[*]mdev
?[*]Support?/etc/mdev.conf
?[*]Support?subdirs/symlinks
?[*]Support?regular?expressions?substitutions?when?renaming?dev
?[*]Support?command?execution?at?device?addition/removal
?[*]Support?loading?of?firmwares
- make 然后 make install
- 設(shè)置 bootargs 掛載添加了busybox移植的rootfs
setenv?bootargs?root=/dev/nfs?nfsroot=192.168.1.141:/root/porting_x210/rootfs?ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off??init=/linuxrc?console=ttySAC2,115200?
掛載成功,執(zhí)行 /linuxrc(也就是busybox)成功,但是因?yàn)檎也坏?/etc/init.d/rcS 和 /dev/tty2 等文件所以一直在打印錯(cuò)誤提示信息,但是其實(shí)有進(jìn)入命令行。2.2 inittab 詳解
- 添加一個(gè)典型的inittab
- inittab格式解析
- 常見的配置項(xiàng)
3. busybox 源碼分析
3.1 分析 busybox 啟動(dòng)狀況
分析一個(gè)程序,不管多龐大還是小,最好的路線都是按照程序運(yùn)行時(shí)的邏輯順序來。所以找到一個(gè)程序的入口至關(guān)重要。主函數(shù)main函數(shù)就是整個(gè)程序的入口,這種情況適應(yīng)于操作系統(tǒng)下工作的應(yīng)用程序的情況。在 uboot 和 linux kernel 這兩個(gè)大的 C 語言的項(xiàng)目中,main函數(shù)都沒有,都不是入口。在我們這種裸機(jī)程序中入口不是 main 函數(shù),而是由連接腳本來指定的。busybox 是 linux 啟動(dòng)起來后工作的一個(gè)應(yīng)用程序,因此其中必然有 main 函數(shù),而且 main 就是入口。3.2 busybox 中 main 函數(shù)全解析
busybox 入口就是 main 函數(shù),其中有很多個(gè) main 但是只有一個(gè)起作用了,其他的是沒起作用的。真正的busybox工作時(shí)的入口是 libbb/appletlib.c 中的 main 函數(shù)。busybox中有很多 xxx_main 函數(shù),這些 main 函數(shù)每一個(gè)都是 busybox 支持的一個(gè)命令的真正入口。例如 ls_main 函數(shù)就是 busybox 當(dāng)作 ls 函數(shù)使用時(shí)的入口程序。ls 或者 cd 等命令其實(shí)都是 busybox 一個(gè)程序,但是實(shí)際執(zhí)行時(shí)的效果卻是各自的效果。busybox 每次執(zhí)行時(shí)都是先執(zhí)行其 main,在 main 函數(shù)中識(shí)別(靠 main 函數(shù)的傳參 argv[0] 來識(shí)別)我們真正要執(zhí)行的函數(shù)(譬如ls)然后去調(diào)用相應(yīng)的xxx_main(譬如ls_main)來具體實(shí)現(xiàn)這個(gè)命令。3.3 inittab 解析與執(zhí)行
inittab 的解析是在 busybox/init/init.c/init_main 函數(shù)中。執(zhí)行邏輯是:先通過 parse_inittab 函數(shù)解析 /etc/inittab(解析的重點(diǎn)是將 inittab 中的各個(gè) action 和 process 解析出來),然后后面先直接執(zhí)行 sysinit 和 wait 和 once(注意這里只執(zhí)行一遍),然后在 while(1) 死循環(huán)中去執(zhí)行 respwan 和 askfirst。3.4 busybox 的體積優(yōu)勢(shì)原理
busybox 實(shí)際上就是把 ls、cd、mkdir 等很多個(gè) linux 中常用的 shell 命令集成在一起了。集成在一起后有一個(gè)體積優(yōu)勢(shì):就是 busybox 程序的大小比 busybox 中實(shí)現(xiàn)的那些命令的大小加起來要小很多。busybox 體積變小的原因主要有2個(gè):- 第一個(gè)是 busybox 本身提供的 shell 命令是閹割版的(busybox 中的命令支持的參數(shù)選項(xiàng)比發(fā)行版中要少,譬如ls在發(fā)行版中可以有幾十個(gè) -x,但是在 busybox 中只保留了幾個(gè)常用的選項(xiàng),不常用的都刪除掉了)
- 第二個(gè)是 busybox 中因?yàn)樗械拿畹膶?shí)現(xiàn)代碼都在一個(gè)程序中實(shí)現(xiàn),而各個(gè)命令中有很多代碼函數(shù)都是通用的(譬如 ls 和 cd、mkdir 等命令都會(huì)需要去操作目錄,因此在 busybox 中實(shí)現(xiàn)目錄操作的函數(shù)就可以被這些命令共用),共用會(huì)降低重復(fù)代碼出現(xiàn)的次數(shù),從而減少總的代碼量和體積。
4. rcS 文件分析與實(shí)戰(zhàn)
4.1 rcS 文件介紹
/etc/init.d/rcS 文件是linux的運(yùn)行時(shí)配置文件中最重要的一個(gè),其他的一些配置都是由這個(gè)文件引出來的。這個(gè)文件可以很復(fù)雜也可以很簡(jiǎn)單,里面可以有很多的配置項(xiàng)。- PATH=xxx
- rcS 中為什么要先導(dǎo)出 PATH?
- runlevel=
- umask=
- mount -a
- mdev
- hostname
- ifconfig
4.2 rcS 文件測(cè)試問題記錄
- PATH





