編譯Linux核心並執行乙個最小映象

2021-08-14 02:30:17 字數 4783 閱讀 9452

公司的專用伺服器使用自定義linux核心,執行乙個由busybox構成的最小映象. 由於某些原因, 使用的核心來自其他人已經編譯好的,並且也拿不到配置檔案。 現在需要:

1. 新增某個專用驅動到核心中,並且新增一些指令碼到新的系統執行映象包initrd中

2. 相容以前的系統映象,不能出現使用舊的核心搭配新映象時無法啟動的問題

linux啟動過程之initrd

bootloader 之 extlinux

編譯linux核心的方法

核心編譯時如何選擇系統自帶的驅動

如何將私有驅動編譯到核心中

啟動核心時,出現 kernel panic - not syncing 的解決辦法

開機後鍵盤無法使用的問題解決

使用busybox製作initrd

機器啟動時,首先是 bios 執行 ,在磁碟的mbr中,找到bootloader。

bootloader執行, bootloader配置檔案會指出系統啟動的某些引數, 比如在**找到 kernel , 在**找到 initrd。

然後開始載入 kernel , 之後載入initrd 進入到 early user space狀態。 initrd 有兩種技術,舊的一種使用映象檔案,叫做 init ram disk , 新的一種使用ramfs歸檔檔案,叫做 init ram filesystem ,可能是由於歷史原因,ubuntu的系統映象雖然是新的技術,但檔名仍然看起來像是舊的 intrd*.

initrd啟動後,如果是舊的技術ram disk,執行的第乙個程式是映象中的 /linuxrc 指令碼 , 如果是新的ram filesytem 執行的第乙個程式是 /init指令碼 , 一般會在指令碼的最後使用 switch_root命令切換根目錄到實際的磁碟根目錄中。

由於我司伺服器的特殊性, 只是把磁碟掛載為 /data 目錄用來儲存資料, 系統仍執行在 initrd 環境下,所以沒有最後這一步。

關於兩種技術的區別, 請參考核心原始碼目錄下 documentation/initrd.txt 和 ibm: linux2.6 核心的 initrd 機制解析

要製作支援initrd的核心參考這個鏈結 csdn:移植linux 核心支援ramdisk

extlinux是一種啟動引導,優點是支援多種啟動介質,配置簡單。

一般用法是

mkdir -p /boot/extlinux

extlinux --install /boot/extlinux

cat mbr.bin > /dev/

***##mbr.bin 在extlinux的安裝目錄下,如果是系統自帶的的則可能在 /usr/lib/extlinux/ 下, 如果沒有,請自行搜尋檔案位置

配置檔案在安裝目錄的 extlinux/extlinux.conf

配置檔案中的引數會傳給核心 ,通過指定特定的的引數, 可以用來除錯核心問題。 系統啟動後可以在 /proc/cmdline 中檢視

/root # cat /proc/cmdline 

vga=0x305 loglevel=3 initrd=/rootfs boot_image=/bzimage

extlinux 官網用法介紹

extlinux.confg 配置檔案詳解

configuring a linux kernel

上面的鏈結說明了如何編譯乙個核心

一般系統的步驟為:

make menuconfig   #該步驟可能會提示缺少 ncurses , apt install libncurses5-dev 即可

#配置好選項, 關於如何配置,參考下一節

make -j4 #開始編譯,指定4個執行緒編譯,根據配置的不同,這裡可能花費幾個小時

make modules_install #安裝模組

make install

#安裝kernel,initrd 並自動更新引導 核心名稱為vmlinuz*

由於公司的伺服器使用busybox最小映象,只需要編譯核心,不需要生成initrd(後面第8節說明如何使用busybox生成initrd), 編譯步驟為:

make menuconfig 

make -j4

make bzimage

將 bzimage 拷貝到伺服器,然後在 extlinux.conf 中指定為 kernel選項的值即可。 或者 extlinux.conf 中kernel的值為乙個符號鏈結, 這樣只需要修改符號鏈結即可

公司伺服器硬體比較特殊, 如果直接使用預設的配置生成bzimage,開機後提示沒有硬碟,同時鍵盤也無法使用,無法進入系統除錯。

