linux初始化內存盤卡住,Linux系統內存磁盤初始化技術詳細解析

轉自:http://m.zol.com.cn/article/1271270.html?via=index

Linux內存初始化技術(initrd)用于支持兩階段的系統引導過程,是在系統啟動過程中被掛載的臨時root文件系統(譯者注:這里的root文件系統是指的根文件系統)。initrd包含很多可執行程序和驅動,并允許在臨時的內存磁盤根文件系統被卸載,內存被釋放后掛載真實的root文件系統。在許多嵌入式linux文件系統中,initrd是最終的根文件系統。這篇文章主要講解了linux2.6內核的initrd技術,包括在內核中的創建及使用。

1 什么是內存磁盤初始化?

0

initrd掛載優先級高于真實根文件系統,它被邦定在內核上,做為內核啟動過程的一部分被加載(load)。然后,做為兩階段引導過程的第一部分,內核掛載(mount)initrd,用于獲得并加載真實有效的文件系統。

為了達到這個目的,initrd包含有最起碼的目錄與程序,例如insmod,來安裝內核模塊到內核中。

對于桌面或服務器linux,initrd是臨時文件系統,它的生存周期很短,僅僅是做為到達真實根文件系統的橋梁。但對于沒有存儲設備的嵌入式系統來說,它才是永久性的根文件系統。本篇文章對這兩方面均有涉及。

2 深入分析initrdL

initrd包含有必須的程序和系統文件,用于支持系統的啟動的第二階段過程。創建初始化內存的方法,是隨著你所使用的系統版本而改變的。從Fedora Core3以后,initrd就由回送設備(loop device)建立。什么是回送設備?它是一個設備驅動,允許你將一個文件掛載為塊設備,并對其文件系統做出描述。也許loop device并不存在與你的內核中,但是你能夠通過內核的配置工具(make menuconfig)打開它。路徑是:Device Drivers-》Block Devices-》LoopBack Device support。下面為檢查命令:

# mkdir temp ; cd temp

# cp /boot/initrd.img.gz .

# gunzip initrd.img.gz

# mount -t ext -o loop initrd.img /mnt/initrd

# ls -la /mnt/initrd

#

現在,你可以通過查看/mnt/initrd的子目錄來查看initrd的內容。需要注意的是,即使你的initrd鏡像文件并不是以.gz做為后綴名,但是你同樣可以通過增加此后綴名來讓gunzip打開它。

從Fedora Core3開始,默認的initrd鏡像就是一個壓縮的gpio歸檔文件。除了用掛載文件的方式以外,你同樣可以通過cpio歸檔的方式來將其掛載成使用了回送設備的壓縮鏡像。你可以通過以下的指令來檢查這個cpio歸檔文件的內容:

# mkdir temp ; cd temp

# cp /boot/initrd-2.6.14.2.img initrd-2.6.14.2.img.gz

# gunzip initrd-2.6.14.2.img.gz

# cpio -i --make-DirectorIEs < initrd-2.6.14.2.img

你看到的結果將是一個小型根文件系統,如下所示:

# ls -la

#

drwxr-xr-x 10 root root 4096 May 7 02:48 .

drwxr-x--- 15 root root 4096 May 7 00:54 ..

drwxr-xr-x 2 root root 4096 May 7 02:48 bin

drwxr-xr-x 2 root root 4096 May 7 02:48 dev

drwxr-xr-x 4 root root 4096 May 7 02:48 etc

-rwxr-xr-x 1 root root 812 May 7 02:48 init

-rw-r--r-- 1 root root 1723392 May 7 02:45 initrd-2.6.14.2.img

drwxr-xr-x 2 root root 4096 May 7 02:48 lib

drwxr-xr-x 2 root root 4096 May 7 02:48 loopfs

drwxr-xr-x 2 root root 4096 May 7 02:48 proc

lrwxrwxrwx 1 root root 3 May 7 02:48 sbin -> bin

drwxr-xr-x 2 root root 4096 May 7 02:48 sys

drwxr-xr-x 2 root root 4096 May 7 02:48 sysroot

#

一些小的,但是很有必要的程序組合能在./bin目錄下得到,包括nash(它不是一個shell,而是一個腳本解釋工具),用于加載內核模塊的insmod,以及lvm等。

上面所示目錄中,相對比較有趣的是root目錄下的初始化文件。這些文件,和傳統的linux啟動過程中一樣,是在initrd鏡像被解壓縮到RAM中時生成的。待會我們將繼續探討這個問題。

