一、busybox源碼下載及配置linux
https://busybox.net/downloads/shell
1.一、修改Makefileexpress
(1) ARCH = arm
(2) CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin//arm-none-linux-gnueabi-ubuntu
1.二、make menuconfig小程序
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
1.三、make 而後 make installvim
(1)make編譯,若是有錯誤解決之
(2)make install執行的時候實際上是在執行busybox頂層目錄下的一個目標install。
(3)make install在全部的linux下的軟件中做用都是安裝軟件。在傳統的linux系統中安裝軟件時都是選擇源代碼方式安裝的。咱們下載要安裝的軟件源代碼,而後配置、編譯、安裝。make install的目的就是將編譯生成的可執行程序及其依賴的庫文件、配置文件、頭文件安裝到當前系統中指定(通常均可以本身指定安裝到哪一個目錄下,若是不指定通常都有個默認目錄)的目錄下windows
實驗結果:oop
生成文件:bin linuxrc sbin usrpost
掛載成功,執行/linuxrc(也就是busybox)成功,可是由於找不到/etc/init.d/rcS和/dev/tty2等文件因此一直在打印錯誤提示信息,可是其實有進入命令行。測試
二、移植inittab
inittab爲linux初始化文件系統時init初始化程序用到的配置文件。
2.一、添加一個典型的inittab
(1)將我提供的典型的inittab文件複製到咱們製做的rootfs的根目錄下的/etc/目錄下
(2)再次啓動內核掛載這個rootfs看效果
(3)實驗現象是成功啓動而且掛載rootfs進入了控制檯命令行。當前製做的最小rootfs成功了
#first:run the system script file ::sysinit:/etc/init.d/rcS #執行rcS ::askfirst:-/bin/sh #執行命令行 ::ctrlaltdel:-/sbin/reboot #umount all filesystem ::shutdown:/bin/umount -a -r #restart init process ::restart:/sbin/init
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這個程序。」
#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin runlevel=S prevlevel=N umask 022 export PATH runlevel prevlevel mount -a echo /sbin/mdev > /proc/sys/kernel/hotplug mdev -s /bin/hostname -F /etc/sysconfig/HOSTNAME ifconfig eth0 192.168.1.88
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。
runlevel=
(1)runlevel也是一個shell變量,而且被導出爲環境變量。
(2)runlevel這個環境變量到底有什麼用?
(3)runlevel=S表示將系統設置爲單用戶模式
umask=
(1)umask是linux的一個命令,做用是設置linux系統的umask值。
(2)umask值決定當前用戶在建立文件時的默認權限。
mount -a
(1)mount命令是用來掛載文件系統的
(2)mount -a是掛載全部的應該被掛載的文件系統,在busybox中mount -a時busybox會去查找一個文件/etc/fstab文件,這個文件按照必定的格式列出來全部應該被掛載的文件系統(包括了虛擬文件系統)
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的效果和意義。
hostname
(1)hostname是linux中的一個shell命令。命令(hostname xxx)執行後能夠用來設置當前系統的主機名爲xxx,直接hostname不加參數能夠顯示當前系統的主機名。
(2)/bin/hostname -F /etc/sysconfig/HOSTNAME -F來指定了一個主機名配置文件(這個文件通常文件名叫hostname或者HOSTNAME)
ifconfig
(1)有時候咱們但願開機後進入命令行時ip地址就是一個指定的ip地址(譬如192.168.1.30),這時候就能夠在rcS文件中ifconfig eth0 192.168.1.30
3.一、初步一直rcS
一、PATH&runlevel
(1)咱們實戰發現rcS文件明明存在可是卻提示不存在,問題緣由就是rcS文件在windows下建立的,行尾換行符爲'\r\n',多了點東西。可是由於ubuntu中的vi對行尾作了優化,因此在ubuntu中是看不出來多了東西的。可是在securecrt下一看就發現每一行末尾多出來了一個^M。
(2)這個故事告訴咱們:shell腳本文件若是格式不對,運行時可能會被提示文件不存在。
(3)擴展講一個:有時候一個應用程序執行時也會提示文件不存在,問題多是這個程序所調用的一個動態連接庫找不到。
(4)測試結果:PATH原本在busybox中就已經用代碼導出過了,因此rcS中再次導出沒有任何明顯的現象,所以看不出什麼差異;runlevel實際執行結果一直是unknown,問題在於busybox並不支持runlevel這個特性。
3.二、umask測試
(1)umask是022的時候,默認touch建立一個文件的權限是644
(2)umask是044的時候,默認touch建立一個文件的權限是622
(3)umask是444的時候,默認touch建立一個文件的權限是222
總結:umask的規律就是:umask值和默認建立文件的權限值加起來是666.
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文件夾,若是有文件出現則證實掛載成功了,若是沒東西就證實失敗了。
四、profile文件與命令提示符
4.一、profile文件添加
(1)以前添加了/bin/hostname在/etc/sysconfig/HOSTNAME文件中定義了一個hostname(aff),實際效果是:命令行下hostname命令查到的host名字確實是aff。可是問題就是命令行的提示符是沒有顯示的。
(2)這個問題的解決就要靠profile文件。將提供的profile文件放入/etc/目錄下便可。
(3)添加了以後的實驗現象:命令行提示符前面顯示:[@aff ]#
結論是:第一,profile文件起了做用,hostname顯示出來了。第二,還有個問題,登陸用戶名沒顯示出來。緣由就是咱們直接進入了命令行而沒有作登陸。等咱們添加了用戶登陸功能,而且成功登錄後這個問題就能解決。
(4)profile文件工做原理是:profile文件也是被busybox(init進程)自動調用的,因此是認名字的。
# Ash profile # vim: syntax=sh # No core files by default ulimit -S -c 0 > /dev/null 2>&1 USER="`id -un`" LOGNAME=$USER PS1='[\u@\h \W]\# ' PATH=$PATH HOSTNAME=`/bin/hostname` export USER LOGNAME PS1 PATH
4.二、如何看到用戶登陸界面
(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。
4.三、用戶名和密碼的設置
(1)用戶名和密碼的設置是和登陸程序有關聯的,可是/bin/login和/sbin/getty在用戶名和密碼的管理上是同樣的。其實常見的全部的linux系統的用戶名和密碼的管理幾乎都是同樣的。
(2)密碼通常都是用加密文字的,而不是用明文。意思就是系統中的密碼確定是在系統中的一個專門用來存密碼的文件中存儲的,用明文存密碼有風險,所以linux系統都是用密文來存儲密碼的。關於密文密碼的使用下節課實踐時會詳細講。
五、用戶登陸實戰與密碼設置移植
5.一、添加/bin/login到sysinit
(1)在inittab中修改,去掉/bin/sh,換上/bin/login,則系統啓動後出現登陸界面。能夠輸入用戶名和密碼。
(2)實驗現象:成功出現用戶登陸界面,可是死活密碼不對。
5.二、添加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。
5.三、重置密碼實踐
(1)ubuntu剛裝好的時候默認登陸是用普通用戶登陸的,默認root用戶是關閉的。普通用戶的密碼是在裝系統的時候設置的,普通用戶登錄後可使用su passwd root給root用戶設置密碼,設置了密碼後root用戶才能夠登陸。
(2)其實這個緣由就是root用戶在/etc/shadow文件中加密口令是空白的。因此是不能登陸的。
(3)busybox中由於沒有普通用戶,因此作法是:默認root用戶若是加密口令是空的則默認無密碼直接登陸。等咱們登錄了以後仍是能夠用passwd root給root用戶設置密碼。
(4)平時有時候咱們忘記了本身的操做系統的密碼,怎麼辦?有一種解決方法就是用其餘系統(WindowsPE系統或者ubuntu的單用戶模式等···)來引導啓動,啓動後掛載到咱們的硬盤上,而後找到/etc/shadow文件,去掉密文密碼後保存。而後再重啓系統後密碼就沒了。
5.四、getty實戰
(1)你們後面作項目會發現,inittab中最多見的用於登陸的程序不是/bin/login,反而是/sbin/getty。
(2)這兩個的差異不詳,可是在busybox中這兩個是同樣的。這兩個其實都是busybox的符號連接而已。所以不用嚴格區分這兩個
(3)咱們能夠在inittab中用getty替換login程序來實現一樣的效果。
s3c2410_serial2::sysinit:/bin/login
s3c2410_serial2::respawn:/sbin/getty -L s3c2410_serial2 115200 vt100
#first:run the system script file ::sysinit:/etc/init.d/rcS #::askfirst:-/bin/sh #s3c2410_serial2::sysinit:/bin/login s3c2410_serial2::respawn:/sbin/getty -L s3c2410_serial2 115200 vt100 ::ctrlaltdel:-/sbin/reboot #umount all filesystem ::shutdown:/bin/umount -a -r #restart init process ::restart:/sbin/init
到此爲止一個比較完備的根文件系統就作好了
附加:動態連接庫的拷貝
當前的系統因爲缺少必要的C語言庫文件只能執行靜態連接的文件。如要執行動態連接庫的文件須要將經常使用的動態連接庫複製過來。
將arm-linux-gcc的動態連接庫文件複製到開發板rootfs的/lib目錄下便可解決。
附近1:開機自啓動
rcS會在開機時候運行,能夠將須要開機自動執行的文件加入便可開機自啓動。
附近2:前臺運行與後臺運行
(1)程序運行時佔用了當前的控制檯,所以這個程序不結束咱們都沒法使用控制檯,這就叫前臺運行。默認執行程序就是前臺運行的。
(2)後臺運行就是讓這個程序運行,而且同時讓出控制檯。這時候運行的程序還能照常運行並且還可以不影響當前控制檯的使用。
(3)讓一個程序後臺運行的方法就是 ./xxx &
附件3:製做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鏡像。拿去燒錄便可。