久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

《Linux啟動(dòng)過(guò)程分析》內(nèi)核掛載根文件系統(tǒng)

 射天狼星 2014-09-18
  說(shuō)明:本文基于Linux2.6內(nèi)核分析;其他內(nèi)核版本僅供參考,。

  前邊通過(guò)源碼情景分析,,看過(guò)了總線、設(shè)備,、驅(qū)動(dòng)及其發(fā)現(xiàn)機(jī)制,,Linux2.6內(nèi)核udev設(shè)備節(jié)點(diǎn)創(chuàng)建相關(guān);對(duì)于文件系統(tǒng),,一直望而生畏,,但內(nèi)核學(xué)習(xí)、這部分又不可能繞的過(guò)去,。目前對(duì)VFS中使用的hash表還未做研究,,它在dentry和vfsmount下查找節(jié)點(diǎn)起關(guān)鍵作用;后邊在做分析,。下邊將根文件系統(tǒng)掛載過(guò)程做簡(jiǎn)單分析:

  一,、rootfs的誕生

  引子:

  Linux一切皆文件的提出:在Linux中,普通文件,、目錄,、字符設(shè)備、塊設(shè)備,、套接字等都以文件被對(duì)待,;他們具體的類型及其操作不同,,但需要向上層提供統(tǒng)一的操作接口。

  虛擬文件系統(tǒng)VFS就是Linux內(nèi)核中的一個(gè)軟件層,,向上給用戶空間程序提供文件系統(tǒng)操作接口,;向下允許不同的文件系統(tǒng)共存。所以,,所有實(shí)際文件系統(tǒng)都必須實(shí)現(xiàn)VFS的結(jié)構(gòu)封裝,。

  矛盾的提出:

  Linux系統(tǒng)中任何文件系統(tǒng)的掛載必須滿足兩個(gè)條件:掛載點(diǎn)和文件系統(tǒng)。

  直接掛載nfs或flash文件系統(tǒng)有如下兩個(gè)問(wèn)題必須解決:

  1.誰(shuí)來(lái)提供掛載點(diǎn),?我們可以想象自己創(chuàng)建一個(gè)超級(jí)塊(包含目錄項(xiàng)和i節(jié)點(diǎn)),,這時(shí)掛載點(diǎn)不是就有了嗎;很可惜,,linux引入VFS(一切皆文件,所有類型文件系統(tǒng)必須提供一個(gè)VFS的軟件層,、以向上層提供統(tǒng)一接口)后該問(wèn)題不能這么解決,因?yàn)閽燧d點(diǎn)必須關(guān)聯(lián)到文件系統(tǒng),、也就是說(shuō)掛載點(diǎn)必須屬于某個(gè)文件系統(tǒng),。

  2.怎樣訪問(wèn)到nfs或flash上的文件系統(tǒng)?我們可以說(shuō)直接訪問(wèn)設(shè)備驅(qū)動(dòng)讀取其上邊的文件系統(tǒng)(設(shè)備上的文件系統(tǒng)是掛載在自己的根目錄),,不就可以了嗎,;別忘了還是Linux的VFS,設(shè)備訪問(wèn)也不例外,。因?yàn)樵L問(wèn)設(shè)備還是需要通過(guò)文件系統(tǒng)來(lái)訪問(wèn)它的掛載點(diǎn),,不能直接訪問(wèn)(要滿足Linux的VFS架構(gòu),一切皆文件),。

  所以,,一句話:rootfs之所以存在,是因?yàn)樾枰赩FS機(jī)制下給系統(tǒng)提供最原始的掛載點(diǎn),。

  如此矛盾,,需要我們引入一種特殊文件系統(tǒng):

  1.它是系統(tǒng)自己創(chuàng)建并加載的第一個(gè)文件系統(tǒng);該文件系統(tǒng)的掛載點(diǎn)就是它自己的根目錄項(xiàng),。

  2.該文件系統(tǒng)不能存在于nfs或flash上,,因?yàn)槿绱藢?huì)陷入之前的矛盾。

  rootfs的誕生:

  上述問(wèn)題需要我們創(chuàng)建具有如下三個(gè)特點(diǎn)的特殊文件系統(tǒng):

  1.它是系統(tǒng)自己創(chuàng)建并加載的第一個(gè)文件系統(tǒng),;

  2.該文件系統(tǒng)的掛載點(diǎn)就是它自己的根目錄項(xiàng)對(duì)象,;

  3.該文件系統(tǒng)僅僅存在于內(nèi)存中。

  由以上分析可以看出,,rootfs是Linux的VFS(一切皆文件,,所有類型文件系統(tǒng)必須提供一個(gè)VFS的軟件層、以向上層提供統(tǒng)一接口)存在的基石;二者關(guān)系密切,。如果沒有VFS機(jī)制,,rootfs也就沒有存在的必要;同樣,,如果沒有rootfs、VFS機(jī)制也就不能實(shí)現(xiàn)。

  這就是兩者之間的真正關(guān)系,,之前看網(wǎng)上什么說(shuō)法都有:有的只說(shuō)關(guān)系密切,,沒有指明具體關(guān)系;有的干脆誤人子弟,,說(shuō)VFS就是rootfs,。

  其實(shí),VFS是一種機(jī)制,、是Linux下每一種文件系統(tǒng)(包括剛才說(shuō)的rootfs,,還有常見的ext3、yaffs等)都必須按照這個(gè)機(jī)制去實(shí)現(xiàn)的一種規(guī)范,;而rootfs僅僅是符合VFS規(guī)范的而且又具有如上3個(gè)特點(diǎn)的一個(gè)文件系統(tǒng),。

  VFS是Linux文件系統(tǒng)實(shí)現(xiàn)必須遵循的一種機(jī)制,rootfs是一種具體實(shí)現(xiàn)的文件系統(tǒng),、Linux下所有文件系統(tǒng)的實(shí)現(xiàn)都必須符合VFS的機(jī)制(符合VFS的接口),;這就是二者的真正關(guān)系。

  以下分析基于Android模擬器Linux2.6.29內(nèi)核:

  二,、相關(guān)數(shù)據(jù)結(jié)構(gòu)

  Linux內(nèi)核中current指針作為全局變量,,使用非常廣泛;例如:進(jìn)程上下文中獲取當(dāng)前進(jìn)程ID,、任務(wù)調(diào)度,,以及open等文件系統(tǒng)調(diào)用中路徑搜索等;首先介紹下current結(jié)構(gòu)體:

  各個(gè)平臺(tái),、各個(gè)內(nèi)核版本中current的實(shí)現(xiàn)可能不同,;但原理是一樣的。該指針一般定義在具體平臺(tái)的current.h頭文件中,,類型為struct task_struct:

  #define current (get_current())

  static inline struct 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; //本節(jié)將大量使用這個(gè)

  struct files_struct *files;

  ......

  }

  1.文件系統(tǒng)注冊(cè)

  kernel/include/include/fs.h

  struct file_system_type {

  const char *name; //文件系統(tǒng)名字;如:rootfs及ext3等

  int fs_flags;

  int (*get_sb) (struct file_system_type *, int, const char *, void *, struct vfsmount *);

  //安裝/掛載文件系統(tǒng)時(shí),,會(huì)調(diào)用;獲取超級(jí)塊,。

  void (*kill_sb) (struct super_block *);

  //卸載文件系統(tǒng)時(shí)會(huì)調(diào)用,。

  struct module *owner;

  struct file_system_type * next;

  //指向下一個(gè)文件系統(tǒng)類型。

  struct list_head fs_supers;

  //同一個(gè)文件系統(tǒng)類型中所有超級(jí)塊組成雙向鏈表,。

  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.文件系統(tǒng)掛載vfsmount(struct vfsmount):

  本質(zhì)上,,mount操作的過(guò)程就是新建一個(gè)vfsmount結(jié)構(gòu),然后將此結(jié)構(gòu)和掛載點(diǎn)(目錄項(xiàng)對(duì)象)關(guān)聯(lián),。關(guān)聯(lián)之后,,目錄查找時(shí)就能沿著vfsmount掛載點(diǎn)一級(jí)級(jí)向下查找文件了。

  對(duì)于每一個(gè)mount的文件系統(tǒng),,都由一個(gè)vfsmount實(shí)例來(lái)表示,。

  kernel/include/linux/mount.h

  struct vfsmount {

  struct list_head mnt_hash; //內(nèi)核通過(guò)哈希表對(duì)vfsmount進(jìn)行管理

  struct vfsmount *mnt_parent;//指向父文件系統(tǒng)對(duì)應(yīng)的vfsmount

  struct dentry *mnt_mountpoint; //指向該文件系統(tǒng)掛載點(diǎn)對(duì)應(yīng)的目錄項(xiàng)對(duì)象dentry

  struct dentry *mnt_root; //該文件系統(tǒng)對(duì)應(yīng)的設(shè)備根目錄dentry

  struct super_block *mnt_sb; //指向該文件系統(tǒng)對(duì)應(yīng)的超級(jí)塊

  struct list_head mnt_mounts;

  struct list_head mnt_child; //同一個(gè)父文件系統(tǒng)中的所有子文件系統(tǒng)通過(guò)該字段鏈接成雙聯(lián)表

  int mnt_flags;

  /* 4 bytes hole on 64bits arches */

  const char *mnt_devname;/* Name of device e.g. /dev/dsk/hda1 */

  struct list_head mnt_list; //所有已掛載文件系統(tǒng)的vfsmount結(jié)構(gòu)通過(guò)該字段鏈接在一起

  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.超級(jí)塊(struct super_bloc):

  kernel/include/linux/fs.h

  struct super_block {

  struct list_heads_list;/* Keep this first */

  dev_ts_dev;/* search index; _not_ kdev_t */

  unsigned longs_blocksize;

  unsigned chars_blocksize_bits;

  unsigned chars_dirt;

  unsigned long longs_maxbytes;/* Max file size */

  struct file_system_type*s_type; //文件系統(tǒng)類型

  //(kernel/include/linux/fs.h,struct file_system_type)

  const struct super_operations*s_op;

  struct dquot_operations*dq_op;

  struct quotactl_ops*s_qcop;

  const struct export_operations *s_export_op;

  unsigned longs_flags;

  unsigned longs_magic;

  struct dentry*s_root; //超級(jí)塊要指向目錄項(xiàng)對(duì)象

  struct rw_semaphores_umount;

  struct mutexs_lock;

  ints_count;

  ints_need_sync_fs;

  atomic_ts_active;

  #ifdef CONFIG_SECURITY

  void *s_security;

  #endif

  struct xattr_handler**s_xattr;

  struct list_heads_inodes;/* all inodes */

  struct list_heads_dirty;/* dirty inodes */

  struct list_heads_io;/* parked for writeback */

  struct list_heads_more_io;/* parked for more writeback */

  struct hlist_heads_anon;//哈希表頭/* anonymous dentries for (nfs) exporting */

  struct list_heads_files;

  /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */

  struct list_heads_dentry_lru;/* unused dentry lru */

  ints_nr_dentry_unused;/* # of dentry on lru */

  struct block_device*s_bdev;

  struct mtd_info*s_mtd;

  struct list_heads_instances;

  struct quota_infos_dquot;/* Diskquota specific options */

  ints_frozen;

  wait_queue_head_ts_wait_unfrozen;

  char s_id[32];/* Informational name */

  void *s_fs_info;/* Filesystem private info */

  fmode_ts_mode;

  /*

  * The next field is for VFS *only*. No filesystems have any business

  * even looking at it. You had been warned.

  */

  struct mutex s_vfs_rename_mutex;/* Kludge */

  /* Granularity of c/m/atime in ns.Cannot be worse than a second */

  u32 s_time_gran;

  /*

  * Filesystem subtype. If non-empty the filesystem type field

  * in /proc/mounts will be 'type.subtype'

  */

  char *s_subtype;

  /*

  * Saved mount options for lazy filesystems using

  * generic_show_options()

  */

  char *s_options;

  /*

  * storage for asynchronous operations

  */

  struct list_head s_async_list;

  };

  4.目錄索引節(jié)點(diǎn)(struct inode):

  kernel/include/linux/fs.h

  struct inode {

  struct hlist_nodei_hash; //哈希表節(jié)點(diǎn)

  struct list_headi_list;

  struct list_headi_sb_list;

  struct list_headi_dentry;

  unsigned longi_ino;

  atomic_ti_count;

  unsigned inti_nlink;

  uid_ti_uid;

  gid_ti_gid;

  dev_ti_rdev;

  u64i_version;

  loff_ti_size;

  #ifdef __NEED_I_SIZE_ORDERED

  seqcount_ti_size_seqcount;

  #endif

  struct timespeci_atime;

  struct timespeci_mtime;

  struct timespeci_ctime;

  unsigned inti_blkbits;

  blkcnt_ti_blocks;

  unsigned short i_bytes;

  umode_ti_mode;

  spinlock_ti_lock;/* i_blocks, i_bytes, maybe i_size */

  struct mutexi_mutex;

  struct rw_semaphorei_alloc_sem;

  const struct inode_operations*i_op;

  const struct file_operations*i_fop;/* former ->i_op->default_file_ops */

  struct super_block*i_sb;

  struct file_lock*i_flock;

  struct address_space*i_mapping;

  struct address_spacei_data;

  #ifdef CONFIG_QUOTA

  struct dquot*i_dquot[MAXQUOTAS];

  #endif

  struct list_headi_devices;

  union {

  struct pipe_inode_info*i_pipe;

  struct block_device*i_bdev;

  struct cdev*i_cdev;

  };

  inti_cindex;

  __u32i_generation;

  #ifdef CONFIG_DNOTIFY

  unsigned longi_dnotify_mask; /* Directory notify events */

  struct dnotify_struct*i_dnotify; /* for directory notifications */

  #endif

  #ifdef CONFIG_INOTIFY

  struct list_headinotify_watches; /* watches on this inode */

  struct mutexinotify_mutex;/* protects the watches list */

  #endif

  unsigned longi_state;

  unsigned longdirtied_when;/* jiffies of first dirtying */

  unsigned inti_flags;

  atomic_ti_writecount;

  #ifdef CONFIG_SECURITY

  void*i_security;

  #endif

  void*i_private; /* fs or device private pointer */

  };

  5.目錄項(xiàng)對(duì)象(struct dentry):

  kernel/include/linux/dcache.h

  struct dentry {

  atomic_t d_count;

  unsigned int d_flags;/* protected by d_lock */

  spinlock_t d_lock;/* per dentry lock */

  int d_mounted;

  struct inode *d_inode; //目錄項(xiàng)對(duì)象與目錄索引的關(guān)聯(lián)

  /* Where the name belongs to - NULL is

  * negative */

  /*

  * The next three fields are touched by __d_lookup. Place them here

  * so they all fit in a cache line.

  */

  struct hlist_node d_hash; //哈希表節(jié)點(diǎn)/* lookup hash list */

  struct dentry *d_parent; //目錄項(xiàng)對(duì)象的父親/* parent directory */

  struct qstr d_name; //d_name.name這個(gè)是文件名,,目錄對(duì)象與目錄名的關(guān)聯(lián)

  struct list_head d_lru;/* LRU list */

  /*

  * d_child and d_rcu can share memory

  */

  union {

  struct list_head d_child;/* child of parent list */

  struct rcu_head d_rcu;

  } d_u;

  struct list_head d_subdirs;/* our children */

  struct list_head d_alias;/* inode alias list */

  unsigned long d_time;/* used by d_revalidate */

  struct dentry_operations *d_op;

  struct super_block *d_sb; //指向文件系統(tǒng)的超級(jí)塊/* The root of the dentry tree */

  void *d_fsdata;/* fs-specific data */

  unsigned char d_iname[DNAME_INLINE_LEN_MIN];/* small names */

  };

  其他:

  include/linux/fs.h

  struct file {

  /*

  * fu_list becomes invalid after file_free is called and queued via

  * fu_rcuhead for RCU freeing

  */

  union {

  struct list_headfu_list;

  struct rcu_head fu_rcuhead;

  } f_u;

  struct pathf_path; //重要?。?!記錄掛載信息和目錄項(xiàng)信息

  #define f_dentryf_path.dentry

  #define f_vfsmntf_path.mnt

  const struct file_operations*f_op;

  atomic_long_tf_count;

  unsigned int f_flags;

  fmode_tf_mode;

  loff_tf_pos;

  struct fown_structf_owner;

  const struct cred*f_cred;

  struct file_ra_statef_ra;

  u64f_version;

  #ifdef CONFIG_SECURITY

  void*f_security;

  #endif

  /* needed for tty driver, and maybe others */

  void*private_data;

  #ifdef CONFIG_EPOLL

  /* Used by fs/eventpoll.c to link all the hooks to this file */

  struct list_headf_ep_links;

  spinlock_tf_ep_lock;

  #endif /* #ifdef CONFIG_EPOLL */

  struct address_space*f_mapping;

  #ifdef CONFIG_DEBUG_WRITECOUNT

  unsigned long f_mnt_write_state;

  #endif

  };

  include/linux/fs_struct.h

  struct fs_struct {

  atomic_t count;

  rwlock_t lock;

  int umask;

  struct path root, pwd; //重要?。?!記錄掛載信息和目錄項(xiàng)信息

  };

  include/linux/namei.h

  struct nameidata {

  struct pathpath; //重要?。?!記錄掛載信息和目錄項(xiàng)信息

  struct qstrlast; //重要?。?!記錄目錄名

  unsigned intflags;

  intlast_type;

  unsigneddepth;

  char *saved_names[MAX_NESTED_LINKS + 1];

  /* Intent data */

  union {

  struct open_intent open;

  } intent;

  };

  include/linux/path.h

  struct path {

  struct vfsmount *mnt; //重要?。?!記錄文件系統(tǒng)掛載信息

  struct dentry *dentry; //重要?。?!記錄目錄項(xiàng)信息

  };

  include/linux/dcache.h

  struct qstr {

  unsigned int hash;

  unsigned int len;

  const unsigned char *name;//重要?。?!目錄/文件名字,,如'/','tank1'等具體的文件名

  };

  三、注冊(cè)/創(chuàng)建、安裝/掛載rootfs,,并調(diào)用set_fs_root設(shè)置系統(tǒng)current的根文件系統(tǒng)為rootfs

  過(guò)程:

  第一步:建立rootfs文件系統(tǒng),;

  第二步:調(diào)用其get_sb函數(shù)(對(duì)于rootfs這種內(nèi)存/偽文件系統(tǒng)是get_sb_nodev,實(shí)際文件系統(tǒng)比如ext2等是get_sb_bdev),、建立超級(jí)塊(包含目錄項(xiàng)和i節(jié)點(diǎn)),;

  第三步:掛載該文件系統(tǒng)(該文件系統(tǒng)的掛載點(diǎn)指向該文件系統(tǒng)超級(jí)塊的根目錄項(xiàng));

  第四步:將系統(tǒng)current的根文件系統(tǒng)和根目錄設(shè)置為rootfs和其根目錄,。

  kernel/init/main.c

  asmlinkage void __init start_kernel(void)

  {

  setup_arch(&command_line);//解析uboot命令行,,實(shí)際文件系統(tǒng)掛載需要

  parse_args('Booting kernel', static_command_line, __start___param,

  __stop___param - __start___param,

  &unknown_bootoption);

  vfs_caches_init(num_physpages);

  }

  kernel/fs/dcache.c

  void __init vfs_caches_init(unsigned long mempages)

  {

  mnt_init();

  bdev_cache_init(); //塊設(shè)備文件創(chuàng)建

  chrdev_init();//字符設(shè)備文件創(chuàng)建

  }

  kernel/fs/namespace.c

  void __init mnt_init(void)

  {

  init_rootfs(); //向內(nèi)核注冊(cè)rootfs

  init_mount_tree();//重要!??!rootfs根目錄的建立以及rootfs文件系統(tǒng)的掛載;設(shè)置系統(tǒng)current根目錄和根文件系統(tǒng)為rootfs

  }

  下邊分兩步:

  1.向內(nèi)核注冊(cè)rootfs虛擬文件系統(tǒng)init_rootfs

  kernel/fs/ramfs/inode.cint __init init_rootfs(void)

  {

  err = register_filesystem(&rootfs_fs_type);

  }

  static struct file_system_type rootfs_fs_type = {

  .name= 'rootfs',

  .get_sb= rootfs_get_sb,

  .kill_sb= kill_litter_super,

  };

  2.建立rootfs的根目錄,,并將rootfs掛載到自己的根目錄;設(shè)置系統(tǒng)current根目錄和根文件系統(tǒng)

  kernel/fs/namespace.cstatic void __init init_mount_tree(void)

  {

  struct vfsmount *mnt;

  struct mnt_namespace *ns;

  struct path root;

  //創(chuàng)建rootfs的vfsmount結(jié)構(gòu),,建立rootfs的超級(jí)塊,、并將rootfs掛載到自己的根目錄。

  /*

  mnt->mnt_mountpoint = mnt->mnt_root = dget(sb->s_root),,而該mnt和自己的sb是關(guān)聯(lián)的,;

  所以,是把rootfs文件系統(tǒng)掛載到了自己對(duì)應(yīng)的超級(jí)塊的根目錄上,。

  這里也是實(shí)現(xiàn)的關(guān)鍵:一般文件系統(tǒng)的掛載是調(diào)用do_mount->do_new_mount而該函數(shù)中首先調(diào)用do_kern_mount,,這時(shí)mnt->mnt_mountpoint = mnt->mnt_root;但后邊

  它還會(huì)調(diào)用do_add_mount->graft_tree->attach_recursive_mnt如下代碼mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt)改變了其掛載點(diǎn)?。,。?br/>
  */

  mnt = do_kern_mount('rootfs', 0, 'rootfs', NULL);

  list_add(&mnt->mnt_list, &ns->list);

  ns->root = mnt; //將創(chuàng)建好的mnt加入系統(tǒng)當(dāng)前

  mnt->mnt_ns = ns;

  init_task.nsproxy->mnt_ns = ns; //設(shè)置進(jìn)程的命名空間

  get_mnt_ns(ns);

  root.mnt = ns->root; //文件系統(tǒng)為rootfs,,相當(dāng)與root.mnt = mnt;

  root.dentry = ns->root->mnt_root;//目錄項(xiàng)為根目錄項(xiàng),,相當(dāng)與root.dentry = mnt->mnt_root;

  //設(shè)置系統(tǒng)current的pwd目錄和文件系統(tǒng)

  set_fs_pwd(current->fs, &root);

  //設(shè)置系統(tǒng)current根目錄,根文件系統(tǒng)。這個(gè)是關(guān)鍵?。,。≌麄€(gè)內(nèi)核代碼最多只有兩處調(diào)用

  set_fs_root(current->fs, &root);

  }

  以下著重分析do_kern_mount函數(shù),,它實(shí)現(xiàn)了rootfs在自己根目錄上的掛載:

  kernel/fs/super.cstruct vfsmount *

  do_kern_mount(const char *fstype, int flags, const char *name, void *data)

  {

  mnt = vfs_kern_mount(type, flags, name, data);

  return mnt;

  }

  kernel/fs/super.c

  struct vfsmount *

  vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)

  {

  mnt = alloc_vfsmnt(name); //建立并填充vfsmount

  error = type->get_sb(type, flags, name, data, mnt);//為文件系統(tǒng)建立并填充超級(jí)塊(主要是其dentry和inode),,建立rootfs根目錄

  mnt->mnt_mountpoint = mnt->mnt_root; //文件系統(tǒng)掛載點(diǎn)目錄,其實(shí)就是剛才建立的”/”目錄。掛載點(diǎn)就是自己?。,。。?br/>
  mnt->mnt_parent = mnt; //父對(duì)象是自己?。,。?!

  return mnt;

  }kernel/fs/ramfs/inode.cstatic int rootfs_get_sb(struct file_system_type *fs_type,

  int flags, const char *dev_name, void *data, struct vfsmount *mnt)

  {

  return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super,

  mnt);

  }

  kernel/fs/super.c

  int get_sb_nodev(struct file_system_type *fs_type,

  int flags, void *data,

  int (*fill_super)(struct super_block *, void *, int),

  struct vfsmount *mnt)

  {

  struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);

  //在內(nèi)存中分配一個(gè)超級(jí)塊

  error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);

  //執(zhí)行回調(diào),,填充超級(jí)塊,并建立根目錄項(xiàng)及對(duì)應(yīng)i節(jié)點(diǎn)

  /*

  kernel/fs/ramfs/inode.c

  static int ramfs_fill_super(struct super_block * sb, void * data, int silent)

  {

  struct inode * inode;

  struct dentry * root;

  sb->s_maxbytes = MAX_LFS_FILESIZE;

  sb->s_blocksize = PAGE_CACHE_SIZE;

  sb->s_blocksize_bits = PAGE_CACHE_SHIFT;

  sb->s_magic = RAMFS_MAGIC;

  sb->s_op = &ramfs_ops;

  //static const struct super_operations ramfs_ops;

  sb->s_time_gran = 1;

  //建立根目錄索引節(jié)點(diǎn),,我們最終的目標(biāo)是要找到目錄項(xiàng)對(duì)象關(guān)聯(lián)的索引節(jié)點(diǎn),。

  //根目錄索引節(jié)點(diǎn)會(huì)有自己的ops。

  inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);

  //ramfs_get_inode

  kernel/fs/ramfs/inode.c

  struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)

  {

  struct inode * inode = new_inode(sb);

  switch (mode & S_IFMT) { //判斷文件類型

  default:

  init_special_inode(inode, mode, dev);

  //init_special_inode

  void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)

  {

  inode->i_mode = mode;

  if (S_ISCHR(mode)) {//字符設(shè)備文件

  inode->i_fop = &def_chr_fops;

  inode->i_rdev = rdev;

  } else if (S_ISBLK(mode)) {//塊設(shè)備文件

  inode->i_fop = &def_blk_fops;

  inode->i_rdev = rdev;

  } else if (S_ISFIFO(mode))

  inode->i_fop = &def_fifo_fops;

  else if (S_ISSOCK(mode)) //網(wǎng)絡(luò)設(shè)備文件

  inode->i_fop = &bad_sock_fops;

  else

  printk(KERN_DEBUG 'init_special_inode: bogus i_mode (%o) for'

  ' inode %s:%lu\n', mode, inode->i_sb->s_id,

  inode->i_ino);

  }

  //init_special_inode end

  break;

  case S_IFREG: //普通文件

  inode->i_op = &ramfs_file_inode_operations; //索引節(jié)點(diǎn)的操作方法

  inode->i_fop = &ramfs_file_operations; //缺省普通文件的操作方法

  break;

  case S_IFDIR: //目錄文件

  inode->i_op = &ramfs_dir_inode_operations;

  //ramfs_dir_inode_operations

  static const struct inode_operations ramfs_dir_inode_operations;

  kernel/include/linux/fs.h

  struct inode_operations {

  int (*create) (struct inode *,struct dentry *,int, struct nameidata *);

  int (*mkdir) (struct inode *,struct dentry *,int);

  int (*rmdir) (struct inode *,struct dentry *);

  int (*mknod) (struct inode *,struct dentry *,int,dev_t);

  }

  //ramfs_dir_inode_operations end

  inode->i_fop = &simple_dir_operations; //目錄文件的操作方法

  inc_nlink(inode);

  break;

  }

  }

  //ramfs_get_inode end

  //建立根目錄目錄對(duì)象,,目錄項(xiàng)對(duì)象的存在主要是為了我們進(jìn)行路徑的查找,。

  root = d_alloc_root(inode);

  //d_alloc_root

  kernel/fs/dcache.c

  struct dentry * d_alloc_root(struct inode * root_inode)

  {

  struct dentry *res = NULL;

  static const struct qstr name = { .name = '/', .len = 1 };

  res = d_alloc(NULL, &name);

  res->d_sb = root_inode->i_sb; //指向該文件系統(tǒng)的超級(jí)塊

  res->d_parent = res; //根目錄的父親是它自己

  d_instantiate(res, root_inode); //關(guān)聯(lián) dentry 和 inode

  }

  //d_alloc_root end

  sb->s_root = root; //超級(jí)塊的s_root指向剛建立的根目錄對(duì)象。

  }

  */

  return simple_set_mnt(mnt, s); //關(guān)聯(lián)超級(jí)塊(包含目錄項(xiàng)dentry和i節(jié)點(diǎn)inode)和vfsmount

  }kernel/fs/namespace.c

  int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)

  {

  printk('TK-------_>>>>>>>namespace.c>>>>simple_set_mnt\n');//add by tankai

  mnt->mnt_sb = sb; //對(duì) mnt_sb超級(jí)塊指針附值

  mnt->mnt_root = dget(sb->s_root); //對(duì)mnt_root指向的根目錄賦值

  return 0;

  }

  至此,,rootfs文件系統(tǒng)建立,、并且掛載于自己超級(jí)塊(包括目錄項(xiàng)dentry和i節(jié)點(diǎn)inod)對(duì)應(yīng)的目錄項(xiàng),設(shè)置了系統(tǒng)current根目錄和根文件系統(tǒng),、pwd的目錄和文件系統(tǒng),。

  ========================================

  釋放Initramfs到rootfs;如果Initramfs中有init,,這種情況比較特殊,、rootfs就是最后系統(tǒng)使用的根文件系統(tǒng)。

  而且此時(shí),,不需要在單獨(dú)燒錄根文件系統(tǒng)的img,;此時(shí),根文件系統(tǒng)就是內(nèi)核uImage的一部分,。當(dāng)然,,缺陷就是該文件系統(tǒng)運(yùn)行時(shí)的介質(zhì)是ramdisk即內(nèi)存盤、它不再與磁盤對(duì)應(yīng),;因此,,此時(shí)修改根目錄下的文件將不被得到保存。它的內(nèi)核配置項(xiàng)為:CONFIG_INITRAMFS_SOURCE,。實(shí)際項(xiàng)目中會(huì)經(jīng)常碰到,。

  make menuconfig->General setup->Initial RAM filesystem and RAM disk(initramfs/initrd) support

  底下的Initramfs source file(s)填寫根文件系統(tǒng)的路徑,如:../out/target/product/tclm6/root,;不填的話,,將導(dǎo)致initrd或磁盤文件系統(tǒng)的掛載(因?yàn)橄逻厡?huì)看到,內(nèi)核將找不到“/init”),。

  對(duì)應(yīng)內(nèi)核源碼:

  kernel/init/main.cstatic int __init kernel_init(void * unused){

  ......

  do_basic_setup(); //初始化設(shè)備驅(qū)動(dòng),,加載靜態(tài)內(nèi)核模塊,;釋放Initramfs到rootfs

  /*

  kernel/init/initramfs.c

  rootfs_initcall(populate_rootfs);

  static int __init populate_rootfs(void)

  {

  printk(KERN_INFO 'checking if image is initramfs...');

  err = unpack_to_rootfs((char *)initrd_start,

  initrd_end - initrd_start, 1); //釋放ramdisk到rootfs

  }

  */

  ......

  if (!ramdisk_execute_command) ramdisk_execute_command = '/init';

  if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {

  ramdisk_execute_command = NULL;

  //如果此時(shí)rootfs中沒有init,則加載initfd,、nfs或磁盤文件系統(tǒng)

  //也即磁盤的文件系統(tǒng)掛載至rootfs的/root目錄,,并設(shè)置系統(tǒng)current對(duì)應(yīng)的根目錄項(xiàng)為磁盤根目錄項(xiàng)、系統(tǒng)current根文件系統(tǒng)為磁盤文件系統(tǒng)

  //至此,,rootfs對(duì)于以后所有進(jìn)程而言,、已被隱藏。

  prepare_namespace();

  }

  init_post(); //啟動(dòng)init進(jìn)程

  ......

  }

  看看init_post實(shí)現(xiàn):

  static noinline int init_post(void)

  {

  if (ramdisk_execute_command) { //Initramfs從這里啟動(dòng)init

  run_init_process(ramdisk_execute_command);

  printk(KERN_WARNING 'Failed to execute %s\n', ramdisk_execute_command);

  }

  //initrd,、nfs和磁盤都是從如下啟動(dòng)的init

  if (execute_command) {

  run_init_process(execute_command);

  printk(KERN_WARNING 'Failed to execute %s. Attempting '

  'defaults...\n', execute_command);

  }

  //一般執(zhí)行如下

  run_init_process('/sbin/init');

  run_init_process('/etc/init');

  run_init_process('/bin/init');

  run_init_process('/bin/sh');

  }

  四,、掛載實(shí)際文件系統(tǒng)至rootfs,并調(diào)用set_fs_root設(shè)置為系統(tǒng)current的根文件系統(tǒng)

  下邊從uboot啟動(dòng)內(nèi)核參數(shù)的角度來(lái)簡(jiǎn)單說(shuō)明:

  以下三種情況都是將文件系統(tǒng)掛載到rootfs的/root目錄,,并將系統(tǒng)current的根目錄切換為/root,、系統(tǒng)current的根文件系統(tǒng)切換為磁盤文件系統(tǒng)。

  kernel/init/do_mounts.c

  void __init prepare_namespace(void)

  {

  if (initrd_load()) //如果掛載initrd并執(zhí)行成功,,則不再掛載磁盤文件系統(tǒng)

  goto out;

  if (saved_root_name[0]) {

  root_device_name = saved_root_name;

  if (!strncmp(root_device_name, 'mtd', 3) ||

  !strncmp(root_device_name, 'ubi', 3)) {

  mount_block_root(root_device_name, root_mountflags); //啟動(dòng)時(shí)root=參數(shù),,如《四.2》中“root=/dev/mtdblock0”

  goto out;

  }

  ROOT_DEV = name_to_dev_t(root_device_name);

  if (strncmp(root_device_name, '/dev/', 5) == 0)

  root_device_name += 5;

  }

  mount_root(); //將實(shí)際文件系統(tǒng)掛載到rootfs的/root目錄

  out:

  //sys_mount('.', '/', NULL, MS_MOVE, NULL); 這句話無(wú)關(guān)緊要,影響理解,;屏蔽不影響功能

  sys_chroot('.'); //將當(dāng)前目錄(/root)設(shè)置為系統(tǒng)current根目錄,,磁盤文件系統(tǒng)設(shè)置為系統(tǒng)current根文件系統(tǒng)。

  }

  下邊分兩步解釋mount_root()和sys_chroot('.')調(diào)用:

  1.將nfs或磁盤文件系統(tǒng)掛載至rootfs的/root目錄(以磁盤為例)

  void __init mount_root(void)

  {

  if (mount_nfs_root()) //如果網(wǎng)絡(luò)文件系統(tǒng)掛載成功,,則nfs作為根文件系統(tǒng)

  return;

  //掛載磁盤文件系統(tǒng)為根文件系統(tǒng)

  //在rootfs中建立/dev/root設(shè)備文件

  create_dev('/dev/root', ROOT_DEV); //在rootfs中建立/dev/root設(shè)備文件,也就是/dev/mtdblock0設(shè)備,。

  //掛載/dev/root到rootfs的/root目錄

  mount_block_root('/dev/root', root_mountflags);

  }

  void __init mount_block_root(char *name, int flags)

  {

  int err = do_mount_root(name, p, flags, root_mount_data);

  }

  static int __init do_mount_root(char *name, char *fs, int flags, void *data)

  {

  int err = sys_mount(name, '/root', fs, flags, data);//將/dev/root掛載到/root

  sys_chdir('/root'); //系統(tǒng)current->fs->pwd為當(dāng)前目錄/root

  ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;

  return 0;

  }

  2.將當(dāng)前目錄/root設(shè)置為系統(tǒng)current根目錄,,磁盤文件系統(tǒng)設(shè)置為系統(tǒng)current根文件系統(tǒng)

  分析sys_chroot('.'):見Linux內(nèi)核編程之C語(yǔ)言預(yù)處理功能與宏

  fs/open.c

  SYSCALL_DEFINE1(chroot, const char __user *, filename)

  {

  struct path path;

  error = user_path_dir(filename, &path);

  //這才是完成切換的關(guān)鍵!?。,。≌麄€(gè)內(nèi)核代碼只有兩處調(diào)用

  set_fs_root(current->fs, &path);

  }

  注意,,如下情況:rootfs特殊文件系統(tǒng)沒有被卸載,,他只是隱藏在基于磁盤的根文件系統(tǒng)下了。

  initrd作為根文件系統(tǒng)

  setenv bootargs root=/dev/ram0 initrd=0x2800000,24M rootfstype=ext2 mem=64M console=ttyAMA0

  參數(shù)說(shuō)明:

  root:用來(lái)指定rootfs的位置,。

  rootfstype:用來(lái)指定文件系統(tǒng)的類型,。

  nfs作為根文件系統(tǒng)

  setenv bootargs root=/dev/nfs nfsroot=192.168.1.7:/opt/yz/nfs,rw ip=192.168.1.160 mem=64M console=ttyAMA0

  參數(shù)說(shuō)明:

  nfsroot:文件系統(tǒng)在哪臺(tái)主機(jī)的哪個(gè)目錄下。

  ip:指定系統(tǒng)啟動(dòng)之后網(wǎng)卡的ip地址,。

  flash作為根文件系統(tǒng)

  setenv bootargs root=/dev/mtdblock0 mem=16M mtdparts=armflash.1:4M@0x400000(jffs2) macaddr=9854 rootfstype=jffs2 console=ttyAMA0

  參數(shù)說(shuō)明:

  mtdparts:根文件系統(tǒng)在flash中的位置,。

  總結(jié):rootfs永遠(yuǎn)不會(huì)被卸載,它只是被隱藏了,。在用戶空間下,,更多地情況是只能見到rootfs這棵大樹的一葉,,而且還是被安裝過(guò)文件系統(tǒng)了的。

  五,、其他說(shuō)明

  至于在mirco2440下mount出的結(jié)果:

  rootfs on / type rootfs (rw)

  /dev/root on / type yaffs (rw,relatime)

  none on /proc type proc (rw,relatime)

  none on /sys type sysfs (rw,relatime)

  none on /proc/bus/usb type usbfs (rw,relatime)

  none on /dev type ramfs (rw,relatime)

  none on /dev/pts type devpts (rw,relatime,mode=622)

  tmpfs on /dev/shm type tmpfs (rw,relatime)

  none on /tmp type ramfs (rw,relatime)

  none on /var type ramfs (rw,relatime)

  從log中體會(huì)一下這個(gè)過(guò)程:

  s3c2410-rtc s3c2410-rtc: setting system clock to 2006-04-16 22:15:34 UTC (1145225734)

  TK------->>>>>init/main.c>>>>>>kernel_init>>before>prepare_namespace

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is rootfs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is rootfs

  ##################################################################################################################

  TK------->>>>>init/do_mounts.c>>>>>>prepare_namespace>>before>mount_root

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is rootfs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is rootfs

  ##################################################################################################################

  yaffs: dev is 32505859 name is 'mtdblock3'

  yaffs: passed flags ''

  yaffs: Attempting MTD mount on 31.3, 'mtdblock3'

  yaffs_read_super: isCheckpointed 0

  VFS: Mounted root (yaffs filesystem) on device 31:3.

  TK------->>>>>init/do_mounts.c>>>>>>prepare_namespace>>before>sys_mount

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is rootfs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  TK------->>>>>init/do_mounts.c>>>>>>prepare_namespace>>before>sys_chroot

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is rootfs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  TK------->>>>>fs/open.c>>>>>>SYSCALL_DEFINE1(chroot>>before>set_fs_root

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is rootfs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  TK------->>>>>init/do_mounts.c>>>>>>SYSCALL_DEFINE1(chroot>>after>set_fs_root

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  TK------->>>>>init/do_mounts.c>>>>>>prepare_namespace>>after>sys_chroot

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  TK------->>>>>init/main.c>>>>>>kernel_init>>after>prepare_namespace

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  ##################################################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is root

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is yaffs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is yaffs

  ##################################################################################################################

  Freeing init memory: 156K

  [16/Apr/2006:14:15:35 +0000] boa: server version Boa/0.94.13

  [16/Apr/2006:14:15:35 +0000] boa: server built Mar 26 2009 at 15:28:42.

  [16/Apr/2006:14:15:35 +0000] boa: starting server pid=681, port 80

  Try to bring eth0 interface up......eth0: link down

  Done

  Please press Enter to activate this console.

  [root@FriendlyARM /]# mount

  rootfs on / type rootfs (rw)

  /dev/root on / type yaffs (rw,relatime)

  none on /proc type proc (rw,relatime)

  none on /sys type sysfs (rw,relatime)

  none on /proc/bus/usb type usbfs (rw,relatime)

  none on /dev type ramfs (rw,relatime)

  none on /dev/pts type devpts (rw,relatime,mode=622)

  tmpfs on /dev/shm type tmpfs (rw,relatime)

  none on /tmp type ramfs (rw,relatime)

  none on /var type ramfs (rw,relatime)

  [root@FriendlyARM /]#

  ubuntu下mount出的結(jié)果:

  /dev/sda5 on / type ext3 (rw,errors=remount-ro,commit=0)

  proc on /proc type proc (rw,noexec,nosuid,nodev)

  sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)

  fusectl on /sys/fs/fuse/connections type fusectl (rw)

  none on /sys/kernel/debug type debugfs (rw)

  none on /sys/kernel/security type securityfs (rw)

  udev on /dev type devtmpfs (rw,mode=0755)

  devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)

  tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)

  none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)

  none on /run/shm type tmpfs (rw,nosuid,nodev)

  /dev/sda7 on /home type ext3 (rw,commit=0)

  binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)

  rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)

  nfsd on /proc/fs/nfsd type nfsd (rw)

  gvfs-fuse-daemon on /home/tankai/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=tankai)

  一個(gè)還顯示rootfs,,一個(gè)干脆不顯示。這個(gè)無(wú)關(guān)緊要,??赡躮icro2440中執(zhí)行mount命令還會(huì)將系統(tǒng)current根目錄的父節(jié)點(diǎn)也顯示出來(lái);而ubuntu下不會(huì)再去關(guān)心系統(tǒng)current根目錄的父節(jié)點(diǎn),。但所有的文件搜索,,內(nèi)核都是從系統(tǒng)current根目錄開始向下查找的,因此,、可以說(shuō)我們不能在訪問(wèn)rootfs中除了作為系統(tǒng)current根文件系統(tǒng)之外的其他任何節(jié)點(diǎn),。

  六、測(cè)試用例,,說(shuō)明系統(tǒng)current的文件系統(tǒng)布局,,不管在那個(gè)目錄、其根都不會(huì)改變:

  hello.c

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  //#include 'pnode.h'

  //#include 'internal.h'

  #include

  #include

  MODULE_LICENSE('Dual BSD/GPL');

  static int hello_init(void)

  {

  printk(KERN_ALERT 'Hello, world\n');

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is %s\n',current->fs->root.dentry->d_name.name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is %s\n',current->fs->root.dentry->d_sb->s_type->name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is %s\n',current->fs->root.mnt->mnt_mountpoint->d_name.name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is %s\n',current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is %s\n',current->fs->root.mnt->mnt_root->d_name.name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is %s\n',current->fs->root.mnt->mnt_root->d_sb->s_type->name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is %s\n',current->fs->root.mnt->mnt_sb->s_type->name);

  printk('########################################################################################\n');

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is %s\n',current->fs->pwd.dentry->d_name.name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is %s\n',current->fs->pwd.dentry->d_sb->s_type->name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is %s\n',current->fs->pwd.mnt->mnt_mountpoint->d_name.name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is %s\n',current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is %s\n',current->fs->pwd.mnt->mnt_root->d_name.name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is %s\n',current->fs->pwd.mnt->mnt_root->d_sb->s_type->name);

  printk('TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is %s\n',current->fs->pwd.mnt->mnt_sb->s_type->name);

  return 0;

  }

  static void hello_exit(void)

  {

  printk(KERN_ALERT'Goodbye, cruel world\n');

  }

  module_init(hello_init);

  module_exit(hello_exit);Makefile

  ifneq ($(KERNELRELEASE),)

  obj-m:=hello.o

  else

  KERNELDIR:=/home/android2.3/android2.3_kernel/

  PWD:=$(shell pwd)

  default:

  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

  clean:

  rm -rf *.o *.mod.c *.mod.o *.ko

  endif

  make生成hello.ko

  先看下文件系統(tǒng)布局:

  mount

  rootfs / rootfs ro 0 0

  tmpfs /dev tmpfs rw,mode=755 0 0

  devpts /dev/pts devpts rw,mode=600 0 0

  proc /proc proc rw 0 0

  sysfs /sys sysfs rw 0 0

  none /acct cgroup rw,cpuacct 0 0

  tmpfs /mnt/asec tmpfs rw,mode=755,gid=1000 0 0

  tmpfs /mnt/obb tmpfs rw,mode=755,gid=1000 0 0

  none /dev/cpuctl cgroup rw,cpu 0 0

  /dev/block/mtdblock0 /system yaffs2 rw 0 0

  /dev/block/mtdblock1 /data yaffs2 rw,nosuid,nodev 0 0

  /dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0

  /dev/block/vold/179:0 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0

  /dev/block/vold/179:0 /mnt/secure/asec vfat rw,dirsync,nosuid,nodev,noexec,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0

  tmpfs /mnt/sdcard/.android_secure tmpfs ro,size=0k,mode=000 0 0

  1.放入/data/下運(yùn)行insmod hello.ko rmmod hello.ko

  Hello, world

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is rootfs

  ########################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is yaffs2

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is data

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is yaffs2

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is yaffs2

  Goodbye, cruel world2.放在/sdcard/tank/下運(yùn)行insmod hello.ko rmmod hello.koHello, world

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.dentry->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_root->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->root.mnt->mnt_sb->s_type->name is rootfs

  ########################################################################################

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_name.name is tank

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.dentry->d_sb->s_type->name is vfat

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_name.name is sdcard

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_mountpoint->d_sb->s_type->name is rootfs

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_name.name is /

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_root->d_sb->s_type->name is vfat

  TK---->>>>init/main.c>>>kernel_init>>>>current->fs->pwd.mnt->mnt_sb->s_type->name is vfat

  Goodbye, cruel world

  由此證明,;current->fs->root就是系統(tǒng)承認(rèn)的根文件系統(tǒng),。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多