3 創建initrd的工具。

現在,讓我們回到一開始的討論:initrd的鏡像是如何被創建的?在傳統的linux系統中,initrd是在linux build的時候被創建的。像mkinitrd這樣的許許多多的工具,都能夠用于通過必須的庫和模塊來自動構建一個用于過渡到真實根文件系統的initrd。事實上,mkinitrd工具是一個腳本文件,因此,我們能夠很清楚得看到,這個過程是如何進行的。同樣的,YAIRD (Yet Another Mkinitrd)工具,也允許我們自定制每一個initrd被構建的階段。

4 自己動手,打造自定義的初始化內存盤

由于很多基于linux的嵌入式系統都沒有硬盤驅動器,initrd也可以做為永久性的根文件系統。下面我就將告訴你們,如何創建一個initrd鏡像。我使用的是標準linux桌面系統,因此大家即使沒有嵌入式目標設備也可以照著做。除了交叉編譯以外,嵌入式目標文件的構建過程是相同的。

#!/bin/bash

# Housekeeping...

rm -f /tmp/ramdisk.img

rm -f /tmp/ramdisk.img.gz

# Ramdisk Constants

RDSIZE=4000

BLKSIZE=1024

# Create an empty ramdisk image

dd if=/dev/zero of=/tmp/ramdisk.img bs=$$BLKSIZE count=$$RDSIZE

# Make it an ext2 mountable file system

/sbin/mke2fs -F -m 0 -b $$BLKSIZE /tmp/ramdisk.img $$RDSIZE

# Mount it so that we can populate

mount /tmp/ramdisk.img /mnt/initrd -t ext2 -o loop=/dev/loop0

# Populate the filesystem (subdirectories)

mkdir /mnt/initrd/bin

mkdir /mnt/initrd/sys

mkdir /mnt/initrd/dev

mkdir /mnt/initrd/proc

# Grab busybox and create the symbolic links

pushd /mnt/initrd/bin

cp /usr/local/src/busybox-1.1.1/busybox .

ln -s busybox ash

ln -s busybox mount

ln -s busybox echo

ln -s busybox ls

ln -s busybox cat

ln -s busybox ps

ln -s busybox dmesg

ln -s busybox sysctl

popd

# Grab the necessary dev files

cp -a /dev/console /mnt/initrd/dev

cp -a /dev/ramdisk /mnt/initrd/dev

cp -a /dev/ram0 /mnt/initrd/dev

cp -a /dev/null /mnt/initrd/dev

cp -a /dev/tty1 /mnt/initrd/dev

cp -a /dev/tty2 /mnt/initrd/dev

# Equate sbin with bin

pushd /mnt/initrd

ln -s bin sbin

popd

# Create the init file

cat >> /mnt/initrd/linuxrc << EOF

#!/bin/ash

echo

echo "Simple initrd is active"

echo

mount -t proc /proc /proc

mount -t sysfs none /sys

/bin/ash --login

EOF

chmod +x /mnt/initrd/linuxrc

# Finish up...

umount /mnt/initrd

gzip -9 /tmp/ramdisk.img

cp /tmp/ramdisk.img.gz /boot/ramdisk.img.gz

想創建initrd的話,你需要首先創建一個空文件,將/dev/zero(0字符流)做為ramdisk.img的輸入。得到的文件大小大約是4MB(有4000個1K的塊組成)。接下來,用mke2fs命令來創建一個使用這個空文件的ext2文件系統。現在,這個文件就是一個ext2文件系統。ok,接下來,以回路設備的形式掛載這個文件到/mnt/initrd,現在,你就在掛載點擁有一個代表著ext2文件系統的目錄,并用與存放你的initrd。其他大多數的腳本語句都是用于實現這個功能。

下一步,就是創建一些必須的子目錄,用于生成你的根文件系統: /bin, /sys, /dev, 和 /pro。這里只需要少數幾個目錄,例如,沒有/lib。但是它們已經包含了大部分功能。

如果想讓你的根文件系統發揮更大的作用,請使用 BusyBox。這個工具是一個包含了許多獨立工具的鏡像,這些獨立的工具你都能在linux中找到( ash, a等等wk, sed, insmod)。BusyBox的優勢在于,它把它們集合在了一起,并分享了公用的部分,從而極大縮小了鏡像的體積。這對于嵌入式系統來講,是非常理想的。請將BustBox鏡像從它的源目錄中復制出來,到你的/bin目錄下,這樣,很多指向BusyBox工具集的符號鏈接將被創建,BusyBox能確定哪一個工具將被使用,并自動引用它。這個/bin目錄下被創建的鏈接的小型集合將用于對啟動腳本的支持。

