製作linux包 u盤安裝
一、準備核心
首先要有一個能用的 Linux 宿主機,我使用的是 Ubuntu 16.04。然後安裝好編譯時候用到的庫和軟體包,由於我的 Ubuntu 16.04 是使用過一段時間的,可能有一些軟體包或者庫我之前已經裝過了,所以沒有列舉出來,下面是一些我能想到的,其它我沒有想到的可以直接把錯誤資訊放進百度,查詢缺少的包的資訊然後再安裝。開啟命令列,輸入:
sudo apt-get update sudo apt-get upgrade sudo apt-get install libncurses5-dev libncursesw5-dev sudo apt-get install ncurses-devel sudo apt-get install gcc sudo apt-get install vim sudo apt-get install wget
在普通使用者下輸入
cd ~
進入使用者目錄,輸入
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.11.1.tar.xz
等待進度條走到 100%,此時一個完整的 linux 核心原始碼包就放在你的使用者目錄下。輸入
xz -d linux-4.11.1.tar.xz
tar xvf linux-4.11.1.tar
cd linux-4.11.1
這樣一個解壓好的原始碼包就放在了使用者目錄下。
二、編譯配置核心
此時確認在核心目錄下,輸入
pwd
顯示
/home/song/linux-4.11.1
輸入
make x86_64_defconfig make menuconfig
會出現一個視窗
把第二項 Enable Loadable module support 取消掉,把 Networking support 取消掉。
然後選中 Device Devices(裝置驅動) -> Block devices 下的 loopback device support, RAMblock device support
選擇Device Devices->SCSI Support 下的 SCSI device support 下的SCSI disk Support、 SCSI low-level drivers ---> Buslogic SCSI support
選擇Device Devices->USB Support 下的Support for Host-side USB,Preliminary USB device filesystem ,USB Mass Storage support。另外,還需要選EHCI HCD (USB 2.0) support。Preliminary USB device filesystem 沒找到這個選項
然後輸入 make bzImage
編譯過程十分漫長,看個電影再說吧、需要的記憶體也很大。
linux-4.11.1 file arch/x86/boot/bzImage
arch/x86/boot/bzImage: Linux kernel x86 boot executable bzImage, version 4.11.1 ([email protected]) #1 SMP Sat May 20 12:41:40 CST 2017, RO-rootFS, swap_dev 0x4, Normal VGA
3.準備 BusyBox工具
命令列輸入
wget https://busybox.net/downloads/busybox-1.26.2.tar.bz2
下載完成之後輸入
tar -jxvf busybox-1.26.2.tar.bz2
cd busybox-1.26.2/
在命令列輸入
make defconfig
make menuconfig
開始配置將一些必要的選項打[*]或[ ]:
BusyBox Setting->Build Options->[*]Build Busybox as a static binary (no shared libs)
BusyBox Setting->Shells->chose your default shell(ash):
[*]ash
編譯BusyBox,命令列輸入 make
成功提示
LINK busybox_unstripped
Static linking against glibc, can't use --gc-sections
Trying libraries: crypt m
Library crypt is not needed, excluding it
Library m is needed, can't exclude it (yet)
Final link with: m
DOC busybox.pod
DOC BusyBox.txt
DOC busybox.1
DOC BusyBox.html
安裝BusyBox,命令如下:
make install
執行完後會產生_install/bin/ 和_install/sbin/後面會用到這些檔案
部分提示:
busybox-1.26.2 make install
./_install//bin/ash -> busybox
./_install//bin/base64 -> busybox
./_install//bin/cat -> busybox
./_install//bin/catv -> busybox
./_install//bin/chattr -> busybox
./_install//bin/chgrp -> busybox
./_install//bin/chmod -> busybox
./_install//bin/chown -> busybox
./_install//bin/conspy -> busybox
./_install//bin/cp -> busybox
./_install//bin/cpio -> busybox
./_install//bin/cttyhack -> busybox
./_install//bin/date -> busybox
./_install//bin/dd -> busybox
./_install//bin/df -> busybox
./_install//bin/dmesg -> busybox
./_install//bin/dnsdomainname -> busybox
./_install//bin/dumpkmap -> busybox
./_install//bin/echo -> busybox
./_install//bin/ed -> busybox
./_install//bin/egrep -> busybox
./_install//bin/false -> busybox
ls 下會發現多了一個 _install 目錄,裡面是bin、sbin和usr,我們要用它來構建linux的根目錄。
4.無盤 linux 的執行準備
首先在使用者目錄下新建一個資料夾romfs,然後把_install目錄中的內容全部複製到romfs中。
➜ busybox-1.26.2 cd ~
➜ ~ pwd
/home/song
➜ ~ mkdir romfs
➜ ~ cp -r busybox-1.26.2/_install/* romfs/
現在rootfs下已經有了bin、sbin、usr目錄,好像還缺什麼。現在來新增:
➜ romfs mkdir proc mnt var tmp dev sys etc
同時在romfs下還必須要有一個init檔案,這個init檔案可以是一個可執行的二進位制檔案,也可以是一個shell指令碼,或者是指向前面兩者的連結。init檔案會在linux核心初始化就緒後被執行。方便起見,我們就把init做成一個指向bin/sh的軟連線:
➜ ~ cd romfs/
➜ romfs ln -s bin/sh init
dev目錄下還必須有幾個必要的裝置console,null,tty,tty1,tty2,tty3,tty4:
➜ romfs cd dev/
➜ dev sudo mknod console c 5 1
➜ dev sudo mknod null c 1 3
➜ dev sudo mknod tty c 5 0
➜ dev sudo mknod tty1 c 4 1
➜ dev sudo mknod tty2 c 4 2
➜ dev sudo mknod tty3 c 4 3
➜ dev sudo mknod tty4 c 4 4
這些tty就是和使用者互動的終端。
製作 壓縮映象。
➜ dev cd ~/romfs/
➜ romfs find . | cpio -H newc -o > ../romfs.img
5157 塊
➜ romfs cd ../
➜ ~ gzip romfs.img -f
5.在優盤上建立根檔案系統
5.1 在優盤上建立Linux分割槽和ext3檔案格式
把優盤插入物理機,在vmware右下角,點選優盤圖示選擇連線主機
開啟命令列,輸入
sudo fdisk -l
優盤裝置為 /dev/sdb1
格式化優盤,命令列輸入
sudo fdisk /dev/sdb
出現
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
命令(輸入 m 獲取幫助):
輸入 d 刪除原來的分割槽,原來有幾個分割槽就輸入幾次d。直到出現 No partition is defined yet!
命令(輸入 m 獲取幫助): d
Selected partition 1
Partition 1 has been deleted.
命令(輸入 m 獲取幫助): d
No partition is defined yet!
Could not delete partition 1
輸入n 建立新的分割槽
命令(輸入 m 獲取幫助): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):
輸入 p
Select (default p): p
分割槽號 (1-4, default 1):
輸入 1
分割槽號 (1-4, default 1): 1
First sector (2048-30218841, default 2048):
剩下的回車預設
First sector (2048-30218841, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-30218841, default 30218841):
Created a new partition 1 of type 'Linux' and of size 14.4 GiB.
命令(輸入 m 獲取幫助):
輸入p檢視是否分割槽成功
命令(輸入 m 獲取幫助): p
Disk /dev/sdb: 14.4 GiB, 15472047104 bytes, 30218842 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x35ca5e88
裝置 啟動 Start 末尾 扇區 Size Id 型別
/dev/sdb1 2048 30218841 30216794 14.4G 83 Linux
命令(輸入 m 獲取幫助):
輸入w儲存退出
命令(輸入 m 獲取幫助): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
輸入
ls /dev | grep sd
可以看到有了 sdb1,這是我們要裝系統用的分割槽,下面格式化分割槽,製作檔案系統。
mkfs.ext3 /dev/sdb1
➜ ~ sudo mkfs.ext3 /dev/sdb1
mke2fs 1.42.13 (17-May-2015)
/dev/sdb1 contains a ext2 file system
last mounted on /media/song/d96c0389-5965-453f-8091-39a778eb778f on Sat May 20 15:01:03 2017
無論如何也要繼續? (y,n) y
Creating filesystem with 3777099 4k blocks and 944704 inodes
Filesystem UUID: db1cf942-3250-439b-a1ef-773104282c01
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Allocating group tables: 完成
正在寫入inode表: 完成
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成
然後可以把U盤掛載入檔案系統,進行檔案操作。
sudo mkdir /mnt/usb
sudo mount /dev/sdb1 /mnt/usb
linux 要想啟動,還需要一個類似bootloader的程式,它負責解壓並複製initrd到記憶體指定的位置,和解壓並複製核心到記憶體的指定位置,然後jump到核心的入口地址,並告訴核心initrd在哪裡。它通常分為兩個部分。
第一部分是一個短於512位元組的程式碼,這一段程式碼被放在磁碟的第一個扇區,也就是磁碟能夠讀寫的部分的前512位元組,這512位元組被稱作引導區。這512位元組內,除了bootloader的程式碼外,還有64位元組用來存放分割槽表,所以bootloader的程式碼更是少的可憐。這段程式碼做不了什麼複雜的事情,就只包含一個極其簡陋的硬碟驅動程式,找到這塊磁碟上的bootloader的第二階段的程式碼,複製第二階段的程式碼到記憶體,然後jump到第二階段的程式碼的入口地址,執行之。
第二階段的程式碼就複雜多了,它包含各種硬體(尤其是硬碟)與檔案系統的驅動程式。它建立一個較完善的檔案系統,然後從檔案系統中讀取核心與initrd,然後執行核心。
在PC機上,最流行的bootloader就是grub。它的第一部分在引導區中,第二部分在/boot/grub/中。
安裝 grub
sudo grub-install --root-directory=/mnt/usb /dev/sdb
➜ ~ sudo grub-install --root-directory=/mnt/usb /dev/sdb
Installing for i386-pc platform.
Installation finished. No error reported.
這條命令會把grub安裝到/dev/sdb中,即把grub的第一階段(短於512位元組的部分)放入/dev/sdb的第一扇區,並且把第二階段要用到的各種檔案放到當前目錄(即/dev/sdb1分割槽承載的ext3檔案系統)(更準確的說,是放在了/dev/sdb1/boot/grub,即/root/udisk/boot/grub目錄下)。
然後再把過去做好的bzImage和rootfs.img.gz複製到udisk的boot目錄下
➜ ~ sudo cp linux-4.11.1/arch/x86/boot/bzImage /mnt/usb/boot/
➜ ~ sudo cp romfs.img.gz /mnt/usb/boot/
最後就是編輯一下grub.conf配置檔案:
sudo vim /mnt/usb/boot/grub/grub.cfg
輸入
menuentry "songwenshuai-linux" {
set root='hd0,msdos1'
linux /boot/bzImage root=/dev/ram
initrd /boot/romfs.img.gz
}
儲存後,解除安裝U盤:
sudo umount /mnt/usb
拔出優盤製作成功。
更改 bios 的 boot讓它從優盤啟動。
結果
遇到的關鍵問題:
最開始的 grub.cfg 中的
set root='hd0,msdos1'
配置錯誤,在 grub 下輸入 ls
得到正確資訊改正後執行正確。
轉載註明出處