Linux之搭建自己的根文件系統

来源:http://www.cnblogs.com/CrazyCatJack/archive/2016/12/31/6238385.html
-Advertisement-
Play Games

Hi!大家好,我是CrazyCatJack。又和大家見面了。今天給大家帶來的是構建Linux下的根文件系統。希望大家看過之後都能構建出符合自己需求的根文件系統^_^ 1.內容概述 1.構造過程 今天給大家展示的根文件系統構造過程如下圖所示: 正如大家看到的,這是一個環環相扣的過程。因為在這四個方面的 ...


  Hi!大家好,我是CrazyCatJack。又和大家見面了。今天給大家帶來的是構建Linux下的根文件系統。希望大家看過之後都能構建出符合自己需求的根文件系統^_^

1.內容概述

1.構造過程

  今天給大家展示的根文件系統構造過程如下圖所示:

  正如大家看到的,這是一個環環相扣的過程。因為在這四個方面的內容其實相互包含,有很多交集的地方,所以我用環圖給大家展示。在第一部分,我會給大家講解如何在etc/目錄下編寫相應的配置文件,包含etc/init.d/rcS和etc/fstab等;在第二部分,將會教大家使用mdev,利用它來添加熱插拔功能,自動創建已經存在和即將加入的設備驅動節點;第三部分將給大家詳細講解如何用工具生成兩種文件類型的根文件系統,包含yaffs2和jffs2類型;第四部分給大家講解如何用NFS掛載根文件系統,包含啟動後掛載和啟動前掛載兩種方法。

 

2.最小根文件系統

  今天我們構建的最小根文件系統啟動過程如下:

 

   這是我做的最小根文件系統的執行流程圖。這其中2.3.4步是busybox的工作。關於busybox請參照我的上一篇博文《Linux根文件系統分析之init和busybox》,裡面CCJ給大家詳細講解了2.3.4步的內容^_^ 。今天主要給大家講解第一步和第五步。

  1) 創建設備console和null:

  首先,我們需要創建一個目錄,自己命名。這裡博主創建CCJ目錄:mkdir CCJ。然後進入自己創建的這個文件夾目錄,並創建dev目錄:mkdir dev 。進入目錄dev:cd dev/ 。然後我們需要查看一下console和null的主次設備號:ls /dev/console /dev/null -l 。這裡博主顯示的console的主設備號為5,次設備號為1;null的主設備號為1,次設備號為3。現在我們就可以創建設備console和null了:

  mknod console c 5 1     

  mknod null c 1 3

  在CCJ目錄下創建etc目錄:mkdir etc 。創建etc目錄下的inittab配置文件:vi etc/inittab 。併在其中添加console::askfirst:-/bin/sh 使這個shell的標準輸入,標準輸出,標準錯誤都指向這個console。第一步就這樣輕鬆的完成啦!

  2)配置C庫:

  首先我們創建lib目錄,這個目錄將用來存放C庫的文件:mkdir CCJ/lib 。進入你存放C庫文件的目錄下,將C庫文件複製到CCJ/lib目錄下:cp *.so* /CCJ/lib -d。這裡CCJ將C庫中的動態庫文件及其鏈接關係都複製到了CCJ/lib目錄下。這樣配置C庫也完成了。 

 

2.構造過程

1.編寫etc目錄下的配置文件和mdev的使用

  由於使用mdev同樣要配置etc目錄下的配置文件,所以CCJ將這兩個過程合併為一個小題目一起給大家講解^_^ 。

  其實經過上面的過程,我們解決了根文件系統執行的第一步到第五步,現在已經可以生成一個小小的根文件系統了。但如果你生成並燒寫到硬體上就會發現,這個小小的根文件系統的確能夠正常運行,但它的功能還很有限。為了讓它有更加豐富的功能和更方便的使用,現在我們需要添加一些新的配置。

  此刻我們製作的根文件系統中有些程式還沒有安裝,比如ps程式。有兩種方法,一種是在根文件系統啟動後我們手動掛載proc:

  mkdir proc

  mount -t proc none /proc

  這裡的proc是linux內核提供的虛擬文件系統。它會將linux系統運行時的信息採集,必須將它掛接到/proc目錄下。我們才能使用ps程式。那麼經過這樣的掛載我們就可以正常使用ps了。下麵是在燒寫了根文件系統的硬體上執行的命令:

  

