新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 低固存嵌入式系統(tǒng)的uClinux小型化方法

低固存嵌入式系統(tǒng)的uClinux小型化方法

作者: 時(shí)間:2011-06-21 來源:網(wǎng)絡(luò) 收藏
1.2.1 對調(diào)用的影響

本文引用地址:http://m.butianyuan.cn/article/150585.htm

  調(diào)用約有177個(gè),包括關(guān)于進(jìn)程的調(diào)用函數(shù)、文件的調(diào)用函數(shù),以及其它相關(guān)的調(diào)用,其中文件的調(diào)用占了71個(gè)。由于沒有根系統(tǒng),系統(tǒng)調(diào)用中涉及到從根文件系統(tǒng)上或掛接在它某個(gè)文件節(jié)點(diǎn)上的其它文件系統(tǒng)上,裝載、執(zhí)行可執(zhí)行文件的系統(tǒng)調(diào)用都是沒必要的,所以必須做相應(yīng)的更改。典型的是系統(tǒng)調(diào)用execve(),其執(zhí)行流程主干線如圖2所示。

  exeeve()

  ↓

  do_exeeve()

  ↓

  open_execve()

  ↓

  prepare_binpma()

  ↓

  search_binary_hanlder()

  圖2 execve()執(zhí)行流程

  do_execve()是execve()的核心,它調(diào)用open_exec()尋找可執(zhí)行文件并打開,函數(shù)open_exec()返回一個(gè)file結(jié)構(gòu)指針,代表著讀入可執(zhí)行文件的上下文,將其保存在數(shù)據(jù)結(jié)構(gòu)bprm中。然后調(diào)用prepare_binprm()完成對bprm的進(jìn)一步工作,包括從可執(zhí)行文件頭讀取相關(guān)信息,以及拷貝運(yùn)行環(huán)境參數(shù)等到bprm 中。內(nèi)核中有一個(gè)叫formats的隊(duì)列,隊(duì)列中的每個(gè)成員只認(rèn)識并且處理一種特定格式的可執(zhí)行文件的運(yùn)行。search_binary_handler()就是在formats的隊(duì)列中,尋找跟bprm中信息相符的一個(gè)成員,并由此成員來完成可執(zhí)行文件的裝載并初始化運(yùn)行。由于不存在從文件系統(tǒng)加載可執(zhí)行文件,所以bpma數(shù)據(jù)結(jié)構(gòu),及涉及prepare_binprm(),search_binary_hanlder()等相關(guān)操作都是可以刪除的。

  再者,由于沒有可供mount的文件節(jié)點(diǎn),所以有關(guān)掛接的系統(tǒng)調(diào)用也必須做出調(diào)整。比如:mount()是用于文件系統(tǒng)掛接的系統(tǒng)調(diào)用,完全可以刪去;內(nèi)核函數(shù)mount_root()在初始化時(shí)用于安裝根文件系統(tǒng),也是可以刪去的;vfsmount()是內(nèi)核數(shù)據(jù)結(jié)構(gòu),用于描述掛載節(jié)點(diǎn)的信息,包括掛載點(diǎn)的根目錄,被掛載系統(tǒng)的級塊指針等信息。vfsmount()完全是跟掛載有關(guān)的,可以將它刪除,同時(shí)內(nèi)核中有好多涉及操作此數(shù)據(jù)結(jié)構(gòu)的函數(shù)也必須做出更改。比如alloc_vfsmnt()和free_vfsmnt()是分配和釋放vfsmount結(jié)構(gòu),完全可以刪去,但有些內(nèi)核函數(shù)只有一部分涉及到對vfsrmnt結(jié)構(gòu)的操作,所以不能全部刪除,必須對相應(yīng)部分做出修改。

  1.2.2 對內(nèi)核啟動(dòng)初始化的影響

  由于init()進(jìn)程不能從根文件系統(tǒng)加載,所以凡是涉及根文件系統(tǒng)初始化函數(shù)的都必須刪除,以支持內(nèi)核與應(yīng)用程序一體化。初始化進(jìn)程init代碼如下:

  static int init(void *unused)

  {……

  if(open(/dev/console,O_RDWR,0) 0)

  ……

  if(execute_command)

  execve(execute_command,argv_init,envp_init);

  execve(/sbin/init,argv_init;envp_init);

  ……

  panic(No init found.Try passing init= option to kernel);

  }

  init()完成系統(tǒng)的初始化,包括外部設(shè)備的初始化,釋放init()前初始化后代碼占用的內(nèi)存,以及控制臺的初始化,最后從根文件系統(tǒng)加載整個(gè)系統(tǒng)的第一個(gè)進(jìn)程init,它是所有進(jìn)程的“鼻祖”。由于根文件的刪除,所以可以刪除控制臺以及調(diào)用init進(jìn)程。

  1.2.3 對ReFS和外部設(shè)備的影響

  ReFS可以像mount_root()那樣直接把ReFS當(dāng)成根文件系統(tǒng)來裝,但它并不像根文件系統(tǒng)那樣有bash,gretty等應(yīng)用程序,也不具備掛載其它系統(tǒng)的能力,所以不是真正的根文件系統(tǒng)。內(nèi)核中有幾個(gè)根文件系統(tǒng)和外設(shè)相關(guān)的重要內(nèi)核級全局變量:file_system_type,btkdevs[MAX_BLKDEV],chrdevs[MAX_CHRDEV],super_block。

  file_system_type是一個(gè)描述系統(tǒng)中所有支持的文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)。VFS在內(nèi)存中維護(hù)這樣一個(gè)數(shù)據(jù)結(jié)構(gòu)的列表,全局指針變量為file_systems。新文件系統(tǒng)必須通過register_filesystem()來注冊以讓系統(tǒng)識別,即是在鏈表file_systems結(jié)尾插人一個(gè)file_systm_type數(shù)據(jù)結(jié)構(gòu)。blkdevs[MAX_BLKDEV]和chrdevs[MAX_CHRDEV]分別為塊設(shè)備和字符設(shè)備的注冊數(shù)組,包含主設(shè)備號和次設(shè)備號,以及有關(guān)設(shè)備操作的跳轉(zhuǎn)指針。塊設(shè)備和字符設(shè)備分別通過register_blkdev()和register_chrdev()向系統(tǒng)注冊設(shè)備。super_block是超級塊數(shù)據(jù)結(jié)構(gòu),存放著整個(gè)文件系統(tǒng)的信息和超級塊操作的函數(shù)。在通用內(nèi)核中根文件系統(tǒng)的安裝的順序是:從file_systems處取得根文件系統(tǒng)的read_super(),read_super()指向具體的驅(qū)動(dòng)程序讀操作,通過讀取得超級塊,然后在內(nèi)存中創(chuàng)建inode,file,dentry等數(shù)據(jù)結(jié)構(gòu),用于文件的讀寫操作。

  在這里,同樣可以用與根文件系統(tǒng)相同的裝載來初始化ReFS,但是比前者簡單多,因?yàn)楹笳卟簧婕鞍惭b掛載點(diǎn)及與此相關(guān)的操作。對于外設(shè),內(nèi)核一般是通過根文件系統(tǒng)搜索到設(shè)備文件,再來訪問外設(shè),當(dāng)中要涉及到搜索路徑和掛接點(diǎn)到外設(shè)翻譯的問題,而在這里外設(shè)是獨(dú)立的,不依賴于根系統(tǒng),所以實(shí)現(xiàn)起來更簡單,可以直接依據(jù)內(nèi)核數(shù)據(jù)結(jié)構(gòu)blkdevs[]和chrdevs[]提供的操作函數(shù)表指針,來操作具體的驅(qū)動(dòng)程序操作外設(shè)。

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

linux相關(guān)文章:linux教程




評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