1. 程式人生 > >《19.根檔案系統構建實驗及過程詳解》

《19.根檔案系統構建實驗及過程詳解》

《19.根檔案系統構建實驗及過程詳解》

第一部分、章節目錄
2.19.1.根檔案系統的構建路線
2.19.2.busybox的移植實戰
2.19.3.inittab詳解
2.19.4.busybox原始碼分析1
2.19.5.busybox原始碼分析2
2.19.6.rcS檔案介紹1
2.19.7.rcS檔案實戰1
2.19.8.rcS檔案介紹2
2.19.9.profile檔案和使用者登入理論
2.19.10.使用者登入實戰
2.19.11.動態連結庫的拷貝
2.19.12.開機自啟動與主流rcS格式介紹
2.19.13.製作ext2格式的映象並燒錄啟動

第二部分、章節介紹
2.19.1.根檔案系統的構建路線
本節講述我們整個課程從零開始構建一個根檔案系統的路線,是本部分課程的大綱。
2.19.2.busybox的移植實戰
本節我們從零開始移植busybox到資料夾形式的根檔案系統中。
2.19.3.inittab詳解
本節引入並且解析inittab的格式,並且通過新增inittab檔案使我們製作的最小根檔案系統工作起來
2.19.4.busybox原始碼分析1
本節開始解析busybox原始碼,主要分析了busybox中main函式和xxx_main,通過分析從而搞明白busybox的工作原理
2.19.5.busybox原始碼分析2
本節繼續解析busybox原始碼,主要分析了inittab檔案解析部分、通用shell命令如pwd命令的執行部分以及busybox的體積優勢。
2.19.6.rcS檔案介紹1
本節講解/etc/init.d/rcS檔案並且解析其中PATH、runlevel、umask、mount等步驟的具體含義。
2.19.7.rcS檔案實戰1
本節根據上節理論實際新增rcS檔案,並且解決過程中遇到的細節問題,通過實踐現象來印證理論,加深理解。
2.19.8.rcS檔案介紹2
本節繼續解析rcS檔案,主要分析了hostname、ifconfig、mdev等步驟。
2.19.9.profile檔案和使用者登入理論
本節通過新增profile檔案在命令列中顯示hostname,然後講解了使用者登入介面的相關理論。
2.19.10.使用者登入實戰
本節進行使用者登入介面的實戰,通過實際修改inittab檔案來實現使用者登入,並且新增passwd和shadow檔案來管理密碼。
2.19.11.動態連結庫的拷貝
本節首先通過執行靜態編譯連結和動態編譯連結的2個helloworld程式來引出動態連結庫,然後進行實際的庫檔案拷貝工作解決動態連結程式的工作問題。
2.19.12.開機自啟動與主流rcS格式介紹
本節講述如何在rcS檔案中做修改實現開機自啟動和後臺執行,然後介紹了主流產品中rcS檔案的式樣。
2.19.13.製作ext2格式的映象並燒錄啟動
本節將前面做好的資料夾格式的rootfs製作成ext2格式的可燒錄的映象,然後實際燒錄啟動,讓大家體會產品開發的全過程。

第三部分、隨堂記錄
2.19.1.根檔案系統的構建路線
2.19.1.1、課程安排變化。
2.19.1.2、先逐步構建資料夾形式根檔案系統然後製作燒錄映象
(1)rootfs有2種格式:nfs方式啟動的資料夾形式的rootfs和用來燒錄的映象形式的rootfs。
(2)傳統的培訓機構中上課時,rootfs製作實驗都是直接給製作文件,學生參照製作文件的步驟自己動手做,一步到位做出來的就是可供燒錄的rootfs。
(3)我們先從空資料夾開始,逐步向其中新增一些rootfs中必備的東西,然後做一步就用nfs方式去掛載啟動,觀察啟動後的現象,並且理論上去分析原因。
2.19.1.3、動手實踐和理論分析相結合。
2.19.1.4、逐步新增不斷複雜化的rootfs