ps
# ps
  PID  Uid        VSZ Stat Command
    1 0          3088 S   init     
    2 0               SW< [kthreadd]
    3 0               SWN [ksoftirqd/0]
    4 0               SW< [watchdog/0]
    5 0               SW< [events/0]
    6 0               SW< [khelper]
   55 0               SW< [kblockd/0]
   56 0               SW< [ksuspend_usbd]
   59 0               SW< [khubd]
   61 0               SW< [kseriod]
   73 0               SW  [pdflush]
   74 0               SW  [pdflush]
   75 0               SW< [kswapd0]
   76 0               SW< [aio/0]
  710 0               SW< [mtdblockd]
  745 0               SW< [kmmcd]
  763 0          3092 S   -sh 
  770 0          3092 R   ps 

  這裡我們可以看到有許多進程,其中PID表示的是進程號。ps是用來查看後臺進程工作情況的命令。這時,我們進入proc目錄,隨便打開一個進程查看:

 

# cd /proc/
# ls
1              745            diskstats      locks          sys
2              75             driver         meminfo        sysrq-trigger
3              76             execdomains    misc           sysvipc
4              763            fb             modules        timer_list
5              771            filesystems    mounts         tty
55             asound         fs             mtd            uptime
56             buddyinfo      interrupts     net            version
59             bus            iomem          partitions     vmstat
6              cmdline        ioports        scsi           yaffs
61             cpu            irq            self           zoneinfo
710            cpuinfo        kallsyms       slabinfo
73             crypto         kmsg           stat
74             devices        loadavg        swaps

# cd 1
# ls -l fd
lrwx------    1 0        0              64 Jan  1 00:10 0 -> /dev/console
lrwx------    1 0        0              64 Jan  1 00:10 1 -> /dev/console
lrwx------    1 0        0              64 Jan  1 00:10 2 -> /dev/console

  正如大家看到的,proc/目錄下有許多的進程。首列數字與上面的PID號對應,進入PID號,既是進入對應的應用程式。通過" ls -l fd "發現PID為1的進程其標準輸入,標準輸出,標準錯誤都指向/dev/console。

  這種掛載虛擬文件系統的方法雖然可用,但是十分麻煩,如果不想自己一個一個手動掛載的話,可以在etc/下編寫配置文件,統一處理。這樣在根文件系統啟動的時候,配置文件會幫我們處理好所有程式的文件系統掛載。我們就能直接使用各種程式了^_^ 。

  在etc/inittab中添加::sysinit:/etc/init.d/rcS 。然後創建rcS這個腳本文件:mkdir etc/init.d    vi etc/init.d/rcS。在其中輸入:mount -t proc none /proc。保存後再給它添加可執行許可權:chmod +x etc/init.d/rcS 。這樣修改後的根文件系統就會在啟動時為應用程式自動掛載proc,效果和上面手動掛載的一樣。這裡我們也可以在rcS文件中添加:mount -a 命令來取代mount -t 命令。mount -a命令是根據etc/fstab來掛載文件的。編寫etc/fstab為:proc /proc proc defaults 0 0。其效果和上面相同。

  由於linux下有很多設備驅動,如果手動一個一個添加dev/目錄下的內容十分麻煩,所以我們可以用udev自動添加設備節點。這裡我們用到的是busybox下的udev的簡化版:mdev。那麼我們該如何配置才能使用mdev呢?查看busybox目錄下的mdev.txt文件,裡面有詳細的說明:

 

Mdev has two primary uses: initial population and dynamic updates.  Both
require sysfs support in the kernel and have it mounted at /sys.  For dynamic
updates, you also need to have hotplugging enabled in your kernel.

Here's a typical code snippet from the init script:
[1] mount -t sysfs sysfs /sys
[2] echo /bin/mdev > /proc/sys/kernel/hotplug
[3] mdev -s

Of course, a more "full" setup would entail executing this before the previous
code snippet:
[4] mount -t tmpfs mdev /dev
[5] mkdir /dev/pts
[6] mount -t devpts devpts /dev/pts

  首先,根據 [1]、[4]我們得知,需要sys目錄,dev目錄。且需要添加sysfs和tempfs文件類型。所以在etc/fstab中添加:

  sysfs /sys sysfs defaults 0 0

  tmpfs /dev tmpfs defaults 0 0

  這裡從左至右依次代表:設備名、掛載點、文件系統類型、預設參數等。又根據[2]、[3]、[5]、[6]在etc/init.d/rcS中添加:

  mkdir /dev/pts

  mount -t devpts devpts /dev/pts

  echo /sbin/mdev > /proc/sys/kernel/hotplug

  mdev -s

  這裡的hotplug表熱拔插,指向mdev。當添加新設備時,會調用它來創建新設備節點。而mdev -s則表示把現有的設備節點創建出來。經過這一番更改,我們重新生成根文件系統,燒寫到硬體設備上,通過終端觀察實驗現象:

  

  大家可以看到dev/目錄下有很多設備節點,這都是mdev自動創建出來的。etc目錄下配置文件和mdev使用講解完畢。

 

