【文件系統製作】製作jffs文件系統


最近在寫專利,中期答辯前的必備材料還差一篇論文......抽一個週五的晚上來完善一下之前留下的坑,慢慢來吧,先把這些弄完,希望可以在下月中旬之前把論文弄好,然後專心學習...好運


1、Linux根文件系統基本目錄

  1. /bin  :  該目錄存放所有用戶都可以使用的、基本的命令,這些命令可以在掛接其他文件系統之前就可以使用,所以/bin目錄必須跟文件系統在同一個分區中
  2. /sbin  :  該目錄存放基本系統命令(shutdown、reboot等),即只有管理員才能使用的命令,他們用於啓動系統、修復系統等。可以在掛接其他文件系統之前就可以使用這些命令,所以/sbin目錄必須跟文件系統在同一個分區中。
  3. /dev  :  該目錄存放的是設備文件。設備文件是Linux獨有的文件類型,在Linux系統下,以文件的方式訪問各種外設,即通過讀寫某個設備文件操作某個具體硬件。如通過"/dev/ttySAC0"文件可以操作串口0。設備文件有兩種:字符設備(c)塊設備(b)
  4. /etc  :  該目錄存放各種配置文件。對於PC的Linux系統,/etc目錄下目錄、文件非常多。這些目錄、文件都是可選的,他們依賴於系統中所擁有的應用程序,依賴與這些程序是否需要配置文件。在嵌入式系統中,這些內容可以大爲精減。
  5. /lib  :  該目錄下存放共享庫和可加載模塊(即驅動程序),共享庫用於啓動程序、運行根文件系統的可執行程序,比如/bin、/sbin目錄下的程序。
  6. /home : 用戶目錄,對於每個用戶,在/home下都有一個以用戶名命名的子目錄,裏面存放用戶相關的配置文件
  7. /root : 根用戶目錄(用戶名爲root)
  8. /usr : 該目錄的內容可以存在另一個分區中,在系統啓動後再掛接到根文件系統中的/usr目錄下。裏面存放的是共享、制度的程序和數據。
  9. /var : 與/usr目錄相反,/var目錄中存放可變的數據,比如spool目錄(mail、news、打印機等),log文件、臨時文件
  10. /proc :  這是一個空目錄,常作爲proc文件系統的掛接點。proc文件系統是個虛擬的文件系統,他沒有實際的存儲設備,裏面的目錄、文件都是由內核臨時生成的,用來表示系統的運行狀態,也可以操作其中的文件控制系統。
  11. /mnt :  用於掛接某個文件系統的掛接點,通常是空目錄;也可以在裏面創建一個空目錄的字目錄,比如/mnt/cdram、/mnt/hdal等,用來臨時掛接光盤、硬盤。
  12. /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


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章