自制小型linux系統
分析得知:
- 引導grub,內核和initramfs三樣不可缺乏。
- 執行的第一個進程/sbin/init由於須要的配置文件太多也不必,咱們能夠直接進入系統後第一個進程改成bash shell(讓/sbin/init指向它)
- 安裝(拷貝)須要的軟件程序到這個linux系統中(包括它須要的庫文件等),這樣一個簡單的liunx系統便完成了。
具體步驟
- 分區並建立文件系統
fdisk /dev/sdb
分兩個必要的分區
/dev/sdb1對應/boot /dev/sdb2對應根 /
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2
(mkswap /dev/sdb3)
- 掛載boot
mkdir /mnt/boot
- 子目錄的目錄名必須爲boot,父目錄沒要求但下面要指明父目錄(由於要用--root,詳細查看man幫助grub)
mount /dev/sdb1 /mnt/boot (能夠不掛載根/dev/sdb2)
- 安裝grub
grub-install --root-directory=/mnt /dev/sdb
- 恢復內核和initramfs文件
- 也能夠kernel安裝包安裝,rpm --root=/dev/sdb2 --nodeps,不過這樣會沒有initramfs文件,由於腳本會執行錯誤,因此還得手動生成它,不如直接拷貝
- 或者更好的方法是yum --installroot=/dev/sdb2 install kernel.x86_64 ,前提是配置了yum源,這樣作不只能裝好根和initramfs等,還能建立好許多必要的文件夾。
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/
cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot
- 創建grub.conf
vim /mnt/boot/grub/grub.conf
- 注意有細微的幾項差異,以及注意了在這裏寫的root是sda2(雖然當前是sdb2,可是拆掉此設備到其餘機器上時就是sda2了)
title simple_linux
root (hd0,0)
kernel /vmlinuz-2.6.32-642.el6.x86_64 root=/dev/sda2
selinux=0 :selinux關閉
init=/bin/bash :指定bash
initrd /initramfs-2.6.32-642.el6.x86_64.img
chroot /mnt/sysroot
- 建立一級目錄
mkdir /mnt/sysroot
mount /dev/sdb2 /mnt/sysroot
mkdir –pv /mnt/sysroot/{etc,lib,lib64,bin,sbin,tmp,var,usr,sys,proc,opt,home,root,boot,dev,mnt,media}
- 複製bash和相關庫文件(利用編寫的cpcmd腳本)
- 複製相關命令及相關庫文件
如:ifconfig,insmod,ping,mount,ls,cat,df,lsblk,blkid等
- 注意複製的時候也是要建立一個文件夾,而後把未來要做爲根分區的分區(sdb2)掛載上去,而後把cpcmd腳本中的目標目錄改成此文件夾,進行拷貝便可。
- 固然最好仍是用busybox。
注意點
- 仍是用yum安裝內核的方式比較好,由於它會把全部的模塊也給安裝上,這樣的話網絡功能也可以啓用,只須要進入bash shell以後把網絡驅動給載入便可(能夠嘗試下用init啓動)。
- insmod e1000.ko 命令來加載模塊,注意要提早拷貝這個模塊。
- 若是想要開機以後能把除了根以外的boot分區掛載上(包括其餘分區),以及啓動網絡功能進行各類初始化操做。能夠直接在grub.conf中的init=/bin/bash中本身寫一個bash腳本,而後添加上各類初始化設置,讓init指向它便可(固然也要把本來的bash給添加到這個腳本里面,就至關於再原來的bash腳本基礎上增添一些操做)
內核編譯
單內核體系設計、但充分借鑑了微內核設計體系的優勢,爲內核引入模塊化機制node
- 內核組成部分:
kernel:內核核心,通常爲bzImage,一般在/boot目錄下名稱爲 vmlinuz-VERSION-RELEASE
kernel object:內核對象,通常放置於/lib/modules/VERSION-RELEASE/
[ ]: N :表明不啓用此功能
[M]: M :啓用此功能可是會把模塊放在lib/modules中
[*]: Y :啓用功能並將模塊放在vmlinuz中
- 輔助文件:ramdisk
initrd
initramfs
前提:
(1) 準備好開發環境
(2) 獲取目標主機上硬件設備的相關信息
(3) 獲取目標主機系統功能的相關信息
例如:須要啓用相應的文件系統
(4) 獲取內核源代碼包
www.kernel.orglinux
開發環境準備
- 包組
Development Tools
- 目標主機硬件設備相關信息
CPU:
cat /proc/cpuinfo
x86info -a
lscpu
硬件設備
- PCI設備:
lspci
-v
-vv
lsusb
-v
-vv
lsblk 塊設備
- 瞭解所有硬件設備信息
hal-device:CentOS 6
安裝系統
安裝開發包組
下載源碼文件
.config:準備文本配置文件
make menuconfig:配置內核選項
make [-j #]
make modules_install:安裝模塊
make install :安裝內核相關文件
安裝bzImage爲/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
編輯grub的配置文件c++
編譯內核示例
tar xf linux-VERSION.tar.xz -C /usr/src
cd /usr/src
#n -sv linux-4.20.2 linux
cd /usr/src/linux-VERSION
cp /boot/config-$(uname -r) ./.config
make help
make menuconfig :須要安裝一些包才能執行此命令
make -j 2
make modules_install
make install
reboot
編譯內核
-
配置內核選項
支持「更新」模式進行配置:make help
(a) make config:基於命令行以遍歷的方式配置內核中可配置的每一個選項
(b) make menuconfig:基於curses的文本窗口界面
(c) make gconfig:基於GTK (GNOME)環境窗口界面
(d) make xconfig:基於QT(KDE)環境的窗口界面
支持「全新配置」模式進行配置
(a) make defconfig:基於內核爲目標平臺提供的「默認」配置進行配置
(b) make allyesconfig: 全部選項均回答爲「yes「
(c) make allnoconfig: 全部選項均回答爲「no「shell
- 編譯
全編譯:make [-j #]
編譯內核的一部分功能:
(a) 只編譯某子目錄中的相關代碼
cd /usr/src/linux
make dir/
(b) 只編譯一個特定的模塊
cd /usr/src/linux
make dir/file.ko
示例:只爲e1000編譯驅動:
make drivers/net/ethernet/intel/e1000/e1000.ko
如何交叉編譯內核:
編譯的目標平臺與當前平臺不相同
make ARCH=arch_namevim
- 要獲取特定目標平臺的使用幫助
make ARCH=arch_name help
示例:
make ARCH=arm help
在已經執行過編譯操做的內核源碼樹作從新編譯
須要事先清理操做:
make clean:清理大多數編譯生成的文件,但會保留config文件等
make mrproper: 清理全部編譯生成的文件、 config及某些備份文件
make distclean:mrproper、清理patches以及編輯器備份文件bash
卸載內核
刪除/lib/modules/目錄下不須要的內核(對應內核的module)庫文件
(刪除/usr/src/linux/目錄下不須要的內核源碼:根據本身裝的源碼位置來刪除)
刪除/boot目錄下啓動的內核和內核映像文件
更改grub的配置文件,刪除不須要的內核啓動列表(6中手寫title的項目刪除,而7中在完成了前面步驟以後直接grub2-mkconfig從新生成就會自動刪除掉去掉的內核項)網絡
注意點:
- 內核由於配置項太多,所以用菜單模式來選擇。咱們能夠參考已有的文本配置文件來生成菜單並進行修改。
- 這個已有的文本配置文件就是在已經編譯安裝好的linux內核中boot文件夾中的config_VERSION文件
- 其中y表明打入內核,m表明模塊中,not set並註釋就表明沒有啓動此功能。
- 將此已經存在的配置文件拷貝並命名爲.config做爲參考來執行下一步的make menuconfig
- 本身編譯內核可將NTFS文件系統功能給啓用,修改的時候用菜單方式修改(須要利用1中說的參考的文本配置文件,否則項目太多一個一個改也麻煩也不現實)
- 安裝時分爲安裝模塊和安裝內核兩步。
- 一個linux系統中能夠同時裝多個內核,所以直接編譯安裝新內核便可。
- 以前作過rpm安裝內核包的實驗,boot中會出現兩個內核文件和相對應的initramfs.img,以及lib/modules中也會出現兩個內核版本文件夾。
- 開機的時候選擇載入哪一個內核便可,(若是是手動添加的內核,固然這須要修改grub.conf中的設置,新加一個title便可。用命令make modules_install和make install命令添加的自動就會添加到grub.conf(或grub.cfg)文件中)
- make menuconfig須要安裝一些依賴的包才能執行,根據提示一個一個裝
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel
openssl openssl-devel systemd-devel zlib-devel vim lrzsz tree screen lsof tcpdump wget ntpdate net-tools iotop bc zip unzip nfs-utils
- menu通用設置中的local version能夠本身書寫一下,其中寫的就是內核中前面主版本號後面寫的內容。注意最開頭處加上橫槓-比較好,好比-myversion-1.0.
- 修改須要修改的項目好比NTFS以後保存,而後就會修改掉.config文件。以後便會根據它進行編譯。能夠查看一下它是否確實修改了。
- 以後make -j N && echo -e "\a"進行編譯 便可(最好session或者nohup).若是報錯須要某些文件包則先裝好,而後再嘗試。
- 若是隻爲了NTFS,NTFS文件格式的支持在epel源中有包能夠進行操做。會多一個mount.ntfs命令,對NTFS格式文件系統的分區進行掛載以後即可可讀可寫。
Busybox
定製小型的Linux操做系統:linux內核+busybox(安卓手機就是相似如此)
官方網站:https://busybox.net/
busybox命令可能選項比較少,不過也基本夠用。同時它還集成了庫文件,不用再另外安裝拷貝了。session
Busybox使用
busybox 的編譯過程與Linux內核的編譯相似
busybox的使用有三種方式:tcp
- busybox後直接跟命令,如 busybox ls
- 直接將busybox重命名,如 cp busybox tar
- 建立符號連接,如 ln -s busybox rm
busybox的安裝
以上方法中,第三種方法最方便,但爲busybox中每一個命令都建立一個軟連接,至關費事,busybox提供自動方法:busybox編譯成功後,執行make install,則會產生一個_install目錄,其中包含了busybox及每一個命令的軟連接編輯器
編譯Busybox
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel libmcrypt-devel glibc-static ncurses-devel
wget https://busybox.net/downloads/busybox-1.30.0.tar.bz2
tar xvf busybox-1.30.0.tar.bz2
cd busybox-1.30.0/
make menuconfig
- 注意,在menu中按下面選擇,把busybox編譯成靜態二進制、不用共享庫,這樣的話這些二進制文件所須要的庫文件就會被打包集成在busybox中了而不是在當前操做系統的lib中
- busybox自己就是一個程序,只不過功能衆多而已,被視爲多個程序的組合。實質上就是一個程序,要理解靜態編譯在這裏的做用)
- 此時直接拷貝在其它機器上這個busybox也能執行了:
Busybox Settings -->Build Options -->[*] Build BusyBox as a static binary (no shared libs)
而後繼續下面命令
make :只生成二進制文件不生成軟連接
make install :把軟連接也生成,之後執行命令就方便了
- 若是出錯,執行make clean後,從新執行上面命令
mkdir /mnt/sysroot/
cp -a _install/* /mnt/sysroot/ :真正的busybox就在_install/bin/busybox 其餘的在此目錄內的命令都是軟連接
Busybox也可直接下載編譯好的二進制,在官網上有。