日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

使用BusyBox制作根文件系统的理论分析

發布時間:2023/12/20 windows 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用BusyBox制作根文件系统的理论分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以下內容源于朱有鵬嵌入式課程的學習,如有侵權,請告知刪除。




一、inittab文件介紹

#first:run the system script file ::sysinit:/etc/init.d/rcS //sysinit表示控制臺啟動(命令行)之前執行,所以視頻中會打印不能運行rcS,因為剛開始沒有配置該文件 ::askfirst:-/bin/sh //askfirst促使按回車鍵 ::ctrlaltdel:-/sbin/reboot //ctrlaltdel表示按下ctrl和delet鍵,但在scrt中體現不了效果。 #umount all filesystem ::shutdown:/bin/umount -a -r #restart init process ::restart:/sbin/init

(1)inittab的工作原理

  • /linuxrc 執行時調用該文件。

(2)inittab在/etc目錄下

  • 屬于運行時配置文件,是文本格式的(內容由一系列遵照一個格式組織的字符組成);
  • /linuxrc?會按照一定的格式,去解析這個inittab文本文件,然后根據解析的內容來決定要怎么工作。
(3)inittab的格式是怎樣的?inittab對啟動的影響如何體現?
  • 第一個:#開始的行是注釋;
  • 第二個:冒號在里面是分隔符,分隔開各個部分。
  • 第三個:inittab內容是以行為單位的,行與行之間沒有關聯,每行都是一個獨立的配置項,每一個配置項表示一個具體的含義。
  • 第四個:每一行的配置項都是由3個冒號分隔開的4個配置值共同確定的,這四個配置值是id:runlevels:action:process。
  • 第五個:action是一個條件/狀態,process是一個可被執行的程序的pathname,當滿足action的條件時就會執行process這個程序。
  • 第六個:明白各個action的意思。

(4)由busybox的源代碼可知,busybox最終進入一個死循環。

  • 在這個死循環中去反復檢查是否滿足各個action的條件,如果某個action的條件滿足就會去執行對應的process。

(5)當將(使用busybox生成的)sbin/、bin/目錄拷貝到/root/rootfs下,然后創建etc目錄,再在etc/目錄下添加了linuxrc,最小的根文件系統就完成了(可以進入命令行了,但是會提示如下信息:)




二、rcS文件介紹

#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/binrunlevel=S prevlevel=Numask 022export PATH runlevel prevlevelmount -aecho /sbin/mdev > /proc/sys/kernel/hotplug mdev -s/bin/hostname -F /etc/sysconfig/HOSTNAMEifconfig eth0 192.168.1.10

1、/etc/init.d/rcS文件

  • 在開機時,linuxrc會調用此文件。
  • 此文件是linux的運行時配置文件中最重要的一個,其他的一些配置都是由這個文件引出來的。
  • 這個文件可以很復雜也可以很簡單(嵌入式一般不用像ubuntu那么復雜),里面可以有很多的配置項。

2、PATH=xxx

(1)從shell腳本的語法角度分析,該行定義了一個變量PATH,值等于后面的字符串。

(2)用export導出這個PATH,那么PATH就變成一個環境變量。

(3)PATH這個環境變量(環境變量可以有很多個,這里只是PATH這個環境變量)

  • 是linux系統內部定義的一個環境變量;
  • 操作系統去執行程序時會默認到PATH指定的各個目錄下去尋找。
  • 如果找不到就認定這個程序不存在,如果找到了就去執行它。
  • 將一個可執行程序的目錄導出到PATH,可以不帶路徑地執行這個程序。

(4)rcS中為什么要導出PATH?

  • 希望進入命令行后,PATH環境變量中就有默認的/bin /sbin /usr/bin /usr/sbin 這幾個常見的可執行程序的路徑,從而可以直接使用ls、cd等命令。

(5)為什么還沒添加rcS文件,系統啟動就有PATH中的值?

  • 因為busybox用代碼硬編碼為我們導出了一些環境變量,其中就有PATH。

3、runlevel=

(1)runlevel也是一個shell變量,并且被導出為環境變量。

(2)runlevel這個環境變量到底有什么用?類似于window中的啟動模式識別,如安全模式,普通模式。百度。

(3)runlevel=S表示將系統設置為單用戶模式。

4、umask=

(1)umask是linux的一個命令,作用是設置linux系統的umask值。

(2)umask值決定當前用戶在創建文件時的默認權限。

5、mount -a