2.19.2.busybox的移植實戰
2.19.2.1、busybox原始碼下載
(1)busybox是一個開源專案,所以原始碼可以直接從網上下載。
(2)busybox的版本差異不大,版本新舊無所謂。
(3)下載busybox可以去linuxidc等映象網站,也可以去www.busybox.net官方網站下載。

2.19.2.2、修改Makefile
(1) ARCH = arm
(2) CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin//arm-none-linux-gnueabi-

2.19.2.3、make menuconfig進行配置
(1)參照網盤中章節目錄下的《busybox menuconfig配置.txt》檔案中的記錄進行配置。

2.19.2.4、make 然後 make install
(1)make編譯,如果有錯誤解決之
(2)make install執行的時候其實是在執行busybox頂層目錄下的一個目標install。
(3)make install在所有的linux下的軟體中作用都是安裝軟體。在傳統的linux系統中安裝軟體時都是選擇原始碼方式安裝的。我們下載要安裝的軟體原始碼,然後配置、編譯、安裝。make install的目的就是將編譯生成的可執行程式及其依賴的庫檔案、配置檔案、標頭檔案安裝到當前系統中指定(一般都可以自己指定安裝到哪個目錄下,如果不指定一般都有個預設目錄)的目錄下

2.19.2.5、設定bootargs掛載添加了busybox移植的rootfs
(1)之前建立了一個空的資料夾然後自己touch linuxrc隨便建立了一個不能用的/linuxrc然後去nfs掛載rootfs,實驗結果是:掛載成功,執行/linuxrc失敗。
(2)現在我們移植了busybox後/linuxrc就可以用了,然後再次去nfs掛載這個rootfs。預計看到的效果是:掛載成功,執行/linuxrc也能成功。
(3)注意uboot的bootargs設定成: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
(4)實驗結果:掛載成功,執行/linuxrc(也就是busybox)成功,但是因為找不到/etc/init.d/rcS和/dev/tty2等檔案所以一直在列印錯誤提示資訊,但是其實有進入命令列。

2.19.3.inittab詳解
2.19.3.1、新增一個典型的inittab
(1)將我提供的典型的inittab檔案複製到我們製作的rootfs的根目錄下的/etc/目錄下
(2)再次啟動核心掛載這個rootfs看效果
(3)實驗現象是成功啟動並且掛載rootfs進入了控制檯命令列。當前製作的最小rootfs成功了

2.19.3.2、inittab格式解析
(1)inittab的工作原理就是被/linuxrc(也就是busybox)執行時所呼叫起作用。
(2)inittab在/etc目錄下,所以屬於一個執行時配置檔案,是文字格式的(內容是由一系列的遵照一個格式組織的字元組成的),實際工作的時候busybox會(按照一定的格式)解析這個inittab文字檔案,然後根據解析的內容來決定要怎麼工作。
(3)busybox究竟如何完成解析並且解析結果如何去工作(busybox中實現/etc/inittab的原理)並不是我們的目標,我們的重點是inittab的格式究竟怎樣的?我們看到一個inittab後怎麼去分析這個inittab對啟動的影響。
(4)inittab的格式在busybox中定義的,網上可以搜尋到詳細的格式說明,具體去參考即可:
第一個:#開始的行是註釋
第二個:冒號在裡面是分隔符,分隔開各個部分。
第三個:inittab內容是以行為單位的,行與行之間沒有關聯,每行都是一個獨立的配置項,每一個配置項表示一個具體的含義。
第四個:每一行的配置項都是由3個冒號分隔開的4個配置值共同確定的。這四個配置值就是id:runlevels:action:process。值得注意得是有些配置值可以空缺,空缺後冒號不能空缺,所以有時候會看到連續2個冒號。
第五個:每一行的配置項中4個配置值中最重要的是action和process,action是一個條件/狀態,process是一個可被執行的程式的pathname。合起來的意思就是:當滿足action的條件時就會執行process這個程式。

注意:理解inittab的關鍵就是明白“當滿足action的條件時就會執行process這個程式。” 你去分析busybox的原始碼就會發現,busybox最終會進入一個死迴圈,在這個死迴圈中去反覆檢查是否滿足各個action的條件,如果某個action的條件滿足就會去執行對應的process。

