Linux學習之系統的構建

實驗環境:ubuntu 12.04 LTShtml

內核版本:linux-3.9.4linux

        由於一直以來都對Linux的工做機理比較感興趣,因此正好這兩天有機會好好的研究一下,那閒話很少說,直接進入正題。shell

        俗話說的好,公欲善其事,必先利其器。那麼對於一個系統內核級的修改與研究必然不能從本身機器中正在運行的內核下手,這樣一旦發生錯誤,將致使內核崩潰,沒法啓動,這個後果稍微有些嚴重。因此從新編譯一個用於實驗的內核是很是必要的。這裏詳見Linux學習以內核編譯與添加系統調用。ubuntu

        對於本次的任務,一個模擬器也是很是必要的,這裏主要是採用qemu模擬器。這個模擬器在linux下很經常使用,這裏再也不贅述。app

        當編譯內核與安裝qemu模擬器完成後,就能夠正式開始本次任務之旅了。oop

        由於內核已經編譯結束,咱們如今首先要作的是爲咱們本身的Linux系統準備一個很是重要的部分——根文件系統。這裏主要採用了兩種方案。學習

方法一:測試

        首先創建目標根目錄映像:ui

        dd if=/dev/zero of=myinitrd.img  bs=4096 count=1024spa

        dd 是 Linux/UNIX 下的一個很是有用的命令,做用是用指定大小的塊拷貝一個文件,並在拷貝的同時進行指定的轉換。dd 的主要選項:

一、指定數字的地方若如下列字符結尾乘以相應的數字: b=512, c=1, k=1024, w=2, xm=number m
二、if=file     輸入文件名,缺省爲標準輸入。
三、of=file    輸出文件名,缺省爲標準輸出。
四、ibs=bytes     一次讀入 bytes 個字節(即一個塊大小爲 bytes 個字節)。
五、obs=bytes    一次寫 bytes 個字節(即一個塊大小爲 bytes 個字節)。
六、bs=bytes      同時設置讀寫塊的大小爲 bytes ,可代替 ibs 和 obs 。
七、cbs=bytes     一次轉換 bytes 個字節,即轉換緩衝區大小。
八、skip=blocks    從輸入文件開頭跳過 blocks 個塊後再開始複製。
九、seek=blocks     從輸出文件開頭跳過 blocks 個塊後再開始複製。(一般只有當輸出文件是磁盤或磁帶時纔有效)
十、count=blocks     僅拷貝 blocks 個塊,塊大小等於 ibs 指定的字節數。
十一、conv=conversion[,conversion...]     用指定的參數轉換文件。
       
        mkfs.ext3 myinitrd.img
        這句命令的意思是將以前創建的.img文件塊格式化爲ext3的文件格式。
        而後建立rootfs目錄,做爲一個空的掛載點,並將咱們以前建立並格式化爲ext3文件系統格式的映像文件掛載到rootfs目錄下。
        mkdir rootfs
        sudo mount -o loop myinitrd.img rootfs
        這裏的這一掛載使咱們能夠在後面對建立的ext3文件系統映像進行相應的操做。
        而後建立一個咱們本身的init程序,這裏要明確一個概念,在linux操做系統系統啓動的過程當中,當init進程掛載完實際的文件系統以後,會判斷是否有用戶指定的啓動參數「init=」,若沒有,則執行如下命令之一,/sbin/init,/etc/init,/bin/init,/bin/sh。這裏咱們建立本身的init程序就是做爲用戶指定的啓動程序。
       
        能夠看到init程序的主要任務是輸出兩句話。
        而後使用靜態連接的方法編譯成可執行文件,並將這一可執行文件拷貝到目標根目錄下,即rootfs下。
        gcc -static -o init init.c
        cp init rootfs/
        而後準備dev目錄,這裏/dev目錄下主要是包含了linux啓動過程當中所必需的設備文件。
        sudo mkdir rootfs/dev
        sudo mknod rootfs/dev/console c 5 1
        sudo mknod rootfs/dev/ram b 1 0
        其中console控制檯設備就是那套直接鏈接在電腦上的鍵盤和顯示器,是直接和計算機相鏈接的原生設備。另外控制檯也包括虛擬控制檯,總之,這是linux啓動過程當中必不可少的設備。ram在這裏是做爲linux的根設備所建立和掛載的。
        由於在以前已經將咱們所建立的ext3文件系統格式的文件系統映像掛載到了rootfs目錄下,因此上述這些操做,實際上都是針對myinitrd.img這一咱們本身的根文件系統映像進行的操做。而後卸載。
        sudo umount rootfs
        至此,一個包含簡單應用程序的根目錄映像myinitrd.img就準備好了。
        而後使用以前安裝好的qemu模擬器進行模擬,看看咱們本身的linux操做系統可否正常啓動。
        qemu -kernel linux-3.9.4/arch/x86/boot/bzImage -initrd myinitrd.img -append "root=/dev/ram init=/init"
        能夠看到qemu中-kernel參數指定的是咱們本身的Linux操做系統的內核映像的位置,即以前咱們所編譯的內核的bzImage的絕對路徑,而後經過-initrd參數來指定咱們本身的根目錄映像,在-append參數中指定咱們的根設備是/dev/ram,指定啓動參數爲用戶指定的啓動程序init。運行結果以下:
       
        能夠看到咱們本身的init程序做爲用戶指定的啓動參數成功被init進程所執行,至此,採用方法一製做的根文件系統成功掛載。


