[問題]這算是一個猜想,猜測某系統的啟動過程,以及文件系統的掛載方式。
1、根目錄下的init應該是第一個init程序。也就是說,內核並沒有使用initramfs(因為2.6 kernel里面的initramfs不可以config,這里的沒有使用是指將rootfs內容留空,下同);而是直接掛載了squashfs作為root filesystem。
2、支撐前一個猜想的依據有三條:
1)bootloader里的參數設置有root=31:03。只有不使用initramfs機制做init情況下,kernel才會去使用該參數;否則,真正的root file system將會由rootfs中的init來掛載,而不是內核使用“root=”這一參數來掛載。
2)“cat /proc/mounts”,可以看到系統自動掛載rootfs之后,立即就掛載了squashfs。下面是cat /proc/mounts的內容。
rootfs / rootfs rw 0 0 /dev/root / squashfs ro 0 0 none /proc proc rw,nodiratime 0 0 none /sys sysfs rw 0 0 tmpfs /var tmpfs rw 0 0 dev /dev tmpfs rw 0 0 none /dev/pts devpts rw 0 0 none /proc/bus/usb usbfs rw 0 0
3)上面的mount內容和根目錄下init腳本內容是一致的,下面根目錄下的init腳本內容。
#!/bin/sh # # crucial mountpoints mount -t proc none /proc mount -t sysfs none /sys mount -n tmpfs /var -t tmpfs -o size=8388608 tar cf /tmp/devtmp.tar /dev mount dev /dev -t tmpfs tar xf /tmp/devtmp.tar && rm -f /tmp/devtmp.tar mknod /dev/console c 5 1 mknod /dev/ttyS0 c 4 64 ... mkdir /dev/pts /dev/shm # rest of the mounts mount none /dev/pts -t devpts if [ -e /proc/bus/usb ]; then mount none /proc/bus/usb -t usbfs fi # setup console, consider using ptmx? CIN=/dev/console COUT=/dev/console ...
那么,如果是這樣的話,內核是如何通過root=31:03來找到rootfs的呢?對這個過程還不是很清楚,接下來找資料了解下這個過程。
另外,這個init腳本的最后調用了busybox里面的init,唔,順便也會探究一下這個過程。
關於root=31:03的解釋
唔,根據前面的理解,在不使用initramfs情況下,kernel會使用root作為啟動參數。而上面cat /proc/mounts結果中的/dev/root就是內核解釋該參數的結果。
事實上,在這個過程中,先是由bootloader把啟動參數寫到內存的某位置,然后linux內核通過boot loader傳遞過來的 一個指針(cmd_line_ptr)可以獲取到這些參數。你在系統啟動之初看到的boot argument打印就在這里,接着這些參數會被寫到/proc/cmdline里面去,這樣應用程序也可以通過/proc/cmdline來看到啟動參數。具體解釋見:Linux內核自帶的文檔Documentation/x86/boot.txt 。
然后呢,下面是cat /proc/cmdline的結果:
# cat /proc/cmdline console=tty0 root=31:03 rootfstype=squashfs init=/init mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),1024k(kernel),6528k(rootfs),256k(cfg),64k(EEPROM) panic=3 quiet #
前面一篇文檔已經介紹過,root=31:03事實上代表的是mtdblock3,這是應用的Flash設備上的選項。如果是在其它一些block設備上,這個參數可能是一個物理分區(/dev/sda1),或者是一個邏輯分區(I.E. ,LVM Machenism, /dev/VolGroup00/LogVol00), 更有可能是一個RAID設備,當然,支持不支持還得看bootloader。
另外,因為沒有initramfs為root file system掛載驅動啥的,所以,kernel編譯的時候至少要包含啟動root file system所需要的全部驅動。
至於內核得到root參數后,它到底對它做了些什么,本官暫不能斷定,擇日再審~~~目前把kernel當做一個黑盒子來用。
關於init=/init
由於該系統沒有使用initramfs,所以,根據前一篇介紹init的文章,根據"root="的內容掛載root filesystem后,kernel會去找“init=”指向的init程序。
在該文件系統中,這個init就是上面這一個shell,在其最后,它有執行"/sbin/init":
#!/bin/sh
#
# crucial mountpoints
...
echo "...running /sbin/init" exec /sbin/init echo "INTERNAL ERROR!!! Cannot run /sbin/init."
嗯,如果能允許你運行到最后一句,那么和kernel里init部分給爆出panic是一樣的性質,終究是init沒有完成。但是,init腳本執行的話,就已經不是kernel的工作范疇了。
然后去看看/sbin/init
# ls -l /sbin/init lrwxrwxrwx 1 admin admin 7 Aug 29 10:39 /sbin/init -> busybox
是的,它只是指向busybox的一個軟鏈接。
關於,busybox里的init我們在另一篇文檔里進行介紹。