第六個:明白各個action什麼意思

2.19.4.busybox原始碼分析1
2.19.4.1、原始碼目錄梳理
2.19.4.2、SourceInsight工程建立
2.19.4.3、整個程式入口確認
(1)分析一個程式,不管多龐大還是小,最好的路線都是按照程式執行時的邏輯順序來。所以找到一個程式的入口至關重要。
(2)學C語言的時候都知道程式的主函式main函式就是整個程式的入口。這種情況適應於作業系統下工作的應用程式的情況。
(3)在uboot和linux kernel這兩個大的C語言的專案中,main函式都沒有,都不是入口。在我們這種裸機程式中入口不是main函式,而是由連線指令碼來指定的。
(4)busybox是linux啟動起來後工作的一個應用程式,因此其中必然有main函式,而且main就是入口。
2.19.4.4、busybox中main函式全解析
(1)busybox入口就是main函式,其中有很多個main但是隻有一個起作用了,其他的是沒起作用的。真正的busybox工作時的入口是libbb/appletlib.c中的main函式
(2)busubox中有很多xxx_main函式,這些main函式每一個都是busybox支援的一個命令的真正入口。譬如ls_main函式就是busybox當作ls函式使用時的入口程式。
(3)ls或者cd等命令其實都是busybox一個程式,但是實際執行時的效果卻是各自的效果。busybox是如何實現一個程式化身萬千還能各自工作的?答案就是main轉xxx_main。也就是說busybox每次執行時都是先執行其main,在main函式中識別(靠main函式的傳參argv[0]來識別)我們真正要執行的函式(譬如ls)然後去呼叫相應的xxx_main(譬如ls_main)來具體實現這個命令。

2.19.5.busybox原始碼分析2
2.19.5.1、inittab解析與執行
(1)inittab的解析是在busybox/init/init.c/init_main函式中
(2)執行邏輯是:先通過parse_inittab函式解析/etc/inittab(解析的重點是將inittab中的各個action和process解析出來),然後後面先直接執行sysinit和wait和once(注意這裡只執行一遍),然後在while(1)死迴圈中去執行respwan和askfirst。

2.19.5.2、pwd命令執行路徑分析
(1)根據上節講的,我們在busybox命令列下執行pwd命令時實際執行的是pwd_main這個函式。

2.19.5.3、busybox的體積優勢原理
(1)busybox實際上就是把ls、cd、mkdir等很多個linux中常用的shell命令整合在一起了。整合在一起後有一個體積優勢:就是busybox程式的大小比busybox中實現的那些命令的大小加起來要小很多。
(2)busybox體系變小的原因主要有2個:第一個是busybox本身提供的shell命令是閹割版的(busybox中的命令支援的引數選項比發行版中要少,譬如ls在發行版中可以有幾十個-x,但是在busybox中只保留了幾個常用的選項,不常用的都刪除掉了);第二個是busybox中因為所有的命令的實現程式碼都在一個程式中實現,而各個命令中有很多程式碼函式都是通用的(譬如ls和cd、mkdir等命令都會需要去操作目錄,因此在busybox中實現目錄操作的函式就可以被這些命令共用),共用會降低重複程式碼出現的次數,從而減少總的程式碼量和體積。
(3)經過分析,busybox的體積優勢是嵌入式系統本身的要求和特點造成的。