(1)mount命令是用來掛載文件系統的;

(2)mount -a是掛載所有的應該被掛載的文件系統。

  • 在busybox中mount -a時,busybox會去查找一個文件/etc/fstab文件;
  • 這個文件按照一定的格式列出來所有應該被掛載的文件系統(包括了虛擬文件系統)。
  • 比如下面圖片(版本不一樣,內容會不一樣):


6、mdev

(1)mdev是udev的嵌入式簡化版本

  • udev/mdev是用來配合linux驅動工作的一個應用層的軟件;
  • udev/mdev的工作就是配合linux驅動生成相應的/dev目錄下的設備文件。

(2)在rcS文件中沒有mdev配置項時,/dev目錄下啟動后是空的;在rcS文件中添加上mdev有關的2行配置項后,再次啟動系統后發現/dev目錄下生成很多的設備驅動文件。

(3)/dev目錄下的設備驅動文件就是mdev生成的,這就是mdev的效果和意義。

7、hostname

(1)hostname是linux中的一個shell命令。

  • hostname xxx 執行后可以用來設置當前系統的主機名為xxx,直接hostname不加參數可以顯示當前系統的主機名。

(2)/bin/hostname -F /etc/sysconfig/HOSTNAME,指定一個主機名配置文件/etc/sysconfig/HOSTNAME)。

(3)在制作根文件系統時,要創建/etc/sysconfig/HOSTNAME文件,然后在里面敲入文本xjh后保存。

8、ifconfig

  • 如果希望開機進入命令行后,ip地址就是一個指定的ip地址(譬如192.168.1.30),需要在rcS文件中ifconfig eth0 192.168.1.30;
  • 如果沒有配置,完全啟動后會沒有ip地址,但可以在完全啟動后用ifconfig eth0 xxxxxxxxx來設置。



三、rcS文件實戰

1、PATH、runlevel

(1)rcS文件明明存在但是卻提示不存在

  • 原因是rcS文件是在windows下創建的,行尾換行符為'\r\n';
  • 但是因為ubuntu中的vi對行尾做了優化,所以在ubuntu中是看不出來多了東西的。
  • 但是在securecrt(vim 打開)下一看就發現每一行末尾多出來了一個^M。
  • 解決方法是在securecrt下打開,然后刪除^M,或者利用一些軟件工具。

(2)啟示

  • shell腳本文件如果格式不對,運行時可能會被提示文件不存在。
  • 有時候一個應用程序執行時也會提示文件不存在,問題可能是這個程序所調用的一個動態鏈接庫找不到。

(3)測試結果

  • PATH本來在busybox中就已經用代碼導出過了,所以rcS中再次導出沒有任何明顯的現象,因此看不出什么差別;
  • runlevel(是一個命令,可以看到當前運行級別)實際執行結果一直是unknown,問題在于busybox并不支持runlevel這個特性。

2、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)因為根文件系統中找不到掛載點
  • 所謂掛載點就是我們要將目標文件系統(當然這里都是虛擬文件系統)掛載到當前文件系統中的某一個目錄中,這個目錄就是掛載點。
  • 解決方案就是自己在制作的rootfs根目錄下創建這些掛載點目錄即可。
  • 驗證是否掛載成功,可以看掛載時輸出信息;還可以啟動后去看proc和sys文件夾,如果有文件出現則證明掛載成功了,如果沒東西就證明失敗了。



四、profile文件和用戶登錄理論

# Ash profile # vim: syntax=sh# No core files by default ulimit -S -c 0 > /dev/null 2>&1USER="`id -un`" LOGNAME=$USER PS1='[\u@\h \W]\# ' PATH=$PATHHOSTNAME=`/bin/hostname`export USER LOGNAME PS1 PATH

1、profile文件添加

(1)之前添加了/bin/hostname,在/etc/sysconfig/HOSTNAME文件中定義了一個hostname(xjh)。

  • 效果:命令行下hostname命令查到的host名字確實是xjh,但是沒有顯示命令行的提示符#。

(2)解決方法,將提供的profile文件放入/etc/目錄下即可。

(3)添加了之后的實驗現象:命令行提示符前面顯示:[@xjh ]#

  • 表明profile文件起作用了,因為hostname顯示出來了。
  • 但是登錄用戶名沒顯示出來。[xxx@xjh]#
  • 原因是我們直接進入了命令行而沒有做登錄。等后續添加了用戶登錄功能,并且成功登陸后這個問題就能解決。