2.生成yaffs2和jffs2文件

  下麵講一下如何利用工具生成yaffs2和jffs2文件。因為我們在linux下構建的根文件系統是要燒寫到硬體平臺上的,所以需要生成一個可燒寫的文件。今天將兩種可燒寫的根文件系統的文件類型:yaffs2和jffs2。

  1>yaffs2:

  首先我們需要從網路或其他途徑獲取到mkyaffs2image工具,利用它來生成yaffs2文件。進入存有mkyaffs2image工具的目錄下。將它解壓縮:

  cd document_mkyaffs2/

  tar xjf yaffs_source_util_larger_small_page_nand.tar.bz2

  cd Development_util_ok

  cd yaffs2/

  cd utils/

  進入工具目錄後:make 。生成我們需要的mkyaffs2image。將它複製:cp mkyaffs2image /usr/local/bin/。並給它可執行許可權:chmod +x /usr/local/bin/mkyaffs2image。再次進入我們的CCJ目錄,利用mkyaffs2image生成可燒寫的根文件系統:mkyaffs2image CCJ CCJ.yaffs2。

  2>jffs2:

  生成jffs2比yaffs2要稍稍複雜一些。CCJ這裡用到的是"mtd-utils-05.07.23.tar.bz2",它是MTD設備的工具包,編譯它就會生成製作jffs2的工具。它需要zlib壓縮包,所以我們要先安裝zlib。大家可以自行下載zlib的源碼進行安裝,這裡舉例說明:

  tar xzf zlib-1.2.3.tar.gz

  cd zlib-1.2.3/

  ./configure --shared --prefix=/usr/

  make

  這裡的shared是編譯動態庫,prefix表示將zlib安裝在哪裡。make生成zlib後,make install進行安裝。

  現在有了zlib後,我們可以編譯jffs2的生成工具了。

  tar xjf mtd-utils-05.07.23.tar.bz2

  cd mtd-util-05.07.23/util

  make

  make install

  現在我們就安裝瞭解壓後的jffs2生成工具。進入CCJ目錄,執行:mkfs.jffs2 -n -s 2048 -e 128KiB -d CCJ -o CCJ.jffs2

  這裡的-n表示不要在每一個擦除塊上加上清楚標誌;-s 2048表示一頁大小為2048位元組;-e 128KiB表示一個擦除塊大小為128KB;-d 表根文件系統目錄;-o表示輸出文件。按理說,執行完這步生成的jffs2燒寫到硬體平臺上就能夠正常運行,但是請大家註意更改自己的bootloader的環境變數,更改為掛載jffs文件類型,而不要預設為yaffs,否則會啟動失敗。

 

3.NFS掛載根文件系統

   這裡也給大家介紹兩種掛載方法:1.是在已經啟動的硬體平臺上,將伺服器根文件系統掛載到硬體平臺上。2.是在未啟動的硬體平臺上,通過修改環境變數,指定掛載地址為伺服器地址,系統一啟動就掛載伺服器的根文件系統。

  1>啟動後掛載:

  要想用NFS掛載根文件系統,必須滿足兩個條件:(1)伺服器允許那個目錄可被掛接。(2)硬體平臺去掛接那個目錄。首先是第一個條件,我們需要到etc/exports里去配置被允許掛接的目錄:

  cd CCJ

  vi /etc/exports

  在其中添加我們根文件系統所在目錄:

 

  保存後,重啟NFS服務:/etc/init.d/nfs-kernel-server restart。理論上現在就可以掛載了,我們可以先試驗一下,用伺服器掛載自己的根文件系統看能否成功:

  mount -t nfs 192.168.1.19:/work/nfs_root/CCJ /mnt

  如果系統沒有提示出錯,而且根文件系統能夠正常使用,就說明我們成功了。那麼現在來真正的掛載,在已經啟動的硬體平臺的終端上,我們創建掛載點:mkdir /mnt。然後開始掛載:

  mount -t nfs -o nolock 192.168.1.19:/work/nfs_root/CCJ /mnt

  此時,如果掛載成功,在硬體平臺上顯示的就是伺服器的根文件系統了,裡面的文件內容一模一樣,在伺服器上對文件內容的更改也會顯示在硬體平臺上^_^ 。

  2>啟動前掛載:

  這裡,CCJ使用的bootloader是u-boot。只需在系統啟動時,進入u-boot。修改u-boot的環境變數,使系統的根文件系統地址指向伺服器的地址即可。在u-boot下,NFS掛載的定義格式如下:

  nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
  ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>

  所以我們只需根據自己實際的IP地址、網關、子網掩碼等替換掉其中的參數,然後將這條命令輸給u-boot並保存就可以了。這裡CCJ的硬體平臺IP=192.168.1.13;伺服器IP=192.168.1.19;網關=192.168.1.1;子網掩碼=255.255.255.0 。在u-boot下,輸入print就可以看到當前的環境變數,其中和掛載根文件系統相關的是bootargs:

  bootargs=noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0

  現在根據掛載跟文件系統的格式,我們需要更改:

  set bootargs noinitrd root=/dev/nfs nfsroot=192.168.1.19:/work/nfs_root/CCJ ip=192.168.1.13:192.168.1.19:192.168.1.1:255.255.255.0::eth0:off rootfstype=jffs2 init=/linuxrc console=ttySAC0

  將這條環境變數保存,然後啟動內核。就可以看到我們的根文件系統和伺服器是一樣的,也就是說掛載到了伺服器的根文件系統上 。

 