2.19.6.rcS檔案介紹1
2.19.6.0、/etc/init.d/rcS檔案是linux的執行時配置檔案中最重要的一個,其他的一些配置都是由這個檔案引出來的。這個檔案可以很複雜也可以很簡單,裡面可以有很多的配置項。
2.19.6.1、PATH=xxx
(1)首先從shell指令碼的語法角度分析,這一行定義了一個變數PATH,值等於後面的字串
(2)後面用export匯出了這個PATH,那麼PATH就變成了一個環境變數。
(3)PATH這個環境變數是linux系統內部定義的一個環境變數,含義是作業系統去執行程式時會預設到PATH指定的各個目錄下去尋找。如果找不到就認定這個程式不存在,如果找到了就去執行它。將一個可執行程式的目錄匯出到PATH,可以讓我們不帶路徑來執行這個程式。
(4)rcS中為什麼要先匯出PATH?就是因為我們希望一旦進入命令列下時,PATH環境變數中就有預設的/bin /sbin /usr/bin /usr/sbin 這幾個常見的可執行程式的路徑,這樣我們進入命令列後就可以ls、cd等直接使用了。
(5)為什麼我們的rcS檔案還沒新增,系統啟動就有了PATH中的值?原因在於busybox自己用程式碼硬編碼為我們匯出了一些環境變數,其中就有PATH。

2.19.6.2、runlevel=
(1)runlevel也是一個shell變數,並且被匯出為環境變數。
(2)runlevel這個環境變數到底有什麼用?
(3)runlevel=S表示將系統設定為單使用者模式

2.19.6.3、umask=
(1)umask是linux的一個命令,作用是設定linux系統的umask值。
(2)umask值決定當前使用者在建立檔案時的預設許可權。

2.19.6.4、mount -a
(1)mount命令是用來掛載檔案系統的
(2)mount -a是掛載所有的應該被掛載的檔案系統,在busybox中mount -a時busybox會去查詢一個檔案/etc/fstab檔案,這個檔案按照一定的格式列出來所有應該被掛載的檔案系統(包括了虛擬檔案系統)

2.19.7.rcS檔案實戰1
2.19.7.1、PATH&runlevel
(1)我們實戰發現rcS檔案明明存在但是卻提示不存在,問題原因就是rcS檔案在windows下建立的,行尾換行符為’\r\n’,多了點東西。但是因為ubuntu中的vi對行尾做了優化,所以在ubuntu中是看不出來多了東西的。但是在securecrt下一看就發現每一行末尾多出來了一個^M。
(2)這個故事告訴我們:shell指令碼檔案如果格式不對,執行時可能會被提示檔案不存在。
(3)擴充套件講一個:有時候一個應用程式執行時也會提示檔案不存在,問題可能是這個程式所呼叫的一個動態連結庫找不到。
(4)測試結果:PATH本來在busybox中就已經用程式碼匯出過了,所以rcS中再次匯出沒有任何明顯的現象,因此看不出什麼差別;runlevel實際執行結果一直是unknown,問題在於busybox並不支援runlevel這個特性。

2.19.7.2、umask測試
(1)umask是022的時候,預設touch建立一個檔案的許可權是644
(2)umask是044的時候,預設touch建立一個檔案的許可權是622
(3)umask是444的時候,預設touch建立一個檔案的許可權是222
總結:umask的規律就是:umask值和預設建立檔案的許可權值加起來是666.

2.19.7.3、mount測試
(1)掛載時全部出錯:
mount: mounting proc on /proc failed: No such file or directory
mount: mounting sysfs on /sys failed: No such file or directory
mount: mounting tmpfs on /var failed: No such file or directory
mount: mounting tmpfs on /tmp failed: No such file or directory
mount: mounting tmpfs on /dev failed: No such file or directory
(2)原因是因為根檔案系統中找不到掛載點。所謂掛載點就是我們要將目標檔案系統(當然這裡都是虛擬檔案系統)掛載到當前檔案系統中的某一個目錄中,這個目錄就是掛載點。
(3)解決方案就是自己在製作的rootfs根目錄下建立這些掛載點目錄即可。
(4)驗證是否掛載成功,可以看掛載時輸出資訊;還可以啟動後去看proc和sys資料夾,如果有檔案出現則證明掛載成功了,如果沒東西就證明失敗了。

