我試著做了個 USB Flash disk Linux,把一些心得寫下來,
因為是第一次做,所以可能有觀念錯誤的地方,希望各位學長姐不另賜教 Thx

(好文感謝!謝謝thyme先輩!
http://phorum.study-area.org/index.php/topic,42847.0.html)
(文中用了很多"你",不好意思,這是種自言字與的表達方式 哈)
---------------------------------------------------------------------------------------------------------
Element: syslinux + kernel(2.6.15) + initrd.img + busybox(1.17.1) + gcc(3.4.6)
環境:gcc(3.4.6)、Ubuntu(9.04)
硬體:USB 讀卡機 mini SD 4GB
[ syslinux ]
這是一個給FAT(16/32)的 Bootloader(因此隨身碟必須格式化為FAT),
Syslinux Wiki:http://syslinux.zytor.com/wiki/index.php/The_Syslinux_Project
可以下載,裡面提供一些軟體幫助你做bootloader安裝的動作,我用的就是"syslinux"指令,
Ubuntu 9.04 似乎有預設安裝他,所以我就直接用了。
指令:syslinux /dev/sdb1
sdb1 是我的讀卡機。注意,在執行該指令時必須先umount!
當指令完成時再掛載,你會發現硬碟內多了個 "ldlinux.sys" 這就完成了。
syslinux 需要一個設定檔來作bootloader控制以及建立選單,檔名叫 "syslinux.cfg"
這要手寫,我的內容如下
-------------------------------------------------------
TIMEOUT 20
DEFAULT linux
LABEL linux
KERNEL bzImage
APPEND root=/dev/ram0 initrd=initrd.img
-------------------------------------------------------
TIMEOUT:選單等候時間
DEFAULT:預設哪一個啟動選項
LABEL:建立一個啟動選項名稱為 "linux"(例),其後的縮排就是該選項的設定
KERNEL:核心檔案路徑
APPEND:bootloader 控制指令,這裡指的是
將根目錄掛載至 /dev/ram0 上,也就是以ram disk的方式呈現
如此一來每次啟動所做的更動都會在關機時消失。
initrd=initrd.img 指的是 initrd的檔案名稱。
[ busybox 1.17.1 ]
2010.08.12,這是當時載到最新的穩定版,相合的核心是 2.6.15,
這引發了很多相容問題。編時 gcc 使用 3.4.6 版本。
指令:
$make
$make CONFIG_PREFIX=(安裝路徑) install
--> 用這個動作把 busybox 丟入要做成 initrd.img 的資料夾。
[ gcc 3.4.6 ]
原本 Ubuntu 9.04 提供的 gcc 是 4.4.1,但是跟 busybox 1.17.1 較合的來的是
核心 2.6.15,而這個版本需要還沒越過 4.x 的 gcc,所以我載了 3.4.6 來編。
指令:
$make “CFLAGS=-U_FORTIFY_SOURCE”
-> 因為我是用 4.4.1 來編 3.4.6,3.4.6 原始碼少了 4.4.1 需要的元素,
用這個FLAGS來略過。
$make install --> 安裝。這也會使你的 "gcc" 指令預設指到 版本 3.4.6
[ kernel 2.6.15 ]
原本打算用最新版本 2.6.35 的,但是為了 busybox 相容些,而改用 2.6.15。
編時 gcc 使用 3.4.6 版本。
指令:
$make clean -> 好習慣要從小養成
$make defconfig -> 以預設執建立 .config
$make menuconfig -> 將 Device Driver 下的 USB 全部囊括起來!
(好吧,我承認這很粗魯~)
$make all -> 編核心、映像檔、模組。(Time to bed)
這時你應該要在 (kernel source path)/arch/(cpu type)/boot
下看到 bzImage。
$make modules_install -> 將模組安裝至 /lib/modules/(kernel version)
這樣在建立 initrd.img 時才可以正確的打包module。
[ initrd.img ]
我直接使用 Ubuntu 9.04 提供的 mkinitramfs 建立我所要的 initrd.img,
指令:
$mkinitramfs -o (完成檔案路徑) (核心版本)
ex: $mkinitramfs -o ./initrd.img 2.6.15
完成的 initrd.img 是一個 gz 檔,裡面還包一層 cpio 包裝,而syslinux似乎只買這種帳?
拆解指令:
$mv ./initrd.img ./initrd.img.gz -> 附檔名不改成 .gz ,gunzip 是不會買帳的
$gunzip ./initrd.img.gz
$cpio -idv < ./initrd.img -> cpio 的指令方式跟一般不一樣,有點不習慣
會發現 該資料夾已經把 initrd.img 內的東西都掏出來了。
這時就可以開始修改裡面的內容,包含丟入 busybox 元件。因為我這次掛載的是 /dev/ram0,
所以大小似乎是受限的 (測試時 < 80 MB 是OK的),所以也別太貪心。
打包指令:
$find . | cpio -o -H newc | gzip > ./initrd.img
如果一切順利,這個新生成的 initrd.img 就是我們要的東西了。
最後的最後,把bzImage、initrd.img 丟進 SD 卡內,完成!
SD卡內應該有:
bzImage
initrd.img
ldlinux.sys
syslinux.cfg
---------------------------------------------------------------------------------------------------------