Linux2.6 核心的 Initrd 機制解析(4)(轉貼好文)
initrd_load函式負責載入image-initrd,程式碼如下:
int __init initrd_load(void) { [1] if (mount_initrd) { create_dev("/dev/ram", Root_RAM0, NULL); [2] if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { sys_unlink("/initrd.image"); handle_initrd(); return 1; } } sys_unlink("/initrd.image"); return 0; } |
程式碼[1]:如果載入initrd則建立一個ram0裝置 /dev/ram。
程式碼[2]:/initrd.image檔案儲存的就是image-initrd,rd_load_image函式執行具體的載入操作,將image-nitrd的檔案內容釋放到ram0裡。判斷ROOT_DEV!=Root_RAM0的含義是,如果你在grub或者lilo裡配置了 root=/dev/ram0 ,則實際上真正的根裝置就是initrd了,所以就不把它作為initrd處理 ,而是作為realfs處理。
handle_initrd()函式負責對initrd進行具體的處理,程式碼如下:
static void __init handle_initrd(void){ [1] real_root_dev = new_encode_dev(ROOT_DEV); [2] create_dev("/dev/root.old", Root_RAM0, NULL); mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); [3] sys_mkdir("/old", 0700); root_fd = sys_open("/", 0, 0); old_fd = sys_open("/old", 0, 0); /* move initrd over / and chdir/chroot in initrd root */ [4] sys_chdir("/root"); sys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); mount_devfs_fs (); [5] pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); if (pid > 0) { while (pid != sys_wait4(-1, &i, 0, NULL)) yield(); } /* move initrd to rootfs' /old */ sys_fchdir(old_fd); sys_mount("/", ".", NULL, MS_MOVE, NULL); /* switch root and cwd back to / of rootfs */ [6] sys_fchdir(root_fd); sys_chroot("."); sys_close(old_fd); sys_close(root_fd); umount_devfs("/old/dev"); [7] if (new_decode_dev(real_root_dev) == Root_RAM0) { sys_chdir("/old"); return; } [8] ROOT_DEV = new_decode_dev(real_root_dev); mount_root(); [9] printk(KERN_NOTICE "Trying to move old root to /initrd ... "); error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); if (!error) printk("okayn"); else { int fd = sys_open("/dev/root.old", O_RDWR, 0); printk("failedn"); printk(KERN_NOTICE "Unmounting old rootn"); sys_umount("/old", MNT_DETACH); printk(KERN_NOTICE "Trying to free ramdisk memory ... "); if (fd < 0) { error = fd; } else { error = sys_ioctl(fd, BLKFLSBUF, 0); sys_close(fd); } printk(!error ? "okayn" : "failedn"); } |
handle_initrd函式的主要功能是執行initrd的linuxrc檔案,並且將realfs的根目錄設定為當前目錄。
程式碼[1]:real_root_dev,是一個全域性變數儲存的是realfs的裝置號。
程式碼[2]:呼叫mount_block_root函式將initrd檔案系統掛載到了VFS的/root下。
程式碼[3]:提取rootfs的根的檔案描述符並將其儲存到root_fd.它的作用就是為了在chroot到initrd的檔案系統,處理完initrd之後要,還能夠返回rootfs.返回的程式碼參考程式碼[7].
程式碼[4]:chroot進入initrd的檔案系統。前面initrd已掛載到了rootfs的/root目錄。
程式碼[5]:執行initrd的linuxrc檔案,等待其結束。
程式碼[6]:initrd處理完之後,重新chroot進入rootfs.
程式碼[7]:如果real_root_dev在 linuxrc中重新設成Root_RAM0,則initrd就是最終的realfs了,改變當前目錄到initrd中,不作後續處理直接返回。
程式碼[8]:在linuxrc執行完後,realfs裝置已經確定,呼叫mount_root函式將realfs掛載到root_fs的 /root目錄下,並將當前目錄設定為/root.
程式碼[9]:後面的程式碼主要是做一些收尾的工作,將initrd的記憶體盤釋放。
到此程式碼分析完畢。
6.結束語
透過本文前半部分對cpio-initrd和imag-initrd的闡述與對比以及後半部分的程式碼分析,我相信讀者對Linux 2.6核心的initrd技術有了一個較為全面的瞭解。在本文的最後,給出兩點最重要的結論:
1. 儘管Linux2.6既支援cpio-initrd,也支援image-initrd,但是cpio-initrd有著更大的優勢,在使用中我們應該優先考慮使用cpio格式的initrd.
2. cpio-initrd相對於image-initrd承擔了更多的初始化責任,這種變化也可以看作是核心程式碼的使用者層化的一種體現,我們在其它的諸如FUSE等專案中也看到了將核心功能擴充套件到使用者層實現的嘗試。精簡核心程式碼,將部分功能移植到使用者層必然是linux核心發展的一個趨勢。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/312079/viewspace-245536/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux2.6 核心的 Initrd 機制解析(1)(轉貼好文)Linux
- ETCD核心機制解析
- initrd的功能(轉載)
- 轉貼:Oracle的鎖機制歸納總結Oracle
- 轉:Oracle SCN機制解析Oracle
- 巧用Linux2.6核心新功能配置檔案ACL(轉)Linux
- Linux核心的同步機制(2)(轉)Linux
- Linux核心的同步機制(1)(轉)Linux
- 核心管理概述(轉貼)
- 轉載Oracle SCN機制解析Oracle
- Dubbo的微核心機制
- 進擊JavaScript核心 --- (2)函式和預解析機制JavaScript函式
- Apache Hudi核心之檔案標記機制深入解析Apache
- 解析Java的多執行緒機制(2)(轉)Java執行緒
- 解析Java的多執行緒機制(1)(轉)Java執行緒
- linux核心IDR機制詳解【轉】Linux
- iOS 訊息轉發機制Demo解析iOS
- 響應式流的核心機制——背壓機制
- Java核心反射機制Java反射
- 核心同步機制 RCU
- Handler機制解析
- Linux2.6對新型CPU的支援(2)(轉)Linux
- 深度解析Spring AI:請求與響應機制的核心邏輯SpringAI
- js的Event Loop機制解析JSOOP
- Windows記憶體機制解析(二)原始碼 (轉)Windows記憶體原始碼
- 概述javascript部分核心機制JavaScript
- 概述nodejs核心機制NodeJS
- Linux 核心同步機制Linux
- Java入門-核心機制Java
- SPDK QOS機制解析
- Oracle SCN機制解析Oracle
- 4、核心函式 (轉)函式
- Java高階-解析Java中的多執行緒機制(轉)Java執行緒
- ORACLE的工作機制-4Oracle
- C++的核心特性:繼承機制C++繼承
- xenomai核心解析之訊號signal(二)---xenomai訊號處理機制AI
- Oracle SCN機制解析(zt)Oracle
- ZT Oracle SCN機制解析Oracle