2.19.8.rcS檔案介紹2
2.19.8.1、mdev
(1)mdev是udev的嵌入式簡化版本,udev/mdev是用來配合linux驅動工作的一個應用層的軟體,udev/mdev的工作就是配合linux驅動生成相應的/dev目錄下的裝置檔案。
(2)因為這個問題涉及到驅動,因此詳細講解要等到驅動部分。這裡我們只是通過一些直觀的現象來初步理解udev/mdev的工作效果。
(3)在rcS檔案中沒有啟動mdev的時候,/dev目錄下啟動後是空的;在rcS檔案中新增上mdev有關的2行配置項後,再次啟動系統後發現/dev目錄下生成了很多的裝置驅動檔案。
(4)/dev目錄下的裝置驅動檔案就是mdev生成的,這就是mdev的效果和意義。

2.19.8.2、hostname
(1)hostname是linux中的一個shell命令。命令(hostname xxx)執行後可以用來設定當前系統的主機名為xxx,直接hostname不加引數可以顯示當前系統的主機名。
(2)/bin/hostname -F /etc/sysconfig/HOSTNAME -F來指定了一個主機名配置檔案(這個檔案一般檔名叫hostname或者HOSTNAME)

2.19.8.3、ifconfig
(1)有時候我們希望開機後進入命令列時ip地址就是一個指定的ip地址(譬如192.168.1.30),這時候就可以在rcS檔案中ifconfig eth0 192.168.1.30

2.19.9.profile檔案和使用者登入理論
2.19.9.1、profile檔案新增
(1)之前添加了/bin/hostname在/etc/sysconfig/HOSTNAME檔案中定義了一個hostname(aston210),實際效果是:命令列下hostname命令查到的host名字確實是aston210。但是問題就是命令列的提示符是沒有顯示的。
(2)這個問題的解決就要靠profile檔案。將提供的profile檔案放入/etc/目錄下即可。
(3)添加了之後的實驗現象:命令列提示符前面顯示:[@aston210 ]#
結論是:第一,profile檔案起了作用,hostname顯示出來了。第二,還有個問題,登入使用者名稱沒顯示出來。原因就是我們直接進入了命令列而沒有做登入。等我們添加了使用者登入功能,並且成功登陸後這個問題就能解決。
(4)profile檔案工作原理是:profile檔案也是被busybox(init程序)自動呼叫的,所以是認名字的。

2.19.9.2、如何看到使用者登入介面
(1)linux中有一個原則就是用一個小程式來完成一個功能。如果我們產品確實需要很複雜的綜合型的功能,我們傾向於先使用很多個小程式完成其中的一個功能,然後再將這些小程式整合起來完成整個大功能的產品。
(2)這種整合很多個小程式來完成一個大的功能,有很多種技術實現。譬如shell指令碼,還有一些別的技術,譬如linux啟動中的inittab。
(3)因為我們之前intttab中有一個配置項 ::askfirst:-/bin/sh,這個配置項作用就是當系統啟動後就去執行/bin/sh,執行這個就會出現命令列。因此我們這樣的安排就會直接進入命令列而不會出現登入介面。
(4)我們要出現登入介面,就不能直接執行/bin/sh,而應該執行一個負責出現登入介面並且負責管理使用者名稱和密碼的一個程式,busybox中也集成了這個程式(就是/bin/login和/sbin/gettty),因此我們要在inittab中用/bin/login或者/sbin/getty去替代/bin/sh。

2.19.9.3、使用者名稱和密碼的設定
(1)使用者名稱和密碼的設定是和登入程式有關聯的,但是/bin/login和/sbin/getty在使用者名稱和密碼的管理上是一樣的。其實常見的所有的linux系統的使用者名稱和密碼的管理幾乎都是一樣的。
(2)密碼一般都是用加密文字的,而不是用明文。意思就是系統中的密碼肯定是在系統中的一個專門用來存密碼的檔案中儲存的,用明文存密碼有風險,因此linux系統都是用密文來儲存密碼的。關於密文密碼的使用下節課實踐時會詳細講。

2.19.10.使用者登入實戰
2.19.10.1、新增/bin/login到sysinit
(1)在inittab中修改,去掉/bin/sh,換上/bin/login,則系統啟動後出現登入介面。可以輸入使用者名稱和密碼。
(2)實驗現象:成功出現使用者登入介面,但是死活密碼不對。

