最近在寫專利,中期答辯前的必備材料還差一篇論文......抽一個週五的晚上來完善一下之前留下的坑,慢慢來吧,先把這些弄完,希望可以在下月中旬之前把論文弄好,然後專心學習...好運
1、Linux根文件系統基本目錄
- /bin : 該目錄存放所有用戶都可以使用的、基本的命令,這些命令可以在掛接其他文件系統之前就可以使用,所以/bin目錄必須跟文件系統在同一個分區中
- /sbin : 該目錄存放基本系統命令(shutdown、reboot等),即只有管理員才能使用的命令,他們用於啓動系統、修復系統等。可以在掛接其他文件系統之前就可以使用這些命令,所以/sbin目錄必須跟文件系統在同一個分區中。
- /dev : 該目錄存放的是設備文件。設備文件是Linux獨有的文件類型,在Linux系統下,以文件的方式訪問各種外設,即通過讀寫某個設備文件操作某個具體硬件。如通過"/dev/ttySAC0"文件可以操作串口0。設備文件有兩種:字符設備(c)和塊設備(b)
- /etc : 該目錄存放各種配置文件。對於PC的Linux系統,/etc目錄下目錄、文件非常多。這些目錄、文件都是可選的,他們依賴於系統中所擁有的應用程序,依賴與這些程序是否需要配置文件。在嵌入式系統中,這些內容可以大爲精減。
- /lib : 該目錄下存放共享庫和可加載模塊(即驅動程序),共享庫用於啓動程序、運行根文件系統的可執行程序,比如/bin、/sbin目錄下的程序。
- /home : 用戶目錄,對於每個用戶,在/home下都有一個以用戶名命名的子目錄,裏面存放用戶相關的配置文件
- /root : 根用戶目錄(用戶名爲root)
- /usr : 該目錄的內容可以存在另一個分區中,在系統啓動後再掛接到根文件系統中的/usr目錄下。裏面存放的是共享、制度的程序和數據。
- /var : 與/usr目錄相反,/var目錄中存放可變的數據,比如spool目錄(mail、news、打印機等),log文件、臨時文件
- /proc : 這是一個空目錄,常作爲proc文件系統的掛接點。proc文件系統是個虛擬的文件系統,他沒有實際的存儲設備,裏面的目錄、文件都是由內核臨時生成的,用來表示系統的運行狀態,也可以操作其中的文件控制系統。
- /mnt : 用於掛接某個文件系統的掛接點,通常是空目錄;也可以在裏面創建一個空目錄的字目錄,比如/mnt/cdram、/mnt/hdal等,用來臨時掛接光盤、硬盤。
- /tmp : 用來存放臨時文件,通常是空目錄。
對於最小busybox根文件系統至少包含下面文件夾:
- /etc/:存儲重要的配置文件。
- /bin/:存儲經常使用且開機時必須用到的運行文件。
- /sbin/:存儲着開機過程中所需的系統運行文件。
- /lib/:存儲/bin/及/sbin/的運行文件所需的鏈接庫,以及Linux的內核模塊。
- /dev/:存儲設備文件。
2、移植busybox文件系統
2.1 什麼是busybox
busybox是一個遵循GPL v2協議的開源項目(busybox官網)。busybox將衆多的UNIX命令集合進一個很小的可執行程序中,可以用來替換GNU fileutils、shellutils等工具集。
busybox中各種命令與相應的GNU工具相比,所提供的選項較少,但能夠滿足一般應用。busybox爲各種小型或者嵌入式系統提供了一個較完全的工具集。
busybox在編寫過程中對文件大小進行優化,並考慮到資源有限的情況。與一般GNU工具集動輒幾MB的體積相比,動態鏈接的busybox只有幾百KB,即使靜態鏈接也只有1MB左右。
busybox按照模塊進行設計,可以很容易的加入、去除某些命令,或者增減命令的某些選項。
在創建最小的根文件系統時,使用busybox的話,只需要在/dev目錄下創建必要的設備節點、在/etc目錄下創建一些配置文件就可以啦,如果busybox使用動態鏈接,還要再/lib目錄下包含庫文件。
busybox支持uClibc和glibc庫,對Linux2.2.x之後的內核支持良好。
2.2 init進程介紹和用戶程序啓動過程
2.2.1 內核如何啓動init進程
init進程是內核啓動的第一個(也是唯一一個)用戶進程(進程號爲1),他根據配置文件決定啓動哪些程序,比如執行某些腳本、啓動shell、運行用戶指定的程序等。init進程是後續所有進程的發起者,比如init進行啓動/sbin/init程序後,才能夠在控制檯上輸入各種命令。
/* linux/init/目錄下init.c文件 */
static noinline int init_post(void)
{
/* 1.
* 啓動標準輸入、輸出、錯誤
*/
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();
current->signal->flags |= SIGNAL_UNKILLABLE;
/* 2.
* ramdisk_execute_command指定了要運行的程序,運行它
* 如果命令行參數指定了rdinit=...,則ramdisk_execute_command等於這個參數指定的程序
* 否則如果/init存在,則ramdisk_execute_command就等於“/init”
* 否則ramdisk_execute_command爲空
*/
if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
/* 3.
* execute_command指定了要運行的程序,運行它
* 如果命令行參數指定了init=...,則execute_command等於這個參數指定的程序
* 否則execute_command爲空
*/
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
/* 4.
* run_init_process()使用它參數所指定的程序來創建一個用戶進程
* 一旦創建成功,它將不會返回
* 4.1
* 首先執行/sbin/init,根文件系統中存在,將跳轉過去執行,不在返回init_post函數
* 4.2
* 如果根文件系統/sbin/init爲空,則執行/etc/init,這個在我們製作的根文件系統是有的,所以跳
* 轉過去執行了
* 4.3
* 在執行/sbin/init時,需要確保根文件系統已經被正確的掛載
*/
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}
2.2.2 busybox init進程啓動過程
2.3 移植busybox(提取密碼:eje6)
2.3.1 編譯安裝busybox
1、解壓
tar jxvf busybox-1.22.1.tar.bz2
2、配置
make menuconfig
Busybox Settings ->
general configuration ->
[*] don't use /usr //選中它 否則會破壞虛擬機
build options->
cross comliler prefix = arm-linux- //選擇交叉編譯工具
3、編譯&安裝
mkdir -p ~/work/my_rootfs //安裝路徑
make
make install CONFIG_PREFIX=~/work/my_rootfs
cd /work/my_rootfs
ls //查看是否安裝成功
編譯安裝完畢之後,我們的文件系統就生成在 ~/work/my_roofs 目錄下了
2.3.2 配置啓動相關
1、創建 /etc/inittab(必須的,如果想簡單測試,只需要保留console::askfirst:-/bin/sh,同時下面只要按照紅色標題步驟即可創建一個簡單的busybox文件系統)
mkdir -p ~/work/my_rootfs/etc
vi ~/work/my_rootfs/etc/inittab
# /etc/inittab
# 啓動腳本/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
# 啓動 shell
console::askfirst:-/bin/sh
# 重啓關機前 卸載文件系統
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
2、創建 /etc/init.d/rcS
mkdir -p ~/work/my_rootfs/etc/init.d
vi ~/work/my_rootfs/etc/init.d/rcS
# 這是一個腳本文件,用/bin/sh解析
#!/bin/sh
#開啓DM9000網卡 down是關閉
ifconfig eth0 up
# 掛載文件系統
mount -a
# 使用內存文件系統
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
# 設置IP
ifconfig eth0 192.168.0.100 #nfs不需要
# 掛載 /etc/fstab 中的文件系統
mount -a
exec /etc/rc.local
3、創建rc.local
vi /work/my_rootfs/etc/rc.local
#!/bin/sh
#加載環境變量,如果要設置某個應用程序自啓動(需要環境變量),環境變量加加載應該放在程序啓動前頭
. /etc/profile //注意.後邊有個空格!
4、創建/etc/fstab
vi ~/work/my_rootfs/etc/fstab
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
5、構建 /dev 目錄(必須的)
mkdir -p ~/work/my_rootfs/dev
cd ~/work/my_rootfs/dev
sudo mknod console c 5 1
sudo mknod null c 1 3
6、創建其它目錄
mkdir proc mnt tmp sys root usr
7、拷貝Lib(必須的)
cd /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib
cp *.so* ~/work/my_rootfs/lib -d
cd /opt/FriendlyARM/toolschain/4.4.3/lib
cp *.so* ~/work/my_rootfs/lib -d