(4)profile文件工作原理

  • profile文件被busybox(init進程)自動調用的,所以是認名字的。

2、如何看到用戶登錄界面

(1)linux中的原則是,用一個小程序來完成一個功能。

  • 如果產品需要很復雜的綜合型的功能,先使用很多個小程序完成其中的一個功能,然后再將這些小程序集成起來完成整個大功能的產品。
  • 這種集成很多個小程序來完成一個大的功能的思路,有很多種技術實現。譬如shell腳本,還有一些別的技術,譬如linux啟動中的inittab。

(2)intttab中有一個配置項 ::askfirst:-/bin/sh

  • 這個配置項作用就是當系統啟動后,如果按回車就去執行/bin/sh,執行這個就會出現命令行。
  • 因此我們這樣的安排就會直接進入命令行而不會出現登錄界面。

(3)要出現登錄界面,就不能直接執行/bin/sh,而應該執行一個負責出現登錄界面并且負責管理用戶名和密碼的一個程序。

  • busybox中集成了該程序(就是/bin/login或者/sbin/gettty);
  • 在inittab中用/bin/login或者/sbin/getty去替代/bin/sh

3、用戶名和密碼的設置

(1)用戶名和密碼的設置是和登錄程序有關聯的,但是/bin/login和/sbin/getty在用戶名和密碼的管理上是一樣的。

  • 其實常見的所有的linux系統的用戶名和密碼的管理幾乎都是一樣的。

(2)密碼一般都是用加密文字的,而不是用明文。

  • 系統中的密碼,存儲在系統中的一個專門用來存密碼的文件中;
  • 用明文存密碼有風險,因此linux系統都是用密文來存儲密碼的。

五、用戶登錄實戰

1、添加/bin/login到sysinit

(1)在inittab中修改,去掉/bin/sh,換上/bin/login,則系統啟動后出現登錄界面。可以輸入用戶名和密碼。

(2)實驗現象:成功出現用戶登錄界面,但是死活密碼不對。

2、添加passwd和shadow文件

(1)為什么用戶名和密碼不對?因為根本沒有為root用戶設置密碼。

(2)linux系統中用來描述用戶名和密碼的文件是passwd和shadow文件,這兩個文件都在etc目錄下。

  • passwd文件中存儲的是用戶的密碼設置,shadow文件中存儲的是加密后的密碼。

(3)直接復制ubuntu系統中的/etc/passwd和/etc/shadow文件到當前制作的rootfs目錄下,然后再做修改即可。假如只有root用戶

  • 每個文件都只保留root的內容;
  • 從passwd文件中可知,需要將/root改為/root/rootfs/root/目錄,bash(busybox不支持bash)改為sh
  • shadow只保留root的內容,然后剩下的不用修改,密碼和拷貝源一樣。

(4)shadow中默認有一個加密的密碼口令,這個口令和拷貝源的shadow本身有關。

  • 比如拷貝源的ubuntu中root用戶的密碼是root,那么復制過來后登陸時的密碼還是root。

3、重置密碼實踐

(1)ubuntu剛裝好時,默認用普通用戶登錄,默認root用戶是關閉的。

  • 普通用戶的密碼是在裝系統的時候設置的,普通用戶登陸后使用su passwd?root給root用戶設置密碼,設置了密碼后root用戶才可以登錄。

(2)原因是root用戶在/etc/shadow文件中加密口令是空白的,所以是不能登錄的。

(3)busybox中因為沒有普通用戶,因此如果root用戶的加密口令是空的,則默認無密碼直接登錄。登陸了之后,可以用passwd root給root用戶設置密碼。

(4)遺忘操作系統的密碼的解決方法

  • 用其他系統(WindowsPE系統或者ubuntu的單用戶模式等)來引導啟動,啟動后掛載到我們的硬盤上,然后找到/etc/shadow文件,去掉密文密碼后保存。
  • 然后再重啟系統后密碼就沒了。

4、getty實戰

(1)inittab中最常見的用于登錄的程序不是/bin/login,反而是/sbin/getty。

(2)這兩個的差別不詳,但是在busybox中這兩個是一樣的。這兩個其實都是busybox的符號鏈接而已,因此不用嚴格區分這兩個。

(3)我們可以在inittab中用getty替換login程序來實現同樣的效果。



六、動態鏈接庫的拷貝

1、靜態編譯鏈接helloworld程序并執行