2.19.10.2、新增passwd和shadow檔案
(1)為什麼使用者名稱和密碼不對?因為我們根本沒有為root使用者設定密碼。
(2)linux系統中用來描述使用者名稱和密碼的檔案是passwd和shadow檔案,這兩個檔案都在etc目錄下。passwd檔案中儲存的是使用者的密碼設定,shadow檔案中儲存的是加密後的密碼。
(3)我們直接複製ubuntu系統中的/etc/passwd和/etc/shadow檔案到當前製作的rootfs目錄下,然後再做修改即可。
(4)/etc/passwd和/etc/shadow修理好後,shadow中預設有一個加密的密碼口令,這個口令和你拷貝的shadow本身有關,像我的ubuntu中root使用者的密碼就是root,因此複製過來後登陸時的密碼還是root。

2.19.10.3、重置密碼實踐
(1)ubuntu剛裝好的時候預設登入是用普通使用者登入的,預設root使用者是關閉的。普通使用者的密碼是在裝系統的時候設定的,普通使用者登陸後可以使用su passwd root給root使用者設定密碼,設定了密碼後root使用者才可以登入。
(2)其實這個原因就是root使用者在/etc/shadow檔案中加密口令是空白的。所以是不能登入的。
(3)busybox中因為沒有普通使用者,所以做法是:預設root使用者如果加密口令是空的則預設無密碼直接登入。等我們登陸了之後還是可以用passwd root給root使用者設定密碼。
(4)平時有時候我們忘記了自己的作業系統的密碼,怎麼辦?有一種解決方法就是用其他系統(WindowsPE系統或者ubuntu的單使用者模式等···)來引導啟動,啟動後掛載到我們的硬碟上,然後找到/etc/shadow檔案,去掉密文密碼後儲存。然後再重啟系統後密碼就沒了。

2.19.10.4、getty實戰
(1)大家後面做專案會發現,inittab中最常見的用於登入的程式不是/bin/login,反而是/sbin/getty。
(2)這兩個的差別不詳,但是在busybox中這兩個是一樣的。這兩個其實都是busybox的符號連結而已。因此不用嚴格區分這兩個
(3)我們可以在inittab中用getty替換login程式來實現同樣的效果。

2.19.11.動態連結庫的拷貝
2.19.11.1、靜態編譯連結helloworld程式並執行
(1)任務:自己寫一個helloworld程式,然後交叉編譯連線,然後丟到開發板根檔案系統中,開機後去執行。
(2)C程式如果使用gcc來編譯則可以在主機ubuntu中執行,但是不能在開發板執行;要在開發板執行需要用arm-linux-gcc來交叉編譯,但是這時候就不能在主機ubuntu中運行了。我們可以用file xx命令來檢視一個elf可執行程式是哪個架構的。
(3)靜態連結:arm-linux-gcc hello.c -o hello_satic -static
(4)實驗結果:靜態編譯連線後生成的hello_satic已經可以成功執行。

2.19.11.2、動態編譯連線helloworld程式並執行
(1)動態連結:arm-linux-gcc hello.c -o hello_dynamic
(2)實驗結果:-sh: ./hello_dynamic: not found執行時提示找不到程式。
(3)錯誤分析:動態連線的hello程式中呼叫到了printf函式,而printf函式在動態連線時要在執行時環境(開發板的rootfs)中去尋找對應的庫檔案(開發板rootfs中部署的動態連結庫中包含了printf函式的那個庫檔案)。如果找到了則printf函式就會被成功解析,然後hello_dynamic程式就會被執行;如果找不到則程式就不能被執行,命令列會提示錯誤資訊-sh: ./hello_dynamic: not found
(4)解決方案:將arm-linux-gcc的動態連結庫檔案複製到開發板rootfs的/lib目錄下即可解決。