方法二:

        方法二採用的方法是經過使用busybox製做根文件系統。

        首先下載busybox源碼,並解壓縮。

        http://busybox.net/downloads/busybox-1.19.3.tar.bz2

        而後進入busybox-1.19.3目錄下,對busybox進行配置編譯。

        make defconfig

        make menuconfig

        這裏要修改以下配置:

        將busybox settings -> build options -> build busybox as a static binary這一項選上。

        make

        而後準備根目錄映像,並安裝busybox到根目錄映像中。

        dd if=/dev/zero of=busyboxmyinitrd12M.img bs=4096 count=3072

        mkfs.ext3 busyboxmyinitrd12M.img

        mkdir rootfs

        sudo mount -o loop busyboxmyinitrd12M.img rootfs

        cd busybox-1.19.3

        sudo make CONFIG_PREFIX=../rootfs/  install

       

        sudo umount rootfs

        至此咱們本身的經過busybox製做的根目錄映像已經作好了,使用qemu模擬器試着運行一下。

        qemu -kernel linux-3.9.4/arch/x86/boot/bzImage -initrd busyboxmyinitrd12M.img -append "root=/dev/ram init=/bin/ash"

        運行結果以下:

       

        能夠看到進入到了busybox提供的shell環境,所以根文件系統加載成功。

        到此爲止,咱們能夠把前面的工做都看做是準備工做,真正精彩的節目開始了。

        下面咱們將製做帶grub啓動的磁盤映像。

        首先得到grub並製做grub啓動軟盤。

        下載grub,解壓縮。

        ftp://alpha.gnu.org/gnu/grub/grub-0.97-i386-pc.tar.gz

        創建啓動軟盤映像:

        dd if=/dev/zero of=vampirem.img bs=512 count=2880

        添加grub啓動功能

        sudo losetup /dev/loop3 vampirem.img

        sudo dd if=./grub-0.97-i386-pc/boot/grub/stage1 of=/dev/loop3 bs=512 count=1

        sudo dd if=./grub-0.97-i386-pc/boot/grub/stage2 of=/dev/loop3 bs=512 seek=1

        sudo losetup -d /dev/loop3

        關於losetup命令的詳細狀況請參閱losetup命令和loop設備的使用

        這裏其實是至關於採用一個循環設備loop3做爲一箇中間的掛載點,來對咱們本身的grub軟盤映像vampirem.img進行相應的修改和操做。

        而後在qemu模擬器上測試一下,看是否能夠進入grub界面。

  qemu -fda vampirem.img

       

        OK,咱們看到grub界面成功啓動了。

        接下來,開始準備咱們本身的linux操做系統的磁盤映像。

        dd if=/dev/zero of=40M.img bs=4096 count=10240

        sudo losetup /dev/loop3 40M.img

        而後要在磁盤映像上創建一個啓動引導分區,這裏採用

        sudo fdisk /dev/loop3

        能夠看到m命令是察看幫助信息的,咱們察看一下

        而後看到n命令是新建一個分區,a命令是將這個分區設爲引導分區,p命令是打印出分區表,w命令是把分區表寫到磁盤上並退出。因而:

        分區建好以後,將活動分區格式化爲ext3fs文件系統格式,並掛載到rootfs目錄下。

        sudo losetup -d /dev/loop3

        sudo losetup -o 1048576 /dev/loop3 40M.img

        這裏的偏移值1048576是由於以前在設置分區時咱們能夠看到第一個扇區是在2048處,所以2048*512=1048576即是此處的偏移值。

        sudo mkfs.ext3 /dev/loop3

        sudo mount -o loop /dev/loop3 rootfs/

        而後把以前準備好的,文件系統映像文件和內核映像文件拷貝到rootfs目錄下,即拷貝到咱們的磁盤映像文件中。

        sudo cp busyboxmyinit12M.img rootfs/

        sudo cp linux-3.9.4/arch/x86/boot/bzImage rootfs/

        而後在rootfs下創建boot目錄,以及boot目錄下的grub目錄。

        sudo mkdir rootfs/boot

        sudo mkdir rootfs/boot/grub

        而後將以前下載的grub的boot/grub目錄下的文件拷貝到rootfs/boot/grub目錄下。

        sudo cp ./grub-0.97-i386-pc/boot/grub/* rootfs/boot/grub

        而後須要在rootfs/boot/grub目錄下創建一個啓動菜單文件menu.lst。具體內容以下:

        裏面的內容意思很明顯,這裏再也不贅述。

        sudo umount rootfs

        sudo losetup -d /dev/loop3             

        下面緊張的時刻到了,咱們看一下,可否利用grub啓動軟盤,在磁盤映像上添加grub功能。

        qemu -boot a -fda vampirem.img -hda 40M.img

 

        能夠看到,成功添加。

        下面測試一下,從剛纔製做好的咱們本身的linux操做系統的磁盤映像文件進入grub界面而後啓動。

        qemu -hda 40M.img

 

        至此,咱們本身的一個小型的LINUX操做系統就完成了~

相關文章
相關標籤/搜索