1. 程式人生 > >第一步,用qemu啟動linux核心,從跑個Helloworld開始

第一步,用qemu啟動linux核心,從跑個Helloworld開始

       老生長談的內容了,就是自己編譯核心,然後製作initramfs,在用qemu跑
起來。不過在這之前先跑個helloworld玩玩。

順便我在學校寫部落格的筆記本系統是ubuntu16.04,在實習單位玩的時候用的系統是centos7,兩個不同的地方我會盡量說明,當然有些地方我自己也不是很清楚就是了。

編譯核心

#  建一個目錄
$  mkdir build
#    首先當然是去下一個linux核心,地址,  我這裡選的版本是3.10.104
$    wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.10.104.tar.xz
#   解壓
$    tar xvf linux-3.10.104.tar.xz  
$    cd linux-3.10.104 
$    make menuconfig


  進行核心選項配置,其中的內容非常多,我也沒看完,但是由於這次我們什麼都用不到,也不用編譯模組,可以把Device Driver裡絕大部分和一些不常用的東西都勾選掉.具體配置自己參照網上吧,也可以直接用別人配好的設定直接覆蓋.  為了方便務必把debug info 勾選上.
#    -j8的選項是為了讓編譯更快點,一般這數字選擇為cpu核數*2.
$    make -j8 
#    ls -la  linux-3.10.104/arch/x86_64/boot/bzImage  
lrwxrwxrwx 1 seijia seijia 22 12月 17 23:52 linux-3.10.104/arch/x86_64/boot/bzImage -> ../../x86/boot/bzImage
$    cp linux-3.10.104/arch/x86_64/boot/bzImage  ..
#  安裝qemu,可以自己去下原始碼安裝,我比較懶直接用apt-get安裝了
$   sudo apt-get install qemu


製作initrd
/*hello.c*/
#include <stdio.h>


void main()
{
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
  /*強制重新整理輸出,不然可能打印不出來*/
    fflush(stdout);
    while(1);
}



initrd吧,全稱是initial ramdisk,在核心啟動的時候會先去載入的一種檔案系統.
$    cd ..
#    使用靜態編譯連結.
$    gcc -static -o helloworld hello.c
#    將helloworld製作成cpio
$    echo helloworld | cpio -o --format=newc > rootfs
1776 blocks
$    ls -la rootfs 
-rw-rw-r-- 1 seijia seijia 909312 12月 21 13:15 rootfs
# 使用qemu進行啟動
$    qemu-system-x86_64   \
     -kernel ./bzImage \
     -initrd ./rootfs  \
     -append "root=/dev/ram rdinit=/helloworld"


  qemu的-kernel 和-initrd能夠繞過bootload直接對指定的kernel和ramdisk進行載入.用-append進行額外的選項配置,在這裡我們把根目錄直接設定成記憶體,啟動的init程式設定成放進去的helloworld.


最後結果,因為while(1),啟動會一直停在這裡.
當然只有helloworld我們是什麼都做不了的.這時候就需要busybox了,用它啟動之後就能使用絕大多數的linux命令了.如果有不對的地方歡迎指出,不過我這麼一個小部落格也沒人看吧(敲打
第一次這個編輯器花了很久才會用,第一次寫格式全崩了...