2.19.11.3、找到並複製動態連結庫檔案到rootfs中
(1)我們用的arm-2009q3這個交叉編譯工具鏈的動態連結庫在/usr/local/arm/arm-2009q3/arm-none-linux-gnueabi/libc/lib目錄下。其他的一些交叉編譯工具鏈中動態連結庫的目錄不一定在這裡,要去找一下。找的方法就是find
(2)複製動態連結庫到roots/lib目錄下。複製時要注意引數用-rdf,主要目的就是符號連結複製過來還是符號連結。
複製命令:cp lib/so /root/porting_x210/rootfs/rootfs/lib/ -rdf
(3)現在再去測試./hello_dynamic看看是否可以執行,實驗結果是可以執行。

2.19.11.4、使用strip工具去掉庫中符號資訊
動態連結庫so檔案中包含了除錯符號資訊,這些符號資訊在執行時是沒用的(除錯時用的),這些符號會佔用一定空間。在傳統的嵌入式系統中flash空間是有限的,為了節省空間常常把這些符號資訊去掉。這樣節省空間並且不影響執行。
去掉符號命令:arm-linux-strip so
實際操作後發現庫檔案由3.8M變成了3.0M,節省了0.8M的空間。

2.19.12.開機自啟動與主流rcS格式介紹
2.19.12.1、修改rcS實現開機自啟動
(1)開機自啟動指的是讓一些應用程式能夠開機後自動執行
(2)開機自啟動的實現原理就是在開機會自動執行的指令碼rcS中新增上執行某個程式的語句程式碼即可

2.19.12.2、前臺執行與後臺執行
(1)程式執行時佔用了當前的控制檯,因此這個程式不結束我們都無法使用控制檯,這就叫前臺執行。預設執行程式就是前臺執行的。
(2)後臺執行就是讓這個程式執行,並且同時讓出控制檯。這時候執行的程式還能照常執行而且還能夠不影響當前控制檯的使用。
(3)讓一個程式後臺執行的方法就是 ./xxx &

2.19.12.3、開機裝載驅動等其他開機自動執行

2.19.12.4、實際開發中rootfs的rcS是怎樣的
(1)我們以X210開發板九鼎科技做的rootfs中rcS部分來分析
(2)分析inittab發現:sysinit執行rcS,shutdown時執行rcK。
(3)分析/etc/init.d/rcS和rcK檔案發現,rcS和rcK都是去遍歷執行/etc/init.d/目錄下的S開頭的指令碼檔案,區別是rcS傳參是start,rcK傳參是stop。
(4)由此可以分析出來,正式產品中的rcS和rcK都是一個引入,而不是真正幹活的。真正幹活的配置指令碼是/etc/init.d/S??*。這些檔案中肯定有一個判斷引數是start還是stop,然後start時去做一些初始化,stop時做一些清理工作。

2.19.13.製作ext2格式的映象並燒錄啟動
2.19.13.1、確定資料夾格式的rootfs可用
(1)設定bootargs為nfs啟動方式,然後從主機ubuntu中做好的資料夾格式的rootfs去啟動,然後看啟動效果,作為將來的參照物。
2.19.13.2、動手製作ext2格式的映象
(1)
dd if=/dev/zero of=rootfs.ext2 bs=1024 count=10240
losetup /dev/loop1 rootfs.ext2
mke2fs -m 0 /dev/loop1 10240
mount -t ext2 /dev/loop1 ./ext2_rootfs/
(2)向./rootfs中複製內容,用cp …/rootfs/* ./ -rf
(3)umount /dev/loop1
losetup -d /dev/loop1
(4)完成後得到的rootfs.ext2就是我們做好的rootfs映象。拿去燒錄即可。

2.19.13.3、燒錄映象並設定合適的bootargs
(1)使用fastboot燒錄製作好的rootfs.ext2到開發板inand中
fastboot flash system rootfs.ext2
燒錄完成後重啟系統
(2)設定bootargs為:set bootargs console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext2
(3)啟動後發現現象和之前nfs方式啟動掛載rootfs後一樣的,至此rootfs製作實驗圓滿完成。

2.19.13.4、總結
(1)13節課將rootfs的製作步驟和原理已經完全清楚的講完了
(2)製作過程本身如果有文件指導非常容易,非常簡單,但是我們學習時側重於不是rootfs製作本身,而是rootfs工作的原理分析。