ARM Linux根文件系統Root Filesystem的製作

2021-01-18 電子產品世界
http://xianzilu.spaces.live.com/blog/fakehandlerpage.aspx?wa=wsignin1.0

http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!290.entry

本文引用地址:

http://www.eepw.com.cn/article/201611/317986.htm

關於根文件系統的製作,網絡上有很多文章,大多數都只講到建幾個目錄,然後用Busybox做個Shell,有很多關鍵的東西沒有說。經過很長時間的摸爬滾打,我終於能夠白手起家建立一個根文件系統了。其實我也不懂得原理,只是告訴大家我的作法,其中也不免有錯誤,歡迎大家指正。

首先介紹根文件系統的組成:目錄、Shell、庫、腳本,一個個來。

根文件系統要包含這些必須有的目錄:/dev、/bin、/usr、/sbin、/lib、/etc、/proc、/sys

/dev是devfs(設備文件系統)或者udev的掛在點所在。在使用devfs的內核裡如果沒有/dev,根本見不到Shell啟動的信息,因為內核找不到/dev/console;在使用udev的系統裡,也事先需要在/dev下建立console和null這兩個節點。關於devfs和udev的區別,網上很多文章說。當然如果你的內核已經不支持devfs了(2.6.12以後),可以使用純純的靜態節點。也就是用mknod人工生成。

/bin、/usr/bin、/usr/sbin、/sbin是編譯Busybox這個Shell時候就有的,用於存放二進位可執行文件,就不多解釋了。

/lib用於存放動態連結庫。網上很多文章都說靜態編譯Busybox,可以省去建庫的麻煩過程。這樣做只能讓Busybox啟動,我們自己寫的,或者是編譯的軟體包還是需要動態庫的。除非全部靜態編譯,你可以試試,一個Hello world就要幾百k。關於庫的內容後面仔細說。

/etc是用來存放初始化腳本和其他配置文件的。關於初始化腳本的內容後面仔細說。

/proc是用來掛載存放系統信息虛擬文件系統——「proc文件系統」,「proc文件系統」在內核裡面可以選。如果沒有「proc文件系統」,很多Shell自己的命令就沒有辦法運行,比如ifconfig。「proc文件系統」不像devfs可以自動掛載,它需要使用初始化腳本掛載。另外,udev也需要「proc文件系統」的支持。

/sys用於掛載「sysfs文件系統」,「sysfs文件系統」在內核裡面可以選。目前我認為它就是給udev提供支持的,。「sysfs文件系統」也需要使用初始化腳本掛載。

另外還可以有/tmp、/mnt、/swp、/var這樣的不是嵌入式系統必須的目錄,在說完Shell的製作之後,我再談建立目錄的事情。

Shell很簡單,就是Busybox,上網下載一個來:http://www.busybox.net/downloads/。說Busybox和arm-linux-gcc有兼容性問題,不過我覺得那是比較低版本的時代問題了,我用Busybox 1.8.2和arm-linux-gcc 3.4.1/3.3.2都可以。解壓縮以後找到Makefile裡面的ARCH和CROSS_COMPILE,改成:
ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/3.4.1/bin/arm-linux-
當然CROSS_COMPILE由你自己的編譯器位置決定,然後
# make menuconfig
# make
# make install
注意配置的時候把一些uCLinux Only的東西去掉,不然會錯;配置的時候還可以修改安裝位置,默認是在Busybox下的「_install」。

之後就可以在Busybox生成的Shell基礎上建立根文件系統了,我就用命令來說吧,Busybox在/home/lxz/busybox,根文件系統在/home/lxz/rootfs

# mkdir /home/lxz/rootfs
# cd /home/lxz/busybox/_install
# cp -r ./ /home/lxz/rootfs

# cd /home/lxz/rootfs
# mkdir dev
# mkdir etc
# mkdir lib
# mkdir proc
# mkdir sys
# mkdir tmp

如果不用devfs,下面的命令是必須的。必須以root用戶執行(用su命令可以切換為root,切換後用exit命令可以返回普通用戶):

# cd /home/lxz/rootfs/dev
# mknod -m 660 console c 5 1
# mknod -m 660 null c 1 3

