1. 程式人生 > >製作linux包 u盤安裝

製作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

得到正確資訊改正後執行正確。

轉載註明出處