再下一步,就是一小部分特殊設備文件的創建。我從我的/dev文件夾中直接拷貝了出來,別忘了加上-a選項來保持它們原有的屬性。

倒數第二步,就是生成linuxrc文件。在內核掛載了內存盤之后,它將搜索并執行相關的啟動文件,如果沒有找到,內核就將linuxrc文件做為其啟動腳本。你最好在這個文件中對環境變量做一些基本設置,例如掛載/proc文件系統等。除了/proc外,我還掛載了/sys文件系統,將消息發送給終端。最后,我調用ash并通過它和根文件系統交互。最后記住,用chmod把linuxrc文件的屬性改為可執行。

最后,你的根文件系統算是ok了。現在它并沒有被掛載,用gzip將它壓縮,并將壓縮后的文件ramdisk.img.gz拷貝到/boot目錄下,這樣它就能被GRUB調用。

想要構建你的初始化ram盤的話,你只需要調用mkird,鏡像就將自動創建并拷貝到/boot目錄下。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453367.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453367.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453367.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

程序員是程序中的臨時變量,用完扔掉?

今天看到某人從墳墓里刨出的文章&#xff0c;挺有意思的。 程序員&#xff0c;到了一定年齡&#xff0c;如果沒有機會轉到領導級&#xff0c;至少是項目經理&#xff0c;能獨立領導團隊完成項目&#xff0c;還是停留在編碼的層次&#xff0c;那么被迫離開的危險會是很高的&…

屬性依賴注入

1.依賴注入方法 手動裝配和自動裝配 2.手動裝配 2.1 基于xml裝配 2.1.1 構造方法 <!-- 構造方法注入<constructor-arg>name:參數名type:類型value: --> <bean id"user" class"g_xml.constructor.User"><constructor-arg name"id…

windows下實現自己的第一個python腳本文件并.exe運行

前言 python可以做很多事情&#xff0c;比如知乎上的回答&#xff0c;每天來到公司都要打開AS&#xff0c; QQ和微信,為了省事決定用python寫一個簡單的腳本來實現。。腳本內容只有幾行,python的代碼真的好簡潔。。。 import os os.startfile("C:\Program Files (x86)\Ten…

C++中引用()基礎認識

對于習慣使用C進行開發的朋友們&#xff0c;在看到c中出現的&符號&#xff0c;可能會犯迷糊&#xff0c;因為在C語言中這個符號表示了取地址符&#xff0c;但是在C中它卻有著不同的用途&#xff0c;掌握C的&符號&#xff0c;是提高代碼執行效率和增強代碼質量的一個很好…

linux無法訪問443端口,linux – 為什么我無法在Ubuntu上ping端口443?

我通過iptables打開了端口443&#xff1a;pkts bytes target prot opt in out source destination45 2428 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/06 1009 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80141 10788 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:220 0 AC…

MediaWiki安裝配置(Linux)【轉】

閱讀目錄 2.1 本例子的安裝環境如下&#xff1a;轉自&#xff1a;http://blog.csdn.net/gao36951/article/details/43965527 版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 目錄(?)[-] 1MediaWiki簡介 2MediaWiki安裝21 本例子的安裝環境如…

提高編程水平的一段必經之路,研讀官方文檔

剛才看了 論壇里 jinxfei 的十年總結&#xff08;14&#xff09;&#xff1a;從CS轉向BS, 說實話&#xff0c;大部分內容我沒有太仔細的看&#xff0c;不過如下的一段引起了我的注意&#xff1a; 真正讓我心里有底的&#xff0c;還是在看了官方文檔之后&#xff1a;http://str…

在Asp.net core返回PushStream

最近用asp.net core webapi實現了一個實時視頻流的推送功能&#xff0c;在Asp.net中&#xff0c;這個是通過PushStreamContent來實現的。 基于對asp.net core的知識&#xff0c;隨手寫了一個&#xff08;要求控制器繼承自Controller基類&#xff09; [HttpGet] public async Ta…

順序棧的代碼實現