敬告:

本文原創,歡迎轉載^_^

轉載請在文章醒目處註明:

原創作者ID:    CrazyCatJack

原始博文鏈接:http://www.cnblogs.com/CrazyCatJack/p/6238385.html                       

 

題外話:

  馬上就是2017年了,首先祝大家元旦快樂!^_^ 這一年裡,CCJ收穫了很多。完成了為期一年的項目,做出了滿意的機器人;找到了心儀的工作,馬上就要到廣東去做linux驅動開發了,從來沒有到過這麼往南的地方呢;相信大家也收穫良多吧,祝我們新的一年有更多的成長,世界也會因代碼而不一樣吧,嘿嘿~

 

 

 

 

 

CrazyCatJack

2016-12-31 16:06:18

 

 

 

 

 

 

 

 

 

 

  

 

 

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 筆記:Memory Notification: Library Cache Object loaded into SGA在警告日誌中發現一些這樣的警告信息:Mon Nov 21 14:24:22 2011Memory Notification: Library Cache Object loaded ...
  • 最近在批量更新數據時,發現無論怎麼操作觸發器都僅僅捕獲到了一條數據,觸發器代碼大致如下。 我們知道在觸發器中DELETE和INSERTED其實是兩張虛表,因此用變數獲取僅能得到一條數據,但是如果用游標的話可以獲取到位於虛表中的所有數據,批量處理。於是修改如下: 既然明白了觸發器中DELETE和INS ...
  • 開始談談開源的SymmetricDS,談談實際使用中,遇到的一些問題和解決辦法。持續更新: SymmetricDS 快速和靈活的資料庫複製 實際使用 和 埋過的坑 (一) ...
  • Oracle補全日誌(Supplemental logging)特性因其作用的不同可分為以下幾種:最小(Minimal),支持所有欄位(all),支持主鍵(primary key),支持唯一鍵(unique),支持外鍵(foreign key)。包括LONG,LOB,LONG RAW及集合等欄位類型 ...
  • 今天發現它真的是一個問題。 拿我最喜歡的Oracle來說吧。一般情況下,建表不管大小寫,建完表名、欄位名總是大寫的,這樣你不得不在單詞之間加下劃線,從而增加了欄位名長度,有時就超長了。在select的結果中顯示也不美觀。Oracle也支持以雙引號括起來的欄位名,不過,你可要註意啦,用"Ok"建的欄位 ...
  • 下載 https://www.raspberrypi.org/downloads/raspbian/ Raspbian 系統這裡有兩個版本的Raspbian,桌面版本與極簡版本或下載其他支持樹莓派的操作系統,如 windows10 iot 等; 接下來我們要做的是把系統鏡像寫入到sd卡中,把sd作為 ...
  • 本文由ilanniweb提供友情贊助,首發於爛泥行天下 想要獲得更多的文章,可以關註我的微信ilanniweb 前一段時間寫過一篇codis集群的文章,寫那篇文章主要是因為當時的項目不支持redis自身集群的功能。 而現在最新的項目是需要redis集群的,這篇文章我們就來介紹下有關redis的安裝與... ...
  • resources 理解 %IOWAIT (%WIO) LINUX系統的CPU使用率和LOAD Linux Performance Observability Tools How Linux CPU Usage Time and Percentage is calculated Linux進程狀態 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...