[置頂] 《Linux啟動過程分析》核心掛載根檔案系統 http://blog.csdn.net/tankai19880619/article/details/12093239
說明:本文基於Linux2.6.29核心分析;其他核心版本僅供參考。
前邊通過原始碼情景分析,看過了匯流排、裝置、驅動及其發現機制,Linux2.6核心udev裝置節點建立相關;對於檔案系統,一直望而生畏,但核心學習、這部分又不可能繞的過去。目前對VFS中使用的hash表還未做研究,它在dentry和vfsmount下查詢節點起關鍵作用;後邊在做分析。下邊將根檔案系統掛載過程做簡單分析:
一、rootfs的誕生
引子:
Linux一切皆檔案的提出:在Linux中,普通檔案、目錄、字元裝置、塊裝置、套接字等都以檔案被對待;他們具體的型別及其操作不同,但需要向上層提供統一的操作介面。虛擬檔案系統VFS就是Linux核心中的一個軟體層,向上給使用者空間程式提供檔案系統操作介面;向下允許不同的檔案系統共存。所以,所有實際檔案系統都必須實現VFS的結構封裝。
矛盾的提出:
Linux系統中任何檔案系統的掛載必須滿足兩個條件:掛載點和檔案系統。
直接掛載nfs或flash檔案系統有如下兩個問題必須解決:
1.誰來提供掛載點?我們可以想象自己建立一個超級塊(包含目錄項和i節點),這時掛載點不是就有了嗎;很可惜,linux引入VFS(一切皆檔案,所有型別檔案系統必須提供一個VFS的軟體層、以向上層提供統一介面)後該問題不能這麼解決,因為掛載點必須關聯到檔案系統、也就是說掛載點必須屬於某個檔案系統。
2.怎樣訪問到nfs或flash上的檔案系統?我們可以說直接訪問裝置驅動讀取其上邊的檔案系統(裝置上的檔案系統是掛載在自己的根目錄),不就可以了嗎;別忘了還是Linux的VFS,裝置訪問也不例外。因為訪問裝置還是需要通過檔案系統來訪問它的掛載點,不能直接訪問(要滿足Linux的VFS架構,一切皆檔案)。所以,一句話:rootfs之所以存在,是因為需要在VFS機制下給系統提供最原始的掛載點。
如此矛盾,需要我們引入一種特殊檔案系統:
1.它是系統自己建立並載入的第一個檔案系統;該檔案系統的掛載點就是它自己的根目錄項。
2.該檔案系統不能存在於nfs或flash上,因為如此將會陷入之前的矛盾。
rootfs的誕生:
上述問題需要我們建立具有如下三個特點的特殊檔案系統:
1.它是系統自己建立並載入的第一個檔案系統;
2.該檔案系統的掛載點就是它自己的根目錄項物件;
3.該檔案系統僅僅存在於記憶體中。
由以上分析可以看出,rootfs是Linux的VFS(一切皆檔案,所有型別檔案系統必須提供一個VFS的軟體層、以向上層提供統一介面)存在的基石;二者關係密切。如果沒有VFS機制,rootfs也就沒有存在的必要;同樣,如果沒有rootfs、VFS機制也就不能實現。
這就是兩者之間的真正關係,之前看網上什麼說法都有:有的只說關係密切,沒有指明具體關係;有的乾脆誤人子弟,說VFS就是rootfs。
其實,VFS是一種機制、是Linux下每一種檔案系統(包括剛才說的rootfs,還有常見的ext3、yaffs等)都必須按照這個機制去實現的一種規範;而rootfs僅僅是符合VFS規範的而且又具有如上3個特點的一個檔案系統。
VFS是Linux檔案系統實現必須遵循的一種機制,rootfs是一種具體實現的檔案系統、Linux下所有檔案系統的實現都必須符合VFS的機制(符合VFS的介面);這就是二者的真正關係。
以下分析基於Android模擬器Linux2.6.29核心:
二、相關資料結構
Linux核心中current指標作為全域性變數,使用非常廣泛;例如:程序上下文中獲取當前程序ID、任務排程,以及open等檔案系統呼叫中路徑搜尋等;首先介紹下current結構體:
各個平臺、各個核心版本中current的實現可能不同;但原理是一樣的。該指標一般定義在具體平臺的current.h標頭檔案中,型別為struct task_struct:
- #define current (get_current())
- staticinlinestruct task_struct *get_current(void)
include/linux/sched.h
- struct task_struct {
- ......
- struct thread_info *thread_info;
- struct list_head tasks;
- pid_t pid;
- pid_t tgid;
- uid_t uid,euid,suid,fsuid;
- gid_t gid,egid,sgid,fsgid;
- struct fs_struct *fs; //本節將大量使用這個
- struct files_struct *files;
- ......
- }
1.檔案系統註冊
kernel/include/include/fs.h
- struct file_system_type {
- constchar *name; //檔案系統名字;如:rootfs及ext3等
- int fs_flags;
- int (*get_sb) (struct file_system_type *, int, constchar *, void *, struct vfsmount *);
- //安裝/掛載檔案系統時,會呼叫;獲取超級塊。
- void (*kill_sb) (struct super_block *);
- //解除安裝檔案系統時會呼叫。
- struct module *owner;
- struct file_system_type * next;
- //指向下一個檔案系統型別。
- struct list_head fs_supers;
- //同一個檔案系統型別中所有超級塊組成雙向連結串列。
- struct lock_class_key s_lock_key;
- struct lock_class_key s_umount_key;
- struct lock_class_key i_lock_key;
- struct lock_class_key i_mutex_key;
- struct lock_class_key i_mutex_dir_key;
- struct lock_class_key i_alloc_sem_key;
- };
2.檔案系統掛載vfsmount(struct vfsmount):
本質上,mount操作的過程就是新建一個vfsmount結構,然後將此結構和掛載點(目錄項物件)關聯。關聯之後,目錄查詢時就能沿著vfsmount掛載點一級級向下查詢檔案了。
對於每一個mount的檔案系統,都由一個vfsmount例項來表示。
kernel/include/linux/mount.h
- struct vfsmount {
- struct list_head mnt_hash; //核心通過雜湊表對vfsmount進行管理
- struct vfsmount *mnt_parent; //指向父檔案系統對應的vfsmount
- struct dentry *mnt_mountpoint; //指向該檔案系統掛載點對應的目錄項物件dentry
- struct dentry *mnt_root; //該檔案系統對應的裝置根目錄dentry
- struct super_block *mnt_sb; //指向該檔案系統對應的超級塊
- struct list_head mnt_mounts;
- struct list_head mnt_child; //同一個父檔案系統中的所有子檔案系統通過該欄位連結成雙聯表
- int mnt_flags;
- /* 4 bytes hole on 64bits arches */
- constchar *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
- struct list_head mnt_list; //所有已掛載檔案系統的vfsmount結構通過該欄位連結在一起
- struct list_head mnt_expire; /* link in fs-specific expiry list */
- struct list_head mnt_share; /* circular list of shared mounts */
- struct list_head mnt_slave_list;/* list of slave mounts */
- struct list_head mnt_slave; /* slave list entry */
- struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
- struct mnt_namespace *mnt_ns; /* containing namespace */
- int mnt_id; /* mount identifier */
- int mnt_group_id; /* peer group identifier */
- /*
- * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
- * to let these frequently modified fields in a separate cache line
- * (so that reads of mnt_flags wont ping-pong on SMP machines)
- */
- atomic_t mnt_count;
- int mnt_expiry_mark; /* true if marked for expiry */
- int mnt_pinned;
- int mnt_ghosts;
- /*
- * This value is not stable unless all of the mnt_writers[] spinlocks
- * are held, and all mnt_writer[]s on this mount have 0 as their ->count
- */
- atomic_t __mnt_writers;
- };
3.超級塊(struct super_bloc):
kernel/include/linux/fs.h
- struct super_block {
- struct list_head s_list; /* Keep this first */
- dev_t s_dev; /* search index; _not_ kdev_t */
- unsigned long s_blocksize;
- unsigned char s_blocksize_bits;
- unsigned char s_dirt;
- unsigned longlong s_maxbytes; /* Max file size */
- struct file_system_type *s_type; //檔案系統型別
- //(kernel/include/linux/fs.h,struct file_system_type)
- conststruct super_operations *s_op;
- struct dquot_operations *dq_op;
- struct quotactl_ops *s_qcop;
- conststruct export_operations *s_export_op;
- unsigned long s_flags;
- unsigned long s_magic;
- struct dentry *s_root; //超級塊要指向目錄項物件
- struct rw_semaphore s_umount;
- struct mutex s_lock;
- int s_count;
- int s_need_sync_fs;
- atomic_t s_active;
- #ifdef CONFIG_SECURITY
- void *s_security;
-
相關推薦
[置頂] 《Linux啟動過程分析》核心掛載根檔案系統 http://blog.csdn.net/tankai19880619/article/details/12093239
說明:本文基於Linux2.6.29核心分析;其他核心版本僅供參考。 前邊通過原始碼情景分析,看過了匯流排、裝置、驅動及其發現機制,Linux2.6核心udev裝置節點建立相關;對於檔案系統,一直望而生畏,但核心學習、這部分又不可能繞的過去。目前對VFS中使用的hash表還未做研究,它在dent
linux音頻alsa-uda134x驅動文檔閱讀之一轉自http://blog.csdn.net/wantianpei/article/details/7817293
發出 hand 增加 int chang == 音頻 set device 前言 目前,linux系統常用的音頻驅動有兩種形式:alsa oss alsa:現在是linux下音頻驅動的主要形式,與簡單的oss兼容。oss:過去的形式而我們板子上的uda1341用的就是als
Linux串列埠程式設計教程(三)——串列埠程式設計詳(原始碼)解:http://blog.csdn.net/u011192270/article/details/48174353 Linux下的串列埠程式設計(二)----(圖文並茂,講解深刻)http://blog.csdn.net/w28252
Linux串列埠程式設計教程(三)——串列埠程式設計詳(原始碼)解:http://blog.csdn.net/u011192270/article/details/48174353 Linux下的串列埠程式設計(二)----(圖文並茂,講解深刻)http://blog.csdn.ne
Hibernate物件三種狀態詳細分析(轉自http://blog.csdn.net/redarmy_chen/article/details/7069482)
在hibernate中有三種狀態:瞬時態(Transient)、 持久態(Persistent)、脫管態(Detached)。處於持久態的物件也稱為PO(Persistence Object),瞬時物件和脫管物件也稱為VO(Value Object)。通過自己在網上的搜尋,
《Linux啟動過程分析》核心掛載根檔案系統
說明:本文基於Linux2.6.29核心分析;其他核心版本僅供參考。 前邊通過原始碼情景分析,看過了匯流排、裝置、驅動及其發現機制,Linux2.6核心udev裝置節點建立相關;對於檔案系統,一直望而生畏,但核心學習、這部分又不可能繞的過去。目前對VFS中使用的has
u-boot通過nfs從伺服器下載核心,並且啟動核心,掛載根檔案系統的方法
http://www.linuxidc.com/Linux/2013-08/89154.htm http://blog.csdn.net/sinat_31500569/article/details/53120530 參考連結 首先要在電腦上安裝nfs伺服器 1.執行命令
TBSchedule原始碼學習筆記-啟動過程 轉自https://blog.csdn.net/weiythi/article/details/78742651
TBSchedule基本概念及原理 概念介紹 TBSchedule是一個支援分散式的排程框架,能讓一種批量任務或者不斷變化的任務,被動態的分配到多個主機的JVM中,不同的執行緒組中並行執行。基於ZooKeeper的純Java實現,由Alibaba開源。 程式碼實
X86架構下Linux啟動過程分析
重要 ack csdn 檢查 point article span 註意 eap 1、X86架構下的從開機到Start_kernel啟動的整體過程 這個過程簡要概述為: 開機——>BIOS——>GRUB/LILO——>Linux Kernel
Linux啟動過程分析(十一)---da850_set_emif_clk_rate()函式分析
/* * 雖然在bootloader中已經把emif的時鐘速率設定為允許的值,但是核心需要重新 *設定以使它支援平臺請求的特定時鐘速率。 */ ret = da850_set_emif_clk_rate()-> static __init int da850_set_emif_c
Linux啟動過程分析(十一)-----customize_machine(註冊開發板相關硬體資訊)
初始化過程進行到下面這一步: c0599c48 t __initcall_customize_machine3 呼叫的函式及其位置如下: Setup.c (arch\arm\kernel):arch_initcall(customize_machine) static int __in
Linux 啟動過程分析 (SysV init啟動模式)
本篇主要分析傳統的Linux啟動方式 SysV init啟動模式。(注:當前Linux發行版大多采用Systemd 啟動模式來替代傳統的 SysV init啟動模式。) &nbs
Linux 啟動過程分析
(點選上方公眾號,可快速關注)編譯: linux中國 / jessie-pang 英文: A
《Linux啟動過程分析》之區別Initramfs與initrd
之前《Linux啟動過程分析》核心掛載根檔案系統一文,分析的rootfs、其實就是解決了Linux的VFS架構下初始掛載點的建立問題。 下邊說的Initramfs/initrd則是填充(僅僅是釋放檔案到rootfs根目錄)/擴充(通過掛載其他檔案系統型別到rootf
從NFS啟動Linux並掛載根檔案系統
要搞嵌入式NFS確實必不可少,否則每次都要重啟煩都煩死。這裡總結在NFS建立過程中遇到的幾個問題。 下面記錄幾個遇到的問題 VFS: Cannot open root device “
linux 核心啟動流程(涉及到根檔案系統的問題)
Linux核心啟動及檔案系統載入過程 當u-boot開始執行bootcmd命令。就進入Linux核心啟動階段,與u-boot類似,普通Linux核心的啟動過程也能夠分為兩個階段,但針對壓縮了的核心如uImage就要包含核心自解壓過程了。本文以linux-2.6.37版原始
Beaglebone Black——理論篇beaglebone black啟動——從串列埠獲得SPL、U-BOOT,TFTP伺服器獲得核心,NFS伺服器掛載根檔案系統
一般來講啟動一個系統所需的bootloader(SPL/MLO、u-boot.img)和根檔案系統(/boot下包含核心zImage)要麼是放在NAND Flash,或者是SD卡,或者是eMMC,或者是USB中,那麼還有一種方式,就是所需要的這些檔案全部
怎樣從網路上核心和根檔案系統啟動開發板
首先在ubuntu虛擬機器上要有nfs伺服器 1.啟動開發板uboot,輸入 下面的命令 set bootargs console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.19:/work/nfs_root/tmp/fs_mini
移植u-boot-2011.03到S3C2440(utu2440)的方法與步驟###8. u-boot引導啟動nand flash中核心和根檔案系統cramfs和使用者檔案系統yaffs2支援
rivers/rtc/hctosys.c: unable to open rtc device (rtc0)uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2,
嵌入式linux 核心和根檔案系統燒寫方式簡介
總體來說,嵌入式Linux核心和根檔案的引導與PC機差不多。嵌入式linux核心和根檔案系統可以存放在各種可能的儲存裝置中,一般情況下我們將核心和根檔案系統直接燒入到Flash中(包括NOR和NAND flash),這種方法的缺點是在核心和根檔案系統出現修改時我們就不得不得
uboot、核心、根檔案系統啟動流程
0.設定cpu為svc模式,關中斷 1. 為核心的解壓做準備(記憶體,中斷等等) 2.核心自解壓 (vmlinux.lds) 3.跳轉到入口地址執行(head.S--->main.c)start_kernel執行核心 4.硬體的初始化(初始mm mmu 中斷(request_irq),軟