如果不使用devfs沒有這兩個靜態節點,console的提示根本就看不到,出現的現象可能是內核提示Free init memory: XXK之後,Warning: Unable to find a initial console之類的,具體的單詞記得不是很準確。我沒有試過使用udev的時候沒有這兩個靜態節點的情況,反正放了也不影響把/dev掛載為tmpfs。

如果使用udev,還需要把udevd、udevstart、udevadmin這三個文件放到/sbin裡面(我使用udev-117,網上介紹較多的udev-100有9個文件要放)。

庫可是一件非常麻煩的事請。我建議初學者拷貝買的開發板裡面帶的文件系統的庫,如果開發板的文件系統是映像,只需要把映像掛載在某個目錄下就可以訪問,假設映像叫做rootfs.cramfs,可以這樣

# mkdir /home/lxz/evb_rootfs
(切換為root用戶)
# mount -o loop rootfs.cramfs /home/lxz/evb_rootfs
(可以切換為普通用戶)
# cd /home/lxz/evb_rootfs/lib
# cp -r ./ /home/lxz/rootfs/lib

一般開發板裡都會帶有很多庫,但是總體積卻比較大。可以刪掉一些不用的庫來減小體積,但是,,我也不知道那些庫具體含有什麼函數,什麼情況刪什麼;也許以後我會把這部分補上。如果覺得庫體積太大,也可以自己編譯glibc或者uclibc,但是這是非常繁瑣的事請——目前我認為庫應該和編譯器arm-linux-gcc一起製作。有個傻瓜式的方案是使用cross-tool,下載地址:http://www.kegel.com/crosstool/。雖然cross-tool是用來製作交叉編譯器的,但是其過程中生成的glibc卻可以作為副產品為我們所用。cross-tool的使用可以看我之前的這篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!274.entry。在成功製作了交叉編譯器之後,就可以從cross-tool的目錄裡把glibc取出來,假設cross-tool的路徑是/home/lxz/cross-tool,編譯出的編譯器叫做arm-linux-gnu-gcc,gcc版本3.4.5,glibc版本2.3.6,想要把glibc庫拷貝到/home/lxz/glibc,下面的操作還是用命令來說明。

# cd /home/lxz/cross-tool/build/arm-linux-gnu-gcc/gcc-3.4.5-glibc-2.3.6/build-glibc

# ../glibc-2.3.6/configure --prefix=/home/lxz/glibc

# make install

等候安裝結束

# cd /home/lxz/glibc

# cp -r lib /home/lxz/rootfs

這樣就把glibc的大部隊拷貝好了,但是這樣還缺兩個庫,我們繼續

# cd /home/lxz/cross-tool/build/arm-linux-gnu-gcc/gcc-3.4.5-glibc-2.3.6/build-gcc/gcc

# cp libgcc_s.so* /home/lxz/rootfs/lib

還缺少一個libtermcap庫,這個就稍微有些麻煩。libtermcap-2.0.8-35-armv4l源碼包的下載地址是http://www.netwinder.org/mirror/pub/netwinder/SRPMS/nw/9/libtermcap-2.0.8-35.src.rpm,你也可以在這裡http://www.netwinder.org/allsrpms.html找到其他版本的。假設libtermcap-2.0.8-35.src.rpm下載到了/home/lxz/libtermcap,下面繼續用命令說明。

# cd /home/lxz/libtermcap

# rpm2cpio libtermcap-2.0.8-35.src.rpm | cpio -ivd
# tar xvjf termcap-2.0.8.tar.bz2
接下來要打13個補丁,很汗啊,請一定按照下面的順序來打補丁

# patch -p0 -i termcap-2.0.8-shared.patch
# patch -p0 -i termcap-2.0.8-setuid.patch
# patch -p0 -i termcap-2.0.8-instnoroot.patch
# patch -p0 -i termcap-2.0.8-compat21.patch
# patch -p0 -i termcap-2.0.8-xref.patch
# patch -p0 -i termcap-2.0.8-fix-tc.patch
# patch -p0 -i termcap-2.0.8-ignore-p.patch
# patch -p0 -i termcap-buffer.patch
# patch -p0 -i termcap-2.0.8-bufsize.patch
# patch -p0 -i termcap-2.0.8-colon.patch
# patch -p0 -i libtermcap-aaargh.patch
# patch -p0 -i termcap-2.0.8-glibc22.patch
# patch -p0 -i libtermcap-2.0.8-ia64.patch