如果要去除所有不必要的驅動和功能, 只保留必要的功能,也可參考上面的鏈結

csdn:製作最小linux核心 , 該文章主要用到命令 lspci -v , lsmod , modinfo

鍵盤驅動問題在第7節中專門解決。

在 linux 核心中增加程式需要完成以下三項工作:

1. 將編寫的源**複製到 linux 核心源**的相應目錄

2. 在目錄的 kconfig 檔案中增加新源**對應專案的編譯配置選項

3. 在目錄的 makefile 檔案中增加對新源**的編譯條目

參考這個鏈結

csdn:linux核心開發之將驅動程式新增到核心

舊式 init ram disk initrd的塊大小必須和核心編譯時的值匹配才能啟動

如果你仔細閱讀了第1節,應該不會出現這個 kernel panic。

然而, 由於公司的伺服器核心配置的塊大小未知,並且新編譯的核心要和以前的相容,所以必須知道原來的塊大小是多少. 大致流程為:

1. 生成乙個512k塊大小的系統 , 並把原來的映象檔案拷貝到該映象中

2. 使用該映象作為initrd啟動

3. 檢查核心的出錯資訊並根據該資訊修改塊大小

bash# dd if=/dev/zero of=../initrd.img bs=512k count=100

bash# mkfs.ext2 -f -m0 ../initrd.img

bash# mount -t ext2 -o loop ../initrd.img /mnt

bash# cp -r * /mnt #拷貝需要的檔案到映象

bash# umount /mnt

bash# gzip -9 ../initrd.img

修改initrd為上面生成的壓縮檔案, 重新啟動系統,出現 kernel panic

kernel panic - not syncing :vfs: unable to mount root fs on unknown-block(2,0)

kernel offset:0x0 from 0xffffffff81000000 (relocation randge :0xffffffff80000000-0x0xffffffff9fffffff)

0xffffffff81000000 和 0xffffffff80000000 相差16m, ‭1677721位元組.

在extlinux.conf 檔案中新增配置

重新啟動成功。 因此塊大小應該為 16m .

#make menuconfig

開啟配置選單,修改兩個配置項,分別是:

- general setup–>選擇 initial ram filesystem and ram disk…… 項

- device drivers–>block devices–>選擇 ram block device support 項

- device driver->block device裡的乙個選項,default ramdisk 設定ramdisk的大小‭16777216‬

儲存退出, 重新編譯即可

可能是主機板的原因, 編譯的核心啟動後無法識別鍵盤, 再bootloader能使用的鍵盤,在開機後反而無法使用.

鍵盤驅動問題,請參考這個鏈結

linux-usb

該鏈結說明了 滑鼠/鍵盤/手柄的驅動配置方法

#! /bin/sh

mount -n -t proc proc /proc

## disable console login

grep -q console=null /proc/cmdline && sed -i s/^tty/#tty/ /etc/inittab

## this is a traditional mechanism for initrd

# notify kernel remount /dev/ram0 as root

echo

0x0100 > /proc/sys/kernel/real-root-dev

umount -n /proc

解除安裝映象, 壓縮映象, 請參考第一節

如果使用 ram filesystem , 刪除 /linuxrc 新增 /init

#!/bin/sh

#init

mount -t proc none /proc

mount -t sysfs none /sys

exec /bin/sh

打包所有檔案為 cpio檔案並壓縮

find .

| cpio --quiet -h newc -o

| gzip -9-n

> /boot/initrd.img

參考鏈結

乙個最簡單的Linux核心模組

include include static int init hello init void static void exit hello exit module init hello init module exit hello exit module license gpl 這個最簡單的核心模...

編譯乙個核心模組

1,編寫hello.c include include module license gpl static int init hello init void static void exit hello exit void module init hello init module exit hel...

了解並編譯linux核心

一 核心的功能 1 系統呼叫 2 程序控制 3 記憶體管理 4 檔案系統管理 5 裝置驅動程式 二 編譯linux核心 進入到核心源 目錄 cd usr src linux 2.6.15 make config make xconfig make menuconfig make 三 裁剪linux ...