棧是一種限定只在表尾進行插入或刪除操作的線性表&#xff0c;棧也是線性表。表頭稱為棧的底部,表尾稱為棧的頂部,表為空稱為空棧。 棧又稱為后進先出的線性表,棧也有兩種表示:順序棧與鏈式棧。順序棧是利用一組地址連續的存儲單元。依次存放從棧底到棧頂的數據元素。 #includ…

Linux5觀察doc目錄并截屏,linux截屏命令

linux系統我們有時需要用到截屏功能&#xff0c;下面由學習啦小編為大家整理了linux截屏命令的相關知識&#xff0c;希望對大家有幫助!linux截屏命令詳解import檢測&#xff1a;import --versionimprot安裝&#xff1a;sudo apt-get install importimport常用命令&#xff1a;1…

eclipse+tomcat開發web程序

環境&#xff1a;windows 7Eclipse Java EE IDE for Web Developerstomcat 7.02 插件&#xff1a;tomcatPluginV321.zip 一.配置Tomcat插件 我們創建一個myplugins文件夾用于存放插件&#xff0c;myplugins位于D:/Program Files/J2EE目錄下。eclipse安裝路徑為&#xff1a;D:/P…

LoadRunner參數包含逗號

loadrunner的參數以逗號區分&#xff0c; 如果參數本身包含逗號&#xff0c;則會報錯 使用","將逗號包起來即可&#xff0c;如下圖 轉載于:https://www.cnblogs.com/cherrysu/p/8507649.html

軟件創業見聞

今天應一位朋友的邀請&#xff0c;過去蹭了個飯吃&#xff0c;順便坐了一個下午在聊著。這位老哥是一家軟件公司的老板&#xff0c;原來是從硬件銷售轉型到做軟件這一塊。因為說到軟件這一塊&#xff0c;我就很想了解一下這位老哥對于2009年的大勢是怎么看的&#xff0c;在2009…

如何采用設置標志的方法來區分循環隊列的滿和空

設立一個標志位,比如說是flag 最開始時隊列為空,設flag0 當入隊的時候讓flag1 出隊的時候flag0 然后再加上判斷隊頭隊尾指針是否重合 重合,且flag0,則為空 重合且flag1,則為滿

linux內核定義的常用信號6,linux復習

(3)設定apache服務器的網頁根目錄&#xff1a;/home/htdocs(4)在此apache服務器上設定一個目錄/home/htdocs/inside,且此目錄只允許IP地址為192.168.1.5的主機訪問(5)定義apache服務器以獨立進程的方式運行2、某系統管理員需每天做一定的重復工作&#xff0c;請按照下列要求&am…

linux 腳本 整數 賦值,shell基礎!!熟悉編程規范與變量

一、SHELL規范SHELL簡單介紹Bash(/bin/bash)是目前大多數 Linux 版本采用的默認 Shell。Bash 的全稱為 Bourne Again Shell&#xff0c;是最受歡迎的開源軟件項目之一。SHELL腳本簡單的來說&#xff0c;就是將平時使用的各種 Linux 命令按順序保存到一個文本文件中&#xff0c;…

一維數組的定義方式

一維數組的定義方式 在C語言中使用數組必須先進行定義。 一維數組的定義方式為&#xff1a;類型說明符 數組名 [常量表達式];其中&#xff0c;類型說明符是任一種基本數據類型或構造數據類型。數組名是用戶定義的數組標識符。方括號中的常量表達式表示數據元素的個數&#xff…

UIButton或UILabel加個下劃線

UIButton ####Objective - C LXYHyperlinksButton.h interface LXYHyperlinksButton : UIButton {UIColor *lineColor; }-(void)setColor:(UIColor*)color; 復制代碼LXYHyperlinksButton.m #import "LXYHyperlinksButton.h"implementation LXYHyperlinksButton- (id)…

android studio發布項目到github

點擊file setting ,打開對話框&#xff0c;如下&#xff0c;判斷git是否安裝成功 選擇GitHub&#xff0c;填寫github地址及密碼 發布項目&#xff1a; 轉載于:https://www.cnblogs.com/haihai88/p/8514683.html

在不使用{}時,else執行到哪里結束

正常情況下,if-else語句使用{}.執行時也執行{}里面的所有語句&#xff0c;但是當語句比較簡單時&#xff0c; 可以不使用{},而直接在if或else的后面寫要執行的語句。 但是程序只會執行到if或else語句后的第一個“;”其余的程序不在if-else的程序范圍內。