然後到/home/lxz/libtermcap/termcap-2.0.8裡,找到Makefile,修改其中的CC和AR,

CC = /usr/local/arm/3.4.1/bin/arm-linux-gcc

AR = /usr/local/arm/3.4.1/bin/arm-linux-ar

當然,你的編譯器在哪裡就改成相應的內容。如果嫌麻煩,可以從本站資料頁面下載我已經打好補丁,修改好Makefile的包,地址http://cosine.oicp.net/project/common/termcap-2.0.8.tar.bz2。需要注意的是,這個包裡CC = arm-linux-gcc、AR = arm-linux-ar,請設置好預設路徑。然後就可以編譯了:

# cd /home/lxz/libtermcap/termcap-2.0.8

# make

# ln -s libtermcap.so.2.0.8 libtermcap.so.2

# cp libtermcap.so* /home/lxz/rootfs/lib

這樣,Shell啟動所需要的基本庫就都備齊了。但是,這些庫裡面還含有調試信息,體積稍大,可以把這些信息去掉(當然不去掉也沒有什麼影響)。

# cd /home/lxz/rootfs/lib

# arm-linux-strip *.so*

至此,庫就製作好了。

有了以上的東西,Shell還是不能正常工作。可能會是內核提示Free init memory: XXK之後就什麼輸出也沒有了,這時候向終端敲入文字,可以顯示;就是沒有終端提示符,不理會輸入的命令。這是因為初始化腳本沒有啟動Shell。下面介紹這些腳本。

首先是/etc/inittab。內核啟動、根文件系統掛載之後所必須的一個文件,其中列舉了Shell和整個系統初始化、關閉所需的命令。如果你想讓Shell出現,那麼只需要加入這麼一行「::askfirst:/bin/ash」。當然如果在編譯Busybox的時候選擇的shell不是「ash」,而是hush、lash、msh之類,那就改成相應的東西。除了啟動Shell,inittab還幹了很多事情,我就用我的inittab來說明了。注意,在編譯Busybox的時候要選上touch、syslogd、klogd等命令。

# Startup the system
null::sysinit:/bin/mount -o remount,rw /
null::sysinit:/bin/mount -t proc proc /proc
null::sysinit:/bin/mount -a
null::sysinit:/bin/hostname -F /etc/hostname

# Now run any rc scripts
::sysinit:/etc/init.d/rcS

# Now invoke shell
::askfirst:/bin/ash

# Logging junk
null::sysinit:/bin/touch /var/log/messages
null::respawn:/sbin/syslogd -n -m 0
null::respawn:/sbin/klogd -n

# Stuff to do for the 3-finger salute
::ctrlaltdel:/sbin/reboot

# Stuff to do before rebooting
null::shutdown:/usr/bin/killall klogd
null::shutdown:/usr/bin/killall syslogd
null::shutdown:/bin/umount -a -r
null::shutdown:/sbin/swapoff -a

好,把上面這些儲存為inittab,啟動系統。應該出現兩個提示,沒有/etc/fstab和/etc/init.d/rcS。目前我的理解/etc/fstab是用來執行mount -a命令的,裡面是文件系統的掛載表。還是用我的fstab來說明。

#


/dev/root / ext2 rw,noauto 0 1
proc /proc proc defaults 0 0
devpts /dev/pts devpts defaults,gid=5,mode=620 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0

還有/etc/init.d/rcS,這在PC上是用來執行/etc/init.d下所有初始化腳本的一個腳本,,請原諒我不懂得怎麼寫這種腳本,對於嵌入式系統,根本不需要這麼複雜,直接寫在/etc/init.d/rcS裡面了。還是用我的/etc/init.d/rcS來說明,其中啟動udev的那些指令對於使用靜態設備節點和devfs的系統不適用。

# Start udev
/bin/mount -t tmpfs tmpfs /dev
/sbin/udevd --daemon
/sbin/udevstart

# Configure net interface
/sbin/ifconfig lo 127.0.0.1 up
/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo
/sbin/ifconfig eth0 192.168.2.25 netmask 255.255.255.0
/sbin/route add default gw 192.168.2.1

