Linux作業系統分析(7)- 打造屬於自己的linux發行版

來源:互聯網
上載者:User
提要

         linux的啟動過程,包括BIOS的加電自檢POST,拷貝MBR的資訊(啟動BootLoader),載入核心,掛載根檔案安系統這幾大步熟悉grub的話會知道linux啟動時grub中有三項:root,kernel,initrd。其三項的作用分別是:

1.指定核心所在的目錄
2.指定核心的名稱,以及掛載根目錄的方式,還有向核心傳遞一定的參數
3.initrd實際就是個小的linux系統,在一般的系統中initrd的作用是:啟動一個很小的linux用來掛載真實的linux。

       今天的目的就是從核心開始,打造一個屬於自己的linux。

環境:Ubuntu13.04 gcc4.7.3

相關的準備工作:

核心的編譯

qemu的安裝

 製作根系統目錄1)建立init程式 首先建立一個init.c檔案,代碼如下:
#include<stdio.h>int main(){    printf("Welcome! My student No. is sa*****310.\n");    return 0;}

 靜態編譯成一個可執行檔。gcc -static -o init init.c2)建立引導根目錄映像終端運行:dd if=/dev/zero of=initrd.img bs=4096 count=1024mkfs.ext3 initrd.img
 有提示,輸入y。
關於dd

dd 是 Linux/UNIX 下的一個非常有用的命令,作用是用指定大小的塊拷貝一個檔案,並在拷貝的同時進行指定的轉換。
文法:dd [選項] 
if =輸入檔案(或裝置名稱)。 
of =輸出檔案(或裝置名稱)。 
ibs = bytes 一次讀取bytes位元組,即讀入緩衝區的位元組數。 

...


3)建立rootfs目錄,並掛載mkdir rootfs
sudo mount -o loop initrd.img rootfs

4)在rootfs中添加一些檔案將init拷貝到initrd4M.img的目標根目錄下(因為linux啟動後期會在根目錄中尋找一個應用程式來運行,在根目錄下提供init是一種可選方案)
cp init rootfs/
準備dev目錄:
sudo mkdir rootfs/dev
linux啟動過程中會啟用console裝置:
sudo mknod rootfs/dev/console c 5 1
另外需要提供一個linux根裝置,我們使用ram:
sudo mknod rootfs/dev/ram b 1 0
sudo umount rootfs
至此,一個包含簡單應用程式的根目錄initrd4M.img映像就準備好。mknod 用於製作字元或塊相關檔案

用qemu跑一下:qemu -kernel ../linux-3.9.2/arch/x86/boot/bzImage -initrd initrd.img -append "root=/dev/ram init=/init"

整合busybox

busybox簡介

           BusyBox 是一個整合了一百多個最常用linux命令和工具的軟體。BusyBox 包含了一些簡單的工具,例如ls、cat和echo等等,還包含了一些更大、更複雜的工具,例如grep、find、mount以及telnet。有些人將 BusyBox 稱為 Linux 工具裡的瑞士軍刀。簡單的說BusyBox就好像是個大工具箱,它整合壓縮了 Linux 的許多工具和命令,也包含了 Android 系統的內建的shell。
            BusyBox 將許多具有共性的小版本的UNIX工具結合到一個單一的可執行檔。這樣的集合可以替代大部分常用工具比如的GNU fileutils , shellutils等工具,BusyBox提供了一個比較完善的環境,可以適用於任何小的或嵌入式系統。


下載源碼:http://www.busybox.net/

這裡選擇1.20穩定版。

解壓,終端進入目錄執行:

make menuconfig

勾選下面的選項:

Build Options
Build BusyBox as a static binary (no shared libs)

這個選項是一定要選擇的,這樣才能把busybox編譯成靜態連結的可執行檔,運行時才獨立於其他函數庫.否則必需要其他庫檔案才能運行,在單一個linux核心不能使他正常工作.

現在直接make的話會報錯:‘RLIMIT_FSIZE’ undeclared

論壇上的回答是沒有包含  sys/resource.h,則在include/libbb.h 中添加:

#include <sys/resource.h>

接下來執行:

#編譯busybox

make 

#安裝busybox
make install 

 

安裝好之後在檔案夾下出現一個_install檔案夾,編譯完成。

下面來整合根檔案系統。

建立一個檔案夾,終端cd進去,將之前的initrd.img拷貝進來。

#建立檔案夾

mkdir rootfs

#掛載鏡像

sudo mount -o loop initrd.img rootfs/ 

#將busybox添加進來

cd ../busybox-1.20.2/

sudo make CONFIG_PREFIX=../Opuntu/rootfs/ install

#查看rootfs中結構

cd ../Opuntu

ls rootfs

 #卸載分區

sudo umount rootfs/