(1)自己寫一個helloworld程序,然后交叉編譯連接,然后丟到開發板根文件系統中,開機后去運行。

(2)如果使用gcc編譯則可以在主機ubuntu中運行,但是不能在開發板運行;要在開發板運行需要用arm-linux-gcc來交叉編譯,但是此時編譯文件不能在主機ubuntu中運行。

  • 可以用file xx命令來查看一個elf可執行程序是哪個架構的。

(3)靜態鏈接:arm-linux-gcc hello.c -o hello_satic -static(即在命令后添加-static)

(4)實驗結果:靜態編譯連接后生成的hello_satic已經可以成功運行。

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目錄下即可解決。

3、找到并復制動態鏈接庫文件到rootfs中

(1)arm-2009q3這個交叉編譯工具鏈的動態鏈接庫在/usr/local/arm/arm-2009q3/arm-none-linux-gnueabi/libc/lib目錄下。

  • 其他的一些交叉編譯工具鏈中動態鏈接庫的目錄不一定在這里,需要查找,查找的方法就是find。
  • find -name "*.so"

(2)復制動態鏈接庫到roots/lib目錄下。

  • 復制時要注意參數用-rdf,主要目的就是符號鏈接復制過來還是符號鏈接。
  • 復制命令:cp lib/*so* /root/porting_x210/rootfs/rootfs/lib/ -rdf

(3)再次測試./hello_dynamic看看是否可以運行,實驗結果是可以運行。

4、使用strip工具去掉庫中符號信息

  • 動態鏈接庫so文件中包含了調試符號信息,這些符號信息在運行時是沒用的(調試時用的),這些符號會占用一定空間。
  • 在傳統的嵌入式系統中flash空間是有限的,為了節省空間常常把這些符號信息去掉。這樣節省空間并且不影響運行。
  • 去掉符號命令:arm-linux-strip *so*,實際操作后發現庫文件由3.8M變成了3.0M,節省了0.8M的空間。



七、開機自啟動與主流rcS格式介紹

1、修改rcS實現開機自啟動

(1)開機自啟動指的是讓一些應用程序能夠開機后自動執行;

(2)開機自啟動的實現原理

  • 在(開機會自動執行的)腳本rcS中添加(執行某個程序的)代碼。

2、前臺運行與后臺運行

(1)程序運行時占用當前的控制臺,因此在這個程序結束前,我們都無法使用控制臺,這就叫前臺運行。

  • 默認執行程序就是前臺運行的。

(2)后臺運行就是讓這個程序運行,并且同時讓出控制臺。

  • 程序可以照常運行,而且不影響當前控制臺的使用。
  • 讓一個程序后臺運行的方法就是 ./xxx &

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

4、實際開發中rootfs的rcS是怎樣的?

(1)以X210開發板九鼎科技做的rootfs中rcS部分來分析;

  • 分析inittab發現,sysinit執行rcS,shutdown時執行rcK;
  • 分析/etc/init.d/rcS和rcK文件發現,rcS和rcK都是去遍歷執行/etc/init.d/目錄下的S開頭的腳本文件,區別是rcS傳參是start,rcK傳參是stop。

(2)由此可知

  • 正式產品中的rcS和rcK都是一個引入,而不是真正干活的。
  • 真正干活的配置腳本是/etc/init.d/S??*。
  • 這些文件中肯定有一個判斷參數是start還是stop,然后start時去做一些初始化,stop時做一些清理工作。



八、制作ext2格式的鏡像并燒錄啟動

1、確定文件夾格式的rootfs可用(用NFS啟動方式驗證此文件夾格式的rootfs可用

  • 設置bootargs為nfs啟動方式;
  • 然后使用剛才在主機ubuntu中做好的文件夾格式的rootfs來啟動;
  • 查看啟動效果,作為將來用ext2格式的鏡像燒錄時的參照物。

2、動手制作ext2格式的鏡像

利用文件夾格式的rootfs,通過一些操作得到鏡像格式的rootfs。

(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/ //這里的./ext2_rootfs/即我們的/root/rootfs? (2)復制./rootfs中的內容,用cp ../rootfs/* ./ -rf,注意ubuntu中rootfs的具體路徑

(3)執行下面命令

umount /dev/loop1 losetup -d /dev/loop1 (4)完成后得到的rootfs.ext2,即做好的rootfs鏡像,可以燒錄。

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制作實驗圓滿完成


創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的使用BusyBox制作根文件系统的理论分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。