如果用的是udev,還必須有udev的配置腳本。這個寫起來有些麻煩,我們可以直接用udev自己帶的那些腳本,位置在udev目錄下的etc/udev/udev.conf和etc/udev/rules.d裡面的文件。把這些放到根文件系統中去,etc/udev/udev.conf變為根文件系統的/etc/udev/udev.conf,etc/udev/rules.d裡面的文件變為/etc/udev/rules.d裡面的文件。

至此,一個可用的最簡單文件系統就完成了。之後,可以使用mkcramfs、mkyaffs之類的工具製作文件映像,這我就不多說了。需要注意的是,cramfs文件系統是只讀的,就算用的是initrd加載的cramfs也一樣是只讀的,這對根文件系統的/var目錄有一定的影響。除了本文中說的辦法,還可以用buildroot這個工具來建,但是現在我還在嘗試中,以後再說。如果你嫌上面的這一切都很麻煩,可以從本站資料站下載我給Linux 2.6.19內核做的最簡文件系統(1.5M),地址是http://cosine.oicp.net/project/at91rm9200/root.img,cramfs格式映像。

相關焦點

  • 製作ZedBoard上linux根文件系統(ramdisk)
    Digilent的OOB設計給出了一個ZedBoard上完整的運行的linux系統所需要的所有文件,包括配置FPGA的bit文件、 配置ARM PS系統的First-Stage boot loader(FSBL)和引導linux需要的Second-Stage boot loader(SSBL)、Linux內核zImage、設備樹文件devicetree_ramdisk.dtb 以及根文件系統
  • qemu運行自製arm64架構Linux系統
    3.製作根文件系統rootfs基於busybox的文件系統啟動過程:/sbin/init => /etc/inittab => /etc/init.d/rdS => /etc/fstab ...
  • 嵌入式根文件製作方法
    (一):首先linux根文件系統的製作需要的開發環境。1:移植Linux內核版本: linux-3.0.1 (只要能用就行)2:交叉編譯工具:arm-linux-gcc 4.3.2(任選)3:文件系統製作工具:Busybox-1.13.3(任選)4:etc.tar.gz(二):交叉編譯環境的搭建(這一步我在我的博客其他文章裡面有 詳細的搭建過程,很簡單滴~)(三):創建根文件系統的目錄
  • 基於busybox的嵌入式Linux根文件系統的的製作方法
    根文件系統一直是Linux系統不可或缺的組件,在嵌入式Lin-ux中,內核在啟動期間進行的最後操作之一就是安裝根文件系統。Busybox是構建嵌入式Linux根文件系統的軟體,用它製作根文件系統簡單、方便,而且設置靈活。
  • 跟光磊學Linux運維-深入淺出Linux文件系統
    Linux目錄結構介紹和Windows以盤符(例如C盤、D盤)作為根目錄不同的是,Linux的文件系統只有一個根目錄,使用/表示。# 查看test.txt文件的屬性信息-rw-r--r--. 1 root root 0 Oct 6 11:02 test.txt在訪問文件系統時,會涉及到兩種路徑:絕對路徑和相對路徑,其中絕對路徑是從根目錄開始的路徑,相對路徑是相對於當前路徑,特殊場景下是相對於某個目錄的位置
  • 高級Linux運維工程師養成記-Linux文件系統目錄結構
    >Linux目錄結構介紹和Windows以盤符(例如C盤、D盤)作為根目錄不同的是,Linux的文件系統只有一個根目錄,使用/表示。Linux系統中的目錄和文件都是呈倒置的樹形結構以.開頭的文件表示隱藏文件,路徑使用/(左斜線)分隔。文件名區分大小寫(是否大小寫敏感和作業系統無關,而是和作業系統的文件系統有關) ,例如opt和OPT是不同的概念文件名最長為255個字節,包括路徑在內文件名最長為4095個字節。
  • 基於S3C2440的嵌入式Linux根文件系統構建
    而文件系統作為作業系統的重要組成部分,用於控制對數據文件及設備的存取,提供對文件和目錄的分層組織形式,數據緩衝以及對文件存取權限的控制。根文件系統一直是Linux系統不可或缺的組件,在嵌入式Lin-ux中,內核在啟動期間進行的最後操作之一就是安裝根文件系統。busybox是構建嵌入式Linux根文件系統的軟體,用它製作根文件系統簡單、方便,而且設置靈活。
  • 帶你閱讀linux內核源碼:下載源碼、編譯內核並運行一個最小系統
    要學習linux內核,先要能夠編譯內核,還需要了解內核如何啟動根文件系統。這樣你才能在修改linux內核代碼之後,完成驗證的過程。本文教你完成下列過程:1.下載linux並編譯linux內核源碼2.編譯busybox3.製作一個最小的根文件系統4.qemu啟動你編譯好的內核和根文件系統
  • 30分鐘自製屬於自己的Linux系統
    Initial RAM filesystem and RAM disk (initramfs/initrd) support ... ...3.製作ramdisk根文件系統rootfs基於busybox製作ramdisk根文件系統rootfs.
  • Linux Lab 推出十大精彩使用案例
    所有的板子都有: 編譯好的 Qemu 的模擬器 編譯好的 文件系統以及配置文件 編譯好的 內核鏡像、dtb 以及配置文件 可直接啟動到串口的 Qemu 啟動腳本 所有倉庫都可以單獨下載,可以在 Linux Lab 內使用,也可以單獨使用。
  • OpenCV ffmpeg移植到ARM平臺
    4 修改生成的Makefile文件:# The name of your C compiler:CC= gcc 該成 CC= /root/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-gcc(根據你自己交叉編譯器的位置修改)# library (.a) file creation commandAR
  • arm linux 系統調用實現
    In this article we will dive into system call interface implementation in arm linux(with gnu eabi
  • 基於Ubuntu9.10和JZ2440的NFS系統
    NFS是個什麼東東,我就不細說了,定義如下:網絡文件系統(NFS,NetworkFileSystem)是一種將遠程主機上的分區(目錄)經網絡掛載到本地系統的一種機制,通過對網絡文件系統的支持,用戶可以在本地系統上像操作本地分區一樣來對遠程主機的共享分區
  • 玄鐵910與ARM_arm彙編 - CSDN
    其實這個值可以從生成的.config文件CONFIG_CONSOLE宏找到。如果搭建其它單板,需要注意內核啟動參數的console=參數值,同樣地,可從生成的.config文件中找到。 製作根文件系統到這裡是否大功告成了呢? 其實在上面的測試中,你會發現內核報panic,因為內核找不到根文件系統,無法啟init進程。
  • linux常用命令
    :w 保存文件但不退出vi:w file 將修改另外保存到file中,不退出vi不保存文件,強制退出vi:e! 放棄所有修改,從上次保存文件開始再編輯7、linux 如何查看目錄的剩餘空間大小?兩個命令df 、du結合比較直觀df -lh 查看整臺伺服器的硬碟使用情況cd / 進入根目錄du -sh * 查看每個文件夾的大小這樣的組合可以快速定位大文件和分區滿了8、查看linux內存剩餘情況free -g9、linux
  • 搭建PXE環境批量部署CENTOS7(Linux版)
    /PXE配置文件目錄:/var/www/html/root/pxelinux.cfg/安裝包目錄:/var/www/html/root/centos7/服務端配置文件HTTP配置文件:/etc/dhcp/dhcpd.confTFTP配置文件:/etc/xinetd.d/tftpPXE
  • 了解Linux安裝ARM交叉編譯器的步驟
    arm-linux-gcc等可執行程序位於bin子目錄下。 (2)環境變量的設置 -- 如果希望在控制臺中直接運行arm-linux-gcc,則必須把arm-linux-gcc所在的路徑記錄到控制臺的默認環境變量PATH中,這需要修改某些配置文件。
  • arm linux上建立nfs文件系統
    nfs文件系統建立(主機ip地址為192.168.3.170,開發板ip地址為192.168.3.100)1.安裝 nfs-kernel-server# sudo aptitude install nfs-kernel-server
  • Linux 系統下ARM Linux交叉編譯環境crosstool工具
    Linux系統下ARM Linux交叉編譯環境的建立目前流行的有三種途徑。cross-2.95.3.tar.bz2一般是交叉編譯2.4的linux內核的,而arm-linux-gcc-3.3.2.tar.bz2一般是交叉編譯2.6版本的內核的。二、自己動手慢慢編譯。這個方法是最麻煩的,需要下載很多源文件,步驟多比較繁瑣,成功率不高,極其容易出錯,即使是經驗豐富程式設計師,自己編譯一套完整的工具鏈也是很難成功的。