運行命令時注意目錄結構!

linux的系統下的目錄都是幹嘛的?

linux下的檔案結構,看看每個檔案夾都是幹嗎用的
/bin 二進位可執行命令 
/dev 裝置特殊檔案 
/etc 系統管理和設定檔 
/etc/rc.d 啟動的設定檔和指令碼 
/home 使用者主目錄的基點,比如使用者user的主目錄就是/home/user,可以用~user表示 
/lib 標準程式設計庫,又叫動態連結共用庫,作用類似windows裡的.dll檔案 
/sbin 系統管理命令,這裡存放的是系統管理員使用的管理程式 
/tmp 公用的臨時檔案儲存體點 
/root 系統管理員的主目錄(呵呵,特權階級) 
/mnt 系統提供這個目錄是讓使用者臨時掛載其他的檔案系統。 

...


最後產生的 initrd.img檔案就是根檔案系統了!

#qemu測試

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

裝載好之後可以在qemu中運行busybox的命令,效果如下:

整合grub

關於Grub

        GNU GRUB(簡稱“GRUB”)是一個來自GNU項目的多作業系統啟動程式。GRUB是多啟動規範的實現,它允許使用者可以在電腦內同時擁有多個作業系統,並在電腦啟動時選擇希望啟動並執行作業系統。GRUB可用於選擇作業系統分區上的不同核心,也可用於向這些核心傳遞啟動參數。

首先來測試一下grub.

從ftp://alpha.gnu.org/gnu/grub/下載GRUB Legacy的最後一個版本0.97的編譯好的檔案grub-0.97-i386-pc.tar.gz.

解壓之後中端cd進去,執行下面的命令。

#建立磁碟片映像:
dd if=/dev/zero of=boot.img bs=512 count=2880
#在boot.img中安裝grub:
sudo losetup /dev/loop0 boot.img
sudo dd if=./grub-0.97-i386-pc/boot/grub/stage1 of=/dev/loop0 bs=512 count=1
sudo dd if=./grub-0.97-i386-pc/boot/grub/stage2 of=/dev/loop0 bs=512 seek=1
sudo losetup -d /dev/loop0

在qemu中測試是否可以進入grub

qemu -fda boot.img

OK.

接下來將grub,kernel,busybox一起整合,離勝利只還有一步 - - 。

先你自己發行版取一個庫一些的名字,比如Opuntu...(Opensuse+ubuntu),建立一個以它命名的檔案夾。

#拷貝boot.img到目前的目錄

sudo cp ../grub-0.97-i386-pc/boot.img ./

#建立rootfs檔案夾

mkdir rootfs

#建立一個32M的磁碟鏡像檔案
dd if=/dev/zero of=/dev/zero of=Opuntu.img bs=4096 count=8192
#給磁碟映像分區
fdisk -C 16065 -H 255 -S 63 Opuntu.img

解釋:設定Opuntu.img的磁頭數為255、磁軌數為16065、扇區數為63,同時給磁碟分割。
這裡我們只分一個區,並設定該分區為引導分區。如下:

#格式化分區
sudo losetup -o 1048576 /dev/loop0 Opuntu.img

sudo mkfs.ext3 -m 0 /dev/loop0

解釋:我們把前面的2048個扇區(0~2047)作為開機磁區使用,格式化分區從第2048個扇區開始,所以1048576=2048*512

#拷貝之前做好的initrd.img和bzImage.img到rootfs

sudo mount /dev/loop0 rootfs/
sudo cp ../linux-3.9.2/arch/x86/boot/bzImage ./rootfs/
sudo cp ../rootfs/initrd.img ./rootfs/

#添加grub

sudo mkdir rootfs/boot
sudo mkdir rootfs/boot/grub

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

內容:

default 0timeout 30title linux on 32M.imgroot (hd0,0)kernel (hd0,0)/bzImage root=/dev/ram init=/bin/ashinitrd (hd0,0)/initrd.img

#卸載磁碟鏡像

sudo umount rootfs
sudo losetup -d /dev/loop0

#利用grub啟動磁碟片,在硬碟映像上添加grub功能
qemu -boot a -fda boot.img -hda Opuntu.img

執行圖中的兩步(注意空格):

運行成功之後,Opuntu.img就是我們的最終成果了,整合了busybox,grub,linux kernel3.92!

qemu -hda Opuntu.img

用qemu跑起來:

參考:

鳥哥私房菜 第二十二章:開關機流程與loader

製作可用grub引導Linux系統的磁碟映像檔案 - http://blog.sina.com.cn/s/blog_70dd169101013gcw.html

詳細講解Linux啟動流程及啟動用到的設定檔及指令碼 - http://guodayong.blog.51cto.com/263451/1168731

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.