FreeBSD学习总结
生活随笔
收集整理的這篇文章主要介紹了
FreeBSD学习总结
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
FreeBSD完全入門手冊
http://www.jb51.net/os/Unix/1525.html雖然非常基礎(chǔ),但是對于初學者非常有用的,相信不管是初學者還是非初學者,都是有用的。 引用:送
給FreeBSD和UNIX的初學者 Annelise Anderson August 15, 1997 引用: 1.登錄和退出引用: ? ? ??
登錄時(當看到login:時)你必?
雖然非常基礎(chǔ),但是對于初學者非常有用的,相信不管是初學者還是非初學者,都是有用的。
引用:送給FreeBSD和UNIX的初學者?
Annelise?
Anderson?
August 15, 1997
引用:?
1.登錄和退出引用:?
? ? ? 登錄時(當看到login:時)你必須是在系統(tǒng)安裝時創(chuàng)建的用戶或root超級用戶.(在FreeBSD系統(tǒng)安裝
時就已經(jīng)創(chuàng)建了root用戶了 ,root用戶遍歷到系統(tǒng)的任何一個目錄并且可以做任何事情,包括刪除系統(tǒng)文
件,所以一定要千萬小心!)符號%和符號# 代表提示符(你的可能不一樣),%表示普通用戶,#表示超級用戶
root要退出系統(tǒng)(并且回到login:提示符),打命令:?
? ? ? # exit?
? ? ? 對,打完命令后按回車,記住UNIX對命令是區(qū)分大小寫的--也就是說,是exit,而不是EXIT.?
? ? ? 要關(guān)閉機器,打命令:?
? ? ? # /sbin/shutdown -h now?
? ? ? 要重啟機器,打命令:?
? ? ? # /sbin/shutdown -r now?
? ? ? 或者?
? ? ? # /sbin/reboot?
? ? ? 你也可以按Ctrl-Alt-Delete來重啟機器.?
? ? ? 花少許時間練習一下.在最近發(fā)行的FreeBSD版本中這和/sbin/reboot是相等的,而且這比按reset
按鈕要好多了.你也不想重裝東西,難道不是嗎?
2.用Root權(quán)限添加用戶引用:?
? ? ? 當你第一次運行adduser時,它也許會創(chuàng)建一些缺省設(shè)置.在它建議你把sh作為缺省shell的時候,你
可能想把csh作為缺省shell 而不是sh.否則直接按回車接受默認值.這些默認設(shè)置保存
在/etc/adduser.conf中,一個可編輯文件.?
? ? ? # adduser?
? ? ? 假如你創(chuàng)建了一個新用戶jack全名為Jack Benimble.出于安全因素,給jack一個口令(即使周圍的
孩子也可能敲擊鍵盤).當它問你是否想jack成為某個組的成員時,回答wheel?
? ? ? Login group is ``jack''. Invite jack into other groups: wheel?
? ? ? 這樣就可以用戶jack登錄系統(tǒng),再用su命令成為root超級用戶.然后你就再也不會因為以root超級
用戶登錄而受到責備了.
? ? ? 你可以在adduser中,通過按Ctrl-C退出隨時退出.在創(chuàng)建結(jié)束時你可以批準該用戶的生成或打n來
取消創(chuàng)建該用戶.你也許想創(chuàng)建第二個用戶(jill?)這樣當你編輯jack的登錄文件時,就有一個熱備份以免
出錯.一旦創(chuàng)建完用戶,exit用exit回到login:提示符以jack登錄.通常情況下,最好不要用root用戶而是
用普通用戶完成大部分的工作.如果你已經(jīng)創(chuàng)建了一個用戶而且想使該用戶能夠用su命令成為root用戶,
你可以root登錄然后編輯文件/etc/group,把jack加入第一行(wheel組),但是你首先要練習使用vi,文本
編輯器--或簡單些的編輯器,安裝在最近發(fā)行的FreeBSD中的ee.
? ? ? 要刪除一個用戶使用rmuser命令.
3. 環(huán)顧四周引用:?
? ? ? 以普通用戶登錄,四處瀏覽一下再使用一些命令試著訪問幫助資源和FreeBSD的別的信息.以下是一
些命令和它們的功能:?
? ? ? id 告訴你你是誰!?
? ? ? pwd 顯示你在哪個目錄--當前工作目錄.?
? ? ? ls 顯示當前目錄的文件.?
? ? ? ls -F 顯示當前目錄的文件.執(zhí)行文件的文件名后加*,目錄名后加/,符號鏈接后加@.?
? ? ? ls -l 以長格式顯示文件.?
? ? ? ls -a 列出隱藏點文件和其它文件.如果你是root用戶,無須加-a選項,點文件將自動顯示.?
? ? ? cd 改變目錄.?
? ? ? cd .. 回到上級目錄;注意cd后的空格.?
? ? ? cd /usr/local 到/usr/local目錄下.?
? ? ? cd ~ 到以登錄用戶的主目錄--例如/usr/home/jack.?
? ? ? 試試cd /cdrom,然后ls, 看看你的CDROM是否mounted并且正常工作.?
? ? ? view filename?
? ? ? 讓你看一個文件(文件名為filename 不改變文件名).試試?
? ? ? view /etc/fstab.?
? ? ? :q :q退出.?
? ? ? cat filename?
? ? ? 在屏幕上顯示filename.如果文件太長你只能看到文件的最末部分,按ScrollLock 然后用上下鍵往
回移; ? ? ? ? ? ??
? ? ? ScrollLock鍵在看手冊的時候也用的上.再按一下ScrollLock將退出屏幕滾動.你可以試一下cat你
主目錄的點文件cat .cshrc , cat .login , cat .profile.?
? ? ? 你也許注意到了.cshrc文件中有關(guān)ls命令的別名(它們用起來很方便).你可以編輯.cshrc文件來創(chuàng)
建一些別的別名.為了使系統(tǒng)的所有用戶都能使用這些別名,把它們放到csh的系統(tǒng)配置文
件/etc/csh.cshrc中.
4. 獲得幫助信息引用:?
? ? ? 這里有一些關(guān)于幫助的有用的資源.text表示你從鍵盤打入的東西--通常是一條命令或文件名.?
? ? ? apropos text 在whatis數(shù)據(jù)庫中所有包含text的有關(guān)信息.?
? ? ? man text?
? ? ? text的手冊.是Un*x系統(tǒng)文檔的主要來源.man ls會告訴你使用ls命令的所有方法.按回車鍵在文本
中移動,Ctrl-b往前翻一頁,Ctrl-f往后翻一頁,q或Ctrl-c退出.?
? ? ? which text 告訴你text命令所在的路徑.?
? ? ? locate text 所有找到text字符串的路徑.?
? ? ? whatis text?
? ? ? 告訴你text命令主要用來干什么和它的手冊頁.打入whatis *將告訴你當前目錄中的所有命令的有
關(guān)信息.?
? ? ? whereis text 尋找text文件,并給出它的完全路徑.?
? ? ? 你可能想對一些常用命令如cat, more,grep,mv,find,tar,chmod,chown,date,和script使用
whatis命令.more命令可以讓你以DOS的方式一次只閱讀一頁內(nèi)容. 例如: ls -l | more 或 more?
filename.符號*代表通配符--例如:ls w*將顯示所有以w開頭的文件名.
? ? ? 這些命令是不是并不太有效?locate和whatis命令都取決于每星期重建一次的數(shù)據(jù)庫.如果你不準
備讓你的機器在周末也運行的話(運行FreeBSD),你也許希望不時地每天、每星期、每月運行這些命令?
現(xiàn)在,以root身份運行這些命令然后在運行下條命令之前指定一個結(jié)束時間.?
? ? ? # /etc/daily 輸出省略?
? ? ? # /etc/weekly 輸出省略?
? ? ? # /etc/monthly 輸出省略?
? ? ? 如果你等的不耐煩了,按Alt-F2到另一個虛擬控制臺上并登錄進去.實際上FreeBSD是一個多用戶、
多任務(wù)系統(tǒng).不過這些命令在運行時出現(xiàn)的信息大概會在你的屏幕上顯示一下;你可以打clear命令清除
屏幕.一旦它們開始運行了,你可以看看/var/mai l/root和/var/log/messages著兩個目錄.
? ? ? 你是你自己系統(tǒng)的管理員,作為一個系統(tǒng)管理員或Unix系統(tǒng)的單用戶,運行這些命令是最基本的.實
質(zhì)上,所有你須要已root身份做的事情就是系統(tǒng)管理.這種職責在那些又大又厚的Unix書里并沒有得到很
好的概括,這些書籍似乎花了很大空間用來說明w indows管理器的下拉菜單.系統(tǒng)管理方面的書你應(yīng)該看
看以下兩本,
? ? ? 紅封面的Evi Nemeth et.al.'s UNIX System Administration Handbook(Prentice-Hall, 1995,?
ISBN 0-13-15051-7)--the second edition,另外一本為aleen Frisch's Essential System?
Administration (O'Reilly & Associates, 1993,ISBN 0-937175-80-3).我使用的是Nemeth的書.
5. 文本編輯引用:?
? ? ? 配置系統(tǒng)的時候,一般都要編輯文本文件.大多數(shù)要編輯的都在/etc目錄下,你需要使用su成為root
才能更改這些文件.你可以使用方便的ee命令,但是長遠考慮,vi值得學
習./src/contrib/nvi/docs/tutorial目錄下有一個出色的教程,如果你安裝了的話;否則你可以從
ftp.cdrom.com的 FreeBSD/FreeBSD-current/src/contrib/nvi/docs/tutorial目錄下ftp過來.
? ? ? 在編輯文件之前,你應(yīng)該先做個備份.假設(shè)你要編輯文件/etc/rc.conf.你只要用cd/etc到達/etc目
錄然后打命令:?
? ? ? # cp rc.conf rc.conf.orig?
? ? ? 這樣就把rc.conf拷貝為rc.conf.orig,稍后你可以把rc.conf.orig拷貝回rc.conf來覆蓋源文件.
但最好是先移動(重命名)然后拷貝回去:?
? ? ? # mv rc.conf rc.conf.orig?
? ? ? # cp rc.conf.orig rc.conf?
? ? ? 因為mv命令保留了文件的原先日期和擁有者.你現(xiàn)在可以編輯rc.conf了.如果你要源備份,你只要
mv rc.conf rc.conf.myedit?
? ? ? (假設(shè)你要保留你的編輯版本)然后用?
? ? ? # mv rc.conf.orig rc.conf?
? ? ? 來恢復(fù)成以前的樣子.?
? ? ? 要編輯文件,打命令?
? ? ? # vi filename?
? ? ? 用方向鍵在文本中來回移動.Esc(escape鍵)使vi進入命令模式.這兒有些命令:?
? ? ? x 刪除光標所在處的字符?
? ? ? dd 刪除整個一行(即使在屏幕上是折行)?
? ? ? i 在光標所在處插入文本?
? ? ? a 在光標所在處之后插入文本?
? ? ? 一旦你打了i或a,你就可以鍵入文本了.Esc使你進入命令模式,然后你可以打:?
? ? ? :w 存盤然后繼續(xù)編輯?
? ? ? :wq 存盤并退出?
? ? ? :q! 放棄存盤并退出?
? ? ? /text 移動光標到text處;/Enter (回車鍵)用來尋找下一個text?
? ? ? G 移動到文件最末?
? ? ? nG 到文件的第n行,n代表一個數(shù)字?
? ? ? Ctrl-L 刷新屏幕?
? ? ? Ctrl-b and Ctrl-f 朝前或朝后翻一屏,就象more和view一樣
? ? ? 在你的主目錄下用vi filename創(chuàng)建一個文件來練習一下如何添加、刪除文本,保存文件,然后繼續(xù)
編輯.vi會帶來一些驚奇,因為它的確相當復(fù)雜,有時候你會不經(jīng)意的發(fā)出一條命令取得一些意想不到的效
果.(一些人竟然會喜歡vi--vi比DOS EDIT強多了--去查查:r命令.)當你遇到麻煩時,多按幾下Esc鍵
以確保你在命令模式然后從那里繼續(xù)下去,經(jīng)常用:w存盤,還有在需要的時候用:q!退出重來一次.
? ? ? 現(xiàn)在你可以cd到/etc目錄下,su成為root,用vi編輯文件/etc/group,加一個用戶到wheel組這樣這
個用戶就有享有root特權(quán)了. 在文件的第一行的末尾加一個逗號和用戶名,按Esc,然后用:wq存盤退出.立
即生效.(你沒有在逗號之后加空格,對嗎?)
6. 在DOS下打印文件引用:?
? ? ? 在這一點上,你也許沒有打印機,有個辦法可以先從手冊頁建一個文件然后再把這個文件移到軟盤,
然后在DOS下打印.假設(shè)你想仔細閱讀一下有關(guān)文件權(quán)限的文檔(非常重要).你可以打命令man chmod.命令
:?
? ? ? # man chmod | col -b > chmod.txt?
? ? ? 會刪掉格式代碼然后把手冊頁發(fā)送到chmod.txt文件,而不是顯示在屏幕上.現(xiàn)在你可以插入一張
dos格式化好的軟盤,su成為ro ot,然后輸入命令:?
? ? ? # /sbin/mount -t msdos /dev/fd0 /mnt?
? ? ? 這樣就把軟盤mount到了/etc目錄下了.?
? ? ? 現(xiàn)在(你沒必要再用root了,輸入exit回到剛才的用戶jack)可以到剛才創(chuàng)建chmod.txt的那個目錄
然后把文件拷貝到軟盤:?
? ? ? % cp chmod.txt /mnt?
? ? ? 再用ls /mnt查看一下/mnt目錄下的文件列表,應(yīng)該能顯示chmod.txt. 也許你很想將/sbin/dmesg
輸出到一個文件,可以輸入命令:?
? ? ? % /sbin/dmesg > dmesg.txt?
? ? ? 然后拷貝dmesg.txt到軟盤./sbin/dmesg是系統(tǒng)的啟動日志,最好能了解它的內(nèi)容,因為它能告訴你
系統(tǒng)在啟動的時候都找到了什么硬件.如果你想向freebsd-questions@freebsd.org或一個USENET組--
象FreeBSD找不到我的磁帶機,我該怎么辦?--回答問題的人總是想先知道dmesg的內(nèi)容.?
? ? ? 現(xiàn)在你可以將軟驅(qū)從FreeBSD卸掉(用root)并取出軟盤:?
? ? ? # /sbin/umount /mnt?
? ? ? 然后重啟機器到DOS.把這些文件copy到一個DOS目錄,用諸如DOS EDIT,Windows Notepad或
Wordpad,或一個字處理器打開上述文件,做一些小小的改動,然后存盤,再象平常一樣在DOS或Windows下打
印出來.希望一切順利!用dos的print命令打印手冊文檔效果最好.(把文件從FreeBSD拷貝到mount好的
dos風區(qū)要冒一些風險.)
? ? ? 要從FreeBSD下打印首先要牽涉到在/etc/printcap目錄下創(chuàng)建合適的條目和在/var/spool/output
目錄下創(chuàng)建相應(yīng)的脫機目錄 .如果你的打印機在lpt0上(即dos下的LPT1),你只須到/var/spool/output目
錄然后用mkdir lpd命令(用root)建一個lpd目錄(如果該目錄原先不存在的話).接著當系統(tǒng)啟動的時候如
果打印機電源接通的話,打印機會有反應(yīng),并且lp或lpr命令應(yīng)該能夠向打印機發(fā)送一個文件.無論文件是
否打印取決于它的配置,在FreeBSD手冊里有詳細介紹.
7. 其他一些常用命令引用:?
? ? ? df 顯示磁盤空間和安裝了的文件系統(tǒng).?
? ? ? ps aux 顯示正在運行的進程.ps ax是窄格式.?
? ? ? rm filename 刪除filename.?
? ? ? rm -R dir 刪除一個目錄,包括所有子目錄--小心!?
? ? ? ls -R?
? ? ? 顯示當前目錄和所有其子目錄的文件;我用的不大一樣,用ls -AFR > where.txt,可以在我找到更
好的查找文件的方法之前得到/目錄和(分別的)/usr目錄下所有文件的列表.?
? ? ? passwd 修改一個用戶(或root)的口令?
? ? ? man hierUnix 文件系統(tǒng)上的手冊?
? ? ? 在/usr或任何別的目錄下使用find命令來查找文件:?
? ? ? % find /usr -name filename?
? ? ? 你可以用在filename里使用*通配符(應(yīng)該加在引號里). 如果你告訴find到/目錄而不是/usr目錄
下查找文件,它會到所有安裝好的文件系統(tǒng)包括CDROM和dos分區(qū)中去查找文件.
? ? ? 關(guān)于Unix命令和使用工具,一本比較好的書是Abrahams & Larson, Unix for the Impatient (2nd?
ed., Addison-Wesley, 1996).在Internet上也有很多Unix信息.看看Unix Reference Desk.
8. 下一步引用:?
? ? ? 現(xiàn)在你有了編輯工具并且知道如何遍歷系統(tǒng),因此你可以運行任何你想要的東西.在FreeBSD的站點
上和FreeBSD手冊上(很可能在你的硬盤上)都可以找到大量的相關(guān)信息.同時在Walnut Creek CDROM和它
的站點上也可以找到大量的應(yīng)用程序包.使用手冊已經(jīng)告訴你如何添加這些程序包(添加程序包的時候該
包必須存在 ,然后用pkg_add/cdrom/packages/All/packagename,packagename表示包的文件名).在下列
目錄及文件中可以找到光盤上有關(guān)每個程序包簡要說明的一張列表:
cdrom/packages/index,cdrom/packages/index.txt,和cdrom/ports/index.更詳細的說明可以
在/cdrom/ports/*/*/pkg/DESCR文件里找到,前后兩個*分別代表程序所屬的類別和程序名.
? ? ? 如果你不能理解手冊上所說的關(guān)于如何從cdrom上安裝程序包的話,下列步驟通常可以行的通:
? ? ? 找一個你要的包,比如kermit.存放在光盤上的某個目錄.用下列命令把該子目錄拷貝到/usr/local
目錄下(供所有用戶使用的軟件最好都放在這):?
? ? ? # cp -R /cdrom/ports/comm/kermit /usr/local?
? ? ? 這樣/usr/local/kermit子目錄就包含了是光盤上kermit子目錄下的所有文件.下一步,如
果/usr/ports/distfiles不存在的話就用mkdir把這個目錄建起來.現(xiàn)在到/cdrom/ports/distfiles文件
里查找一下你所要的程序包的名字.然后包相關(guān)的安裝文件拷貝到/usr/ports/distfiles目錄下;在最近
的新版本中你可以跳過這一步,FreeBSD會自動完成這一步.對kermit來說,沒有d istfile.然后cd到包含
Makefile的/usr/local/kermit子目錄下,打命令:?
? ? ? # make all install?
? ? ? 在這一過程中,如果系統(tǒng)在/usr/ports/distfiles目錄中找不到相關(guān)的壓縮文件的話,它就會ftp去
下載該文件.如果你沒有聯(lián)網(wǎng)并且該文件不在上述目錄下的話,你得用另外一臺機器來獲得該文件,然后再
把它從軟盤或dos分區(qū)拷貝到/usr/ports/distf iles下.閱讀一下Makefile(用cat或more命令)看看應(yīng)該
到哪里(master distribution site)下載、文件名是什么.下載到了dos下后文件名會縮短,你把它放
到/usr/ports/distfiles下后得把文件名改為原來的(用 mv命令),這樣在安裝的時候,系統(tǒng)就能找到這個
文件了.(用二進制模式下載!)然后回到/usr/local/kermit目錄,到有Makefil e的目錄,打make all?
install.
? ? ? 安裝程序包的時候可能碰到的另外一件事就是需要事先安裝一些別的應(yīng)用程序.如果安裝過程停下
來說找不到unzip或別的什么的話,你就必須先安裝unzip的程序包然后才能繼續(xù).
? ? ? 一旦安裝完畢,打rehash命令讓FreeBSD重新讀一下該路徑下的文件,這樣它就知道目錄下都有些什
么.(如果當你用whereis或w hich命令時出現(xiàn)很多路徑找不到的信息的話,你得在你的主目錄下的.cshrc
文件中path描述后添加一部分.出于安全考慮,Unix中的path除了當前目錄不在path中(默認),別的和DOS
下的path都是一樣的,要運行不在path中的當前目錄的命令,要在命令前打./才能使命令執(zhí)行,斜杠后不能
有空格.)?
< br> 也許你想從Netscape的ftp站點上得到最新版的Netscape.(Netscape必須運行在X Windows系統(tǒng)
上.)現(xiàn)在有FreeBSD版本了,仔細找找.只要運行 gunzip filename和tar xvf filename,把執(zhí)行文件移
到/usr/local/bin或其它一些存放執(zhí)行文件的地方,rehash,然后把下列行加到每個用戶主目錄下的.c?
shrc文件中或者(更簡單)干脆到系統(tǒng)啟動配置文件/etc/csh.cshrc中:?
? ? ? setenv XKEYSYMDB /usr/X11R6/lib/X11/XKeysymDB?
? ? ? setenv XNLSPATH /usr/X11R6/lib/X11/nls?
? ? ? 前提是假設(shè)文件XkeysymDB和目錄nls在目錄/usr/X11R6/lib/X11下;如果不在的話,查找一下然后
放到上述目錄下.
? ? ? 如果你以前就已經(jīng)用CDROM(或ftp)安裝了Netscape,不要把用新的Netscape執(zhí)行文件覆
蓋/usr/local/bin/netscape,老的文件只是一個設(shè)置環(huán)境變量的shell腳本.相反,把新的執(zhí)行文件更名為
netscape.bin,然后覆蓋老的執(zhí)行文件/usr/local/lib/nets cape/netscape.bin.
9. 你的工作環(huán)境引用:?
? ? ? 你的shell是你的工作環(huán)境中最重要的部分.在DOS下,shell通常為command.com.對你所打入的命令
進行解釋的程序就是shell, 這樣來與操作系統(tǒng)通信.你也可以寫你自己的shell腳本,就象DOS批處理文件
:一組在運行時不需要你的干涉的命令.
? ? ? FreeBSD裝好后有2個shell:csh和sh.Csh比較適合命令行處理,而腳本應(yīng)該用sh(或bash)來寫.可
以打命令echo $SHELL來查看你用的是什么shell.
? ? ? Csh shell是不錯的,但是tcsh能做的要比csh能做的要多.它允許你用方向鍵調(diào)用歷史命令而且還
能對歷史命令進行編輯.tcsh還允許你用tab鍵補齊文件名(csh用esc鍵),用 cd -命令可以切換到上一次
你所在的目錄.除此而外,用tcsh切換你的提示符也極其方便.Tcsh是你感到更輕松.
? ? ? 安裝一個新的shell分以下3步:
? ? ? I. 把shell作為一個程序包安裝,就象安裝別的程序包一樣.用rehash和which tcsh(假設(shè)你正在安
裝tcsh)來確保安裝正確.?
? ? ? II. 成為root,編輯/etc/shells,為新的shell添加一行,就本例而言,應(yīng)該
為/usr/local/bin/tcsh, 存盤.(有的程序包也許會自動完成.)?
? ? ? III. 用chsh命令把你的shell永久的改為tcsh,或者在提示符下打tcsh更改你的shell,不用重新登
錄.?
注意:對于FreeBSD較早的版本和大部分的Unix,把root的shell改為除sh或csh之外別的什么shell可能回
帶來危險;因為當系統(tǒng)進入單用戶模式后,你的shell可能運行不起來.解決辦法是用su -m成為root,這樣
tcsh就成為你作為root時候的shell了,因為shell是環(huán)境的一部分.把下面的別名加到你的.tcshrc文件中
后上述情況就一直如此了:?
? ? ? alias su su -m.?
? ? ? 當tcsh啟動時,它會和csh一樣樣去讀取/etc/csh.cshrc和/etc/csh.login.還會讀取你主目錄中的
.login和.cshrc文件,除非你的目錄中有.tcshrc文件.你可以干脆把.cshrc拷貝到.tcshrc.
? ? ? 這樣你就把tcsh安裝好了,可以修改提示符了.你可以查看手冊中有關(guān)tcsh的細節(jié).把下面這行放到
你的.tcshrc中后,你就可以知道你打了多少命令、現(xiàn)在幾點鐘和當前所在目錄.如果你是普通用戶,還有
一個>;如果你是root,就是#.Tcsh在任何情況下都能做到:?
? ? ? set prompt = %h %t %~ %#?
? ? ? 如果原來有這句話應(yīng)該放在原來設(shè)置提示符的地方;如果找不到的話,就應(yīng)該在if($?prompt)?
then后面.注釋掉原來的那一行;這樣你就總是可以在喜歡的時候切換到老的提示符.別忘記空格和引號.
打source .tcshrc來讓系統(tǒng)重新讀一下.tcshrc文件.你可以用env命令列出已經(jīng)設(shè)置好的別的環(huán)境變量.
它會顯示你默認的編輯器、翻屏、終端類型和其它一些變量.如果你遠程登錄后不能運行程序,這是因為
終端沒配置好,可以運行命令setenv TERM vt100.
10. 其它引用:?
? ? ? 作為root,用 /sbin/umount /cdrom卸裝CDROM,從光驅(qū)中取出CDROM,放入另外一張,然后假設(shè)cd0a
是你光驅(qū)的設(shè)備名,用 /sbin/mount_cd9660 /dev/cd0a /cdrom安裝光驅(qū)點.在最近的版本中,要安裝光驅(qū)
點的話,只要打/sbin/mount /cdrom.
? ? ? 如果你的空間不夠,可以使用可啟動文件系統(tǒng)-第二張FreeBSD CDROM.可啟動文件系統(tǒng)CDROM上的內(nèi)
容應(yīng)版本的不同而有所變化.使用可啟動文件系統(tǒng)將牽涉到使用lndir,lndir隨X Window系統(tǒng)一起安
裝,lndir告訴程序到哪里找所需要的文件,因為這些文件在/cdrom目錄下而不是通常情況下的/usr目錄.
閱讀一下man lndir.
11. 歡迎提建議引用:?
? ? ? 如果你使用這篇教程的話,我想知道哪里說的不清楚、還有哪些你認為應(yīng)該包括進去的卻被遺漏的
、還有本教程是否對你有幫助.感謝Eugene W. Stark,計算機科學系的教授,和John Fieber和他具有幫助
的注釋.
Annelise Anderson, andrsn@andrsn.stanford.edu?
freebsd-questions@freebsd.org?
-----------------------------?
(C)1999 by China FreeBSD User Group. All rights reserved.?
URL:www.cn.freebsd.org?
E-Mail:webmaster@cn.freebsd.org?
$Date: 1999/12/28 05:40:56 $?
========
FreeBSD核心入門
http://blog.chinaunix.net/uid-210143-id-2408936.html?
翻譯 :Liangvy?
原著 :FreeBSD核心入門(日文版) 大木敦雄
1.1概述?
FreeBSD可以在PC/AT兼容機器上運行。CPU是i386,i486,Pentium,?
Pentium Pro以及其兼容芯片等。?
1.1.1(略)?
1,理論地址: 2個13 bit 長+32 bit 長?
2,線形地址:32 bit 長的空間?
3,物理地址:32 bit 長的空間?
1.1.2進程的虛擬空間?
1,text部分?
這部分是執(zhí)行文件的的text領(lǐng)域,也就是機器語言部分,對于這個?
部分的空間在機器上的物理內(nèi)存頁是共有的,還有,這部分最后的變量?
地址是etext。?
2,data和bss部分?
執(zhí)行文件的data部分,也就是初始化的數(shù)據(jù)段和執(zhí)行文件指定的內(nèi)?
存變量。內(nèi)存變量在開始的時候以0填充。這一段空間可以讀寫。它的?
邊界也是以edata和end的地址做結(jié)尾。進程的malloc()等內(nèi)存分配的?
操作的時候,地址的增加方向向bss空間進行。?
3,stack部分?
也就是進程執(zhí)行的時候的stack空間,這部分空間(從地址的最高位?
開始可以伸縮),其對于物理內(nèi)存,伸縮程度由核心自動執(zhí)行。?
1.2 kernel的configure?
freebsd的kernel構(gòu)成文件在/usr/src/sys的目錄下面。下面的子目錄做一個?
介紹。?
compile 編譯核心的目錄。?
conf configure的目錄。?
ddb 核心調(diào)試的sounre code的目錄。?
dev 一部分的drivers的source code的目錄。?
gnu 浮點運算的仿真以及ex2fs文件系統(tǒng)的source code目錄。?
i386 依賴于pc/at機器的目錄,以下介紹它的字目錄。?
apm suspend一些節(jié)電程序。?
boot 不是kernel本身的東西,只是一些怎么從開機到讀入kernel?
的boot program的source code。?
conf config的一些依賴data。?
isa isa bus的驅(qū)動程序類的source code。?
eisa eisa bus的驅(qū)動程序類的source code。?
include 對pc/at的一些include files?
i386 對pc/at的一些核心code?
ibcs2,linux 使各類的os的執(zhí)行文件在freebsd上執(zhí)行的code?
isofs/cd9660?
cd-rom在unix文件系統(tǒng)上操作的的有關(guān)code?
kern 核心code?
libkern 核心庫的source code?
miscfs 實現(xiàn)unix文件系統(tǒng)的code?
msdosfs 在unix上操作ms-dos文件系統(tǒng)的有關(guān)code?
net 實現(xiàn)network功能的基本部分code?
netatalk?
實現(xiàn)appletalk network功能code?
netinet 實現(xiàn)internet network功能的code?
netipx 實現(xiàn)ipx功能的code?
netns 實現(xiàn)ns network的code?
netkey 實現(xiàn)網(wǎng)絡(luò)加密部分的功能的code?
nfs 實現(xiàn)nfs服務(wù)?
pc98 對于pc98的支持?
pccard 對pcmcia的支持?
pci 對pci bus的驅(qū)動程序的source code?
scsi 對cd-rom,hard disk,tape 等的scsi驅(qū)動程序的source code?
sys 獨立于機器體系結(jié)構(gòu)的一部分code?
ufs unix file system 的支持code?
vm 虛擬內(nèi)存管理的部分?
1.2.1配置的操作----config command?
在root權(quán)限下,config,make實行后,可以得到簡單的kernel。?
*configure file?
移動到/usr/src/sys/i386/config看看。?
GENERIC 從cd-rom等安裝freebsd的時候?qū)?yīng)于defaule kernel?
的配置file?
LINT kernel組合功能的網(wǎng)羅的的配置file?
下面4個是對配置很有必要的的依賴data file?
Makefile.386 config生成的Makefile file的template.?
devices.i386 對于unix filesystem可能的block型的device?
名字和major號的對照表?
files.i386 記錄kernel功能組合的基礎(chǔ)上,依賴于pc/at?
機器的功能名稱和各種功能實現(xiàn)的source code?
file的名字表。?
options.i386 記錄配置項目的表。?
還有,majors.i386是記錄對應(yīng)驅(qū)動器的I/O表和major號的一個文件。?
于核心配置沒關(guān)系。?
對于新的i/o設(shè)備,如果要做device driver,對pc/at,要在files.i386(沒?
有的話在/usr/src/sys/conf/files)追加相應(yīng)的行,不然就不能把它加入?
到核心里面。?
追加的格式為?
相對path名 optional device-name device-driver
對于配置文件,首先,要設(shè)置cpu,bus,i/o設(shè)備,多少用戶等。例如對于GENERIC?
machine "i386"?
cpu "I386_CPU"?
cpu "I486_CPU"?
cpu "I586_CPU"?
cpu "I686_COU"?
ident GENERIC?
maxusers 10?
當作為server時候,應(yīng)該把最大user設(shè)置大一點,以提高系統(tǒng)性能。?
下一步,指定options,對于GENERIC?
options MATH_EMULATE #support for x87 emulation?
options INET #interNETworing?
options FFS #Berkeley Fast Filesystem?
options NFS #Network Filesystem?
......?
options指定的名字xxx等,如果在/usr/src/sys/conf/options或者在?
/usr/src/sys/i386/conf/options.i386中記載的時候,應(yīng)在對應(yīng)的opt_XXX.h中寫入?
。沒有的話,作為cc命令行的參數(shù)定義"-D"在Makefile里面追加。對于XXX的格式應(yīng)該?
是?
相對path名 optional xxx?
下一步,對于config?
config kernel root on wd0?
(略)?
配置文件剩下的部分應(yīng)該是bus,i/o等一些硬件配置,一般有controller,device,?
disk,tape四類。例如?
controller isa0?
controller eisa0?
controller pci0?
等。?
第二層的device和controller,記錄了一些bus設(shè)備的連接。ISA的情況是?
device device_name at isa? 參數(shù)?
controller controller_name at isa? 參數(shù)?
EISA和PCI就相對簡單一點:?
device device_name?
controller controller_name?
device_name里指定的設(shè)備名是,串口,并口,網(wǎng)絡(luò)等裝置。?
第三層的disk和tape為?
disk disk_name at 控制設(shè)備名 drive 號?
tape tape_name at 控制設(shè)備名 drive 號?
SCSI接口卡作為第二層的控制裝置記錄的同時?
controller scbus0?
作為通用的scsi控制設(shè)備。因此,對于它的hard disk,tape,cd-rom,mo設(shè)備,有?
device sd0?
device st0?
device cd0?
device od0?
等,它可以自動識別和分配號碼。?
對于其他的scsi設(shè)備,有?
device pt0 at scbus??
這些東西(bus,scsi,i/o),在生成的ioconf.c以及相應(yīng)的include中有反映。?
configure的最后,不是一些物理設(shè)備,而是kernel內(nèi)部的一些軟設(shè)置?
pseudo-device 理論設(shè)備名?
首先,要考慮以下兩個設(shè)備:?
pseudo-device pty 16 #ttys - can go as high as 256?
pseudo-device log #syslog interface (/dev/klog)?
network使用的場合,應(yīng)該有下面兩個?
pseudo-device loop?
pseudo-device ether?
這種情況下,最好有?
pseudo-device bpfilter 4 #berkeley packet filter?
pseudo-device tun 1 #Tunnel driver ( PPP)?
想做floppy的時候,要?
pseudo-device vn #Vnode driver ( turns a file into a device)?
(代續(xù))
?
FreeBSD核心探討(翻譯)2
1.3 FreeBSD boot之前的工作?
1.3.1pc/at機器的boot順序?
hard disk的最前面的一個block(512byte),叫做master boot recorder(MBR).這?
里有啟動限定的program和分區(qū)的信息。分區(qū)信息是指對于一個區(qū)是16byte長,最多?
只能有4個區(qū)。16byte的內(nèi)容是,分區(qū)哪里開始,哪里結(jié)束。哪種os,能否啟動等。對?
于freebsd,安裝的時候向MBR寫入了boot easy.?
磁盤的結(jié)構(gòu)如下圖表示:?
block Number?
#0 #1 #2 ... #14 #15 #16 #17?
-------------------------------------------------------------?
disk no used?
label?
-------------------------------------------------------------?
<-boot->|<---------boot2-------------->| |<--unix file system--
FreeBSD用的block#0--#14的15個block里面,含有讀入freebsd的程序,bootease?
只在block#0里面,在15個block中并沒有。它的作用?
。讀入mbr,找freebsd的分區(qū)?
。讀入最初的15個block,到物理內(nèi)存中0x0001000?
。跳轉(zhuǎn)到相當于block#2的內(nèi)存位置?
然后,屏幕表示為:?
。。。?
。。。?
boot:?
(參數(shù)說明略)?
它的source是/usr/src/sys/i386/boot/biosboot,make之后,生成兩個文件:?
boot1,boot2分別寫入block#1,block#2--#14中。?
一般,一個物理的unix分區(qū)理論上可以有8個,比如swap,unix system等。?
boot2部分是boot program,它讀入kernel的文件名和option。然后?
。找boot label指定的分區(qū)。?
。構(gòu)造unix filesystem,找指定的kernel?
。從開始執(zhí)行文件,text,data的順序向物理內(nèi)存讀入。對bss清零。?
。以option的選擇,向開始位置跳轉(zhuǎn)。?
1.3.2 kernel的初始化動作?
boot program執(zhí)行之后,轉(zhuǎn)向kernel的text段開始進行初始化,即先執(zhí)行?
locore.s的text段。因此是虛擬內(nèi)存還沒有發(fā)生作用,locore.s的開始部分必?
須對offset進行補正。locore.s的作用是?
。保存從boot program過來的option?
。設(shè)定虛擬的stacker?
。檢測cpu的module?
。對自己的bss空間進行0初始化?
。為使虛擬內(nèi)存工作,要保證最少的管理信息。然后是虛擬空間動作。?
也就是,調(diào)用cpu有強的依賴關(guān)系的過程init386()(@i386/i386/machdep.c),?
然后進行kernel內(nèi)的管理信息初始化,i/o設(shè)備的登記,生成4個kernel process?
,再調(diào)用main()(@kern/init_main.c)。當main()返回locore.s時,應(yīng)該有如下?
5個進程:?
PID TT STAT TIME COMMAND?
0 ?? DLs 0:00.17 (swapper)?
1 ?? Is 0:00.19 /sbin/init --?
2 ?? DL 0:56.60 (pagedaemon)?
3 ?? DL 0:00.06 (vmdaemon)?
4 ?? DL 6:07.65 (updata)?
從locore.s返回到process #1,/sbin/init開始動作,然后轉(zhuǎn)向freebsd的普通?
動作。?
init386()和main()的處理大致如下:?
。init386()?
GDT和LDT,IDT,task stages處理的初始化,例外處理等locore.s沒做的?
事情,虛擬內(nèi)存初始化。然后,根據(jù)boot program的參數(shù),增加物理內(nèi)?
存page數(shù)。然后,作成process #0的雛形。?
。main()?
逐步調(diào)用構(gòu)成kernel模塊的的初始化部分。
FreeBSD核心探討(翻譯)3
(續(xù)上,liangvy.icewolf.leon翻譯)
但是,kernel構(gòu)成的各個模塊的初始化子程序一個個的列舉出來運行很顯然是?
不行的。通常是利用時間連表的技能來運行它(ld command)。也就是,程序?
是以很多個source分開編譯和聯(lián)結(jié)。相同的模塊名字就對應(yīng)于相同的地址來進?
行調(diào)用。它在時間鏈表里面自動調(diào)節(jié)執(zhí)行。?
初始化時候,main()函數(shù)要call的模塊利用在sys/kernel.h里面定義的宏?
SYSINIT()和SYSINIT_KT()進行登記。這樣,kernel在link的時候,ld命令就?
能夠得到那些信息和進行配置列表。這個列表就是kernel的組成模塊的初始化?
routine的登記。檢查source,?
就可以找到初始化routine的部分。?
如表:?
print_caddr_t(copyright) kern/init_main.c?
vm_men_init(NULL) vm/vm_init.c?
syctl_order(&sysctl_) kern/kern_sysctl.c?
kmemnit(NULL) kern/kern_malloc.c?
fpu_init(NULL) i386/i386/math_emulate.c?
cpu_startup(NULL) i386/i386/machdep.c?
gnufpu_init(NULL) miscfs/devfs/devfs_tree.c?
...?
各個device的major號與處理routine的登記 (major循序號)?
...?
configure(NULL) i386/i386/autoconf.c?
proc0_init(NULL) kern/init_main.c?
rqinit(NULL) kern/kern_synch.c?
vm_init_limits(&proc0) vm/vm_glue.c?
vfsinit(NULL) kern/vfs_init.c?
elf_insert_brand_entry(&linux_brand) i386/linux/linux_sysvec.c?
initclocks(NULL) kern/kern_clock.c?
mbinit(NULL) kern/uipc_mbuf.c?
clst_init(NULL) kern/tty_subr.c?
shmnit(NULL) kern/sysv_shm.c?
seminit(NULL) kern/sysv_sem.c?
msginit(NULL) kern/sysc_msg.c?
kludge_splimp(&x_save_spl) kern/uipc_domain.c?
ifinit(NULL) net/if.c?
domaininit(NULL) kern/uipc_domain.c?
kludge_splx(&x_save_spl) kern/uipc_domain.c?
kmstartup(NULL) kern/subr_prof.c?
sched_setup(NULL) kern/init_main.c?
xxx_vfs_mountroot(NULL) kern/init_main.c?
xxx_vfs_root_fdtab(NULL) kern/init_main.c?
swapinit(NULL) kern/init_main.c?
proc0_post(NULL) kern/init_main.c?
kthread_init(NULL) kern/init_main.c||?
kproc_start(&page_kp) vm/vm_pageout.c||?
kproc_start(&vm_kp) vm/vm_pageout.c||?
kproc_start(&up_kp) kern/vfs_bio.c||?
scheduler(NULL) vm/vm_glue.c?
(||表示有多個程序)?
proc-post()被呼叫后,main()就是在對應(yīng)process 0 的kernel的虛擬?
內(nèi)存里動作。kthread_init(),kproc_start(&page_kp),kproc_start(&vm_kp)?
,kproc_start(&up_kp)等這幾個進程,在fork()后相繼被調(diào)用。它就是相?
應(yīng)的進程1,2,3,4等。?
除process 1 以外,其他的進程調(diào)用并不返回調(diào)用的地址。(也就是,main()?
的跟隨執(zhí)行后,并不返回locore.s)。對于process #1的kernel的虛擬內(nèi)存,?
在kthread_init()返回后,main()的跟隨就完了,回到locore.s后,process #1?
的進程空間的配置文件/sbin/init就被執(zhí)行。?
main()在process #0對應(yīng)的kernel虛擬內(nèi)存運行后,進入時間鏈表scheduler()。?
這個并不返回。那現(xiàn)在就有五個進程了。?
然后,fork() 的調(diào)用在下面說明。?
1,分配process ID,保證struct proc()用的空間。?
2,復(fù)制父親的process的虛擬內(nèi)存空間,作成物理內(nèi)存的變換表。對?
應(yīng)兩個進程,采用相對應(yīng)的物理內(nèi)存表。?
3,給回父親的struct proc和struct user,然后對子進程的struct和?
struct user進行初始化。?
4,kernel的stacker也進行復(fù)制。?
5,返回父進程后,標記生成的子進程。完成處理。?
但是,process #0 -- 4 這五個進程的虛擬內(nèi)存里面什么都沒有。這些是核心?
進程的特殊部分。進程0,2,3是調(diào)節(jié)系統(tǒng)存在的進程的執(zhí)行優(yōu)先級,監(jiān)視物理?
內(nèi)存的不足,如果不夠就使用swap區(qū)進行交換。進程4的作用就是定期調(diào)查核心?
的unix文件系統(tǒng)的管理信息與驅(qū)動程序的管理信息的一致性,使它的信息一直?
是最新的。
1.3.3 /sbin/init?
從kernel里面看,/sbin/init就是單一的進程空間里動作,與一般的?
user program一樣,提供user使用的unix文件系統(tǒng)的環(huán)境的服務(wù)。?
核心啟動后最初的動作就是/sbin/init。作用如下:?
。確保file system的一致性,進行mount。?
。之后,network的設(shè)定和各種daemon的啟動。?
。監(jiān)視終端的login的配置和動作狀態(tài)。這個動作完了后(logout),?
修改和配置 login。?
也就是說,如果沒有它,用戶就不能使用unix文件系統(tǒng)。還有就是,如果boot?
progam參數(shù)指定-s的話,它就過渡到單一的用戶模式。相對來說,普通的用戶?
模式也就是multi模式。為了使普通用戶能夠使用系統(tǒng),/sbin/init的參考文件?
主要在/etc目錄里放著。主要就是運行/etc/rc文件對系統(tǒng)進行初始化。?
/etc/rc文件的主要內(nèi)容和作用如下:?
。使系統(tǒng)能夠使用swap區(qū)?
。檢查/etc/fstab,檢查它的連貫性,如果有問題就轉(zhuǎn)到單一的用戶模式?
。mount nfs以外的文件系統(tǒng)?
。讀入network 的設(shè)定和各種daemon進程的設(shè)定情況的記錄文件?
/etc/c.conf,這個內(nèi)容作為shell script的變量設(shè)定,以下的就是?
各個shell的動作調(diào)整?
。serial的初始化(/etc/rc.serial)?
。運行PCMCIA卡的插拔監(jiān)控守護進程(/etc/rc.pccard)?
。network的部分初始化(/etc/rc.network)?
。如果有nfs的時候就進行mount操作?
。network的最終初始化(/etc/rc.network:啟動和entwork有關(guān)的daemon)?
。共有庫的有關(guān)信息的初始化?
。intd,lpd,sendmail的啟動?
。依賴系統(tǒng)的一些初始化進程?
/etc/rc的處理完了后,/sbin/init就對/etc/ttys等記述的一些終端的用戶login進行?
監(jiān)視。對于這個,/etc/ttys里指定的終端,fork()后的進程里:?
。exec()指定的程序(普通的情況是/usr/libexec/getty)?
。/usr/libexec/getty進行終端速度等的設(shè)定。提示login:,等待用戶輸入?
。用戶輸入后,名字作為參數(shù)exec() /etc/bin/login?
。/usr/bin/login就提示出passwd:,等待用戶的輸入?
。準備user名和passwd,對輸入的用戶名進行確定,正確的話就exec()用戶?
shell
下圖就是/sbin/init的監(jiān)視進程圖:
process #1?
-------------------------------------------------------->?
/sbin/init | ^ \?
| fork() | | fork()?
+ exec() exec() exec() | | exec()?
process #n |---------->+--------->+------------------*+--------?
getty login user的login shell process #m
(第一章完,下一章介紹文件系統(tǒng)和驅(qū)動程序,liangvy)
?
FreeBSD核心探討.4.驅(qū)動程序篇
翻譯:liangvy liangvy@bigfoot.com icewolf.leon?
版權(quán)所有,可以轉(zhuǎn)貼
第二章 文件系統(tǒng)和設(shè)備驅(qū)動程序
這章主要介紹文件系統(tǒng)和特殊的設(shè)備文件以及它們的對應(yīng)關(guān)系。
2..1 disk上的 unix file system 的基本知識?
首先介紹一下經(jīng)典的unix file system的思維方法。?
disk 的 partition就是從0到512byte的連續(xù)長度的block的東西。這里有?
1.file/directory有關(guān)的固定長度的信息,i-node?
2.file/directory的本體,data block?
的兩樣不同的東西。partition的前面的附近塊(block#16 ,1--15用于boot?
program )就是i-node,data block用的領(lǐng)域等等的開始位置(block號)?
和長度(block數(shù)量)等的記錄,叫做super-block。一個block可能的容量只?
能有固定數(shù)目的i-node,所以如果分配了固定的i-node,收錄了節(jié)點號和節(jié)?
點的塊號和塊的位置就可以計算出來。?
i-node就是?
。表明i-node的種類(file ,direstory,device等)?
。這個節(jié)點參考的次數(shù)(目錄數(shù))?
。參考,作成,變化的時間?
。權(quán)限?
。所有者的user id / group id?
。本體的長度?
。收集本體的data block的block號碼的固定長度的對應(yīng)表?
的一些記錄。因為data block的對應(yīng)表是固定的關(guān)系,比?
如10個,最長就能夠作出512*10=5k為止的file。
當文件比塊大的時候,unix就采用成組聯(lián)結(jié)的方式對它們進行管理。就是?
把所有的空閑塊以一定數(shù)目為一組的方法作成單向空閑塊stacker。?
特別地,文件的從先頭的byte位置開始和i-node內(nèi)的對應(yīng)表有著密切的關(guān)系。?
而且,對于i-node的輸入輸出,可以對應(yīng)指定位置的數(shù)據(jù)塊進行讀寫。重要?
的是,核心可以依照這個管理表對io裝置進行管理。?
unix對io設(shè)備的操作也是作為(特殊)文件進行的。對于用i-node進行?
描述的io設(shè)備,data block數(shù)據(jù)塊的對應(yīng)表就沒必要了。這個部分的io設(shè)備?
的識別就通過device號碼來進行。向這些對i-node進行輸入輸出處理的,?
就又設(shè)備驅(qū)動號區(qū)別,來進行device driver驅(qū)動。?
那么,節(jié)點怎么的進行查找呢?partition的最初的目錄(根目錄)就是,?
從第二個i-node開始,一個一個順著節(jié)點進行查找。?
比如,對于目錄/uuu/vvv/.../yyy/zzz的查找方式,有這種關(guān)系:?
。i-node #2 所存放的是root directory。讀入它的本體,就可以找到?
相應(yīng)的uuu所對應(yīng)的i-node。?
。讀入這個i-node所存放的directory的i-node本體,找到相應(yīng)的vvv節(jié)點。?
......?
查找對應(yīng)yyy的節(jié)點?
。讀入這個節(jié)點的本體信息,這里包含目錄本題的內(nèi)容,這樣就可以找到?
zzz所對應(yīng)的i-node。?
目錄里面由于記錄了對應(yīng)文件名的節(jié)點號,所以,也有可能同一個節(jié)點號?
根據(jù)文件名不一樣,就可以找到不同的目錄名。這就是硬連接(hard link).?
但是,節(jié)點號有只存在于節(jié)點所在的分區(qū)的含義,所以,不同的分區(qū),?
這種硬連接就不具有存在的可能性。為了解決這個矛盾,就有了符號連接?
(symble link)的說法。當節(jié)點是輸入符號連接的時候,符號連接就包含?
了這個節(jié)點的data block所指定的路徑名。但是,空連接和loop連接這種?
情況也是允許的,所以核心要指定循環(huán)連接的最大次數(shù)。具體由參數(shù)?
MAXSYMLINKS(@sys/param.h)指定。?
這樣,多個分區(qū)建立一個文件系統(tǒng)就有可能了。啟動核心的分區(qū)作為一個?
已存的文件系統(tǒng),其他的分區(qū)就嫁接到目錄層上面。這個操作過程就是mount。?
利用mount指令,就可以實現(xiàn)上面的操作。但是,mount之前的目錄,在mount后?
就給屏蔽了,直到mount結(jié)束,那些目錄就可以再現(xiàn)。?
以上就是經(jīng)典的unix文件系統(tǒng)理論。但是,對于讀入了i-node,就去讀?
data block ,這種情況,對于一個比較大的分區(qū),硬盤磁頭向disk head的距?
離就太大了。總的來說,訪問時間就會變長。在這里有一些指導(dǎo)思想:?
。分區(qū)要比較小,多分小區(qū)?
。了解超級塊的地位,超級塊記錄了分區(qū)的信息,考慮由于介質(zhì)的原因而?
使這個超級塊造成損害,所以,在分區(qū)內(nèi)部就必須為它準備多幾個拷貝。?
。目錄和它下層的文件,要在相同的領(lǐng)域內(nèi)放置。?
。確保單位data block要比磁盤的block大。?
考慮了一些東西后,經(jīng)過改良標準,freebsd就采用一個叫做FFS的文件系?
統(tǒng)(Fast File System),但這只是i-node領(lǐng)域/data領(lǐng)域的配置方法的變化,基?
本的考慮方法并沒有變。對磁盤分區(qū)進行文件系統(tǒng)的構(gòu)造的初始化由命令newfs?
提供。看看它的source就知道怎么配置的了。其他的構(gòu)造(......)對應(yīng)于kernel?
的source,對于構(gòu)成boot program的文件disk.c和sys.c(@i386/boot/biosboot)?
比較簡單易懂(單純性)。?
上面講述的i-node對disk的partition的記錄形式,詳細的(source)在?
struct dinode(@ufs/ufs/dinode.h)里面有。在核心內(nèi)部使用的,包含這個東西?
的是struct inode(@ufs/ufs.inode.h)。
描述io設(shè)備的文件叫特殊文件(special file),他對應(yīng)的i-node有兩個種?
類:?
。塊型(block)?
和裝置的固有的數(shù)據(jù)記錄的單位(大多數(shù)的情況是512byte)無關(guān)。讀寫?
的最小單位是1byte,可以在任意的場所里任意長度的data。核心對各個?
block型的特殊文件進行固定的記錄單位長度(倍數(shù))進行緩沖(buffer)?
管理,這樣就可以處理任意長度的讀寫了.?
。文字型(char)?
讀寫的基本單位是,受到裝置固有的date記錄單位長的限定。沒有block?
型的緩沖管理,對應(yīng)于裝置的物理特性,讀寫屬于專用。或者說,是讀寫?
兩用。?
除了網(wǎng)絡(luò)接口之外,io裝置可以全部分為文字型和塊型兩個大類。總的來說,?
磁盤操作的兩樣都用,但其他的io裝置只有文字型。還有就是一些沒對應(yīng)物理設(shè)?
備的kernel modules提供的虛擬設(shè)備也有,它們對應(yīng)著文字型的特殊文件。特殊?
文件習慣放在目錄/dev里面。
對于特殊設(shè)備文件的i-node有block和chat兩個類,設(shè)備通過驅(qū)動號進行記錄?
。通過這些,就可以識別device driver。device 號就是major號(8bit)(主設(shè)備?
號)和minor號(24bit)(輔助設(shè)備號),device driver的識別就是由major的不?
一樣而區(qū)別。而且呢,block型,char型的等等可能存在最大數(shù)目是256種類。一般的?
情況,同種類的設(shè)備不同數(shù)目的區(qū)別就是通過輔助設(shè)備號進行識別。實際上,對于?
disk的特殊文件,有disk/slide/partition表示法,而且,文字型,塊型等的特殊?
設(shè)備文件也存在。以下就是一個ide硬盤的的文字型特殊設(shè)備文件的例子:?
/dev/rwd0 1臺ide的硬盤?
/dev/rwd0s1 1臺ide的硬盤的slide #1?
/dev/rwd0s2 1臺ide的硬盤的slide #2?
/dev/rwd0s2a slide #2的partition a?
/dev/rwd0s2b slide #2的partition b?
...?
/dev/rwd0s3 1臺的ide的硬盤的slide #3
如果把rwd換成wd,對應(yīng)的就是block型的特殊設(shè)備文件了。?
對于磁盤,有如下的使用方法:?
。對于slide的文字型特殊文件?
讀寫disk label時候使用(disklabel command)?
。對于對應(yīng)的partition的文字型特殊文件?
在分區(qū)上建立unix文件系統(tǒng)時候(newfs command),文件系統(tǒng)修復(fù),?
檢查(fsck)時候使用?
。對于partition的block型的特殊文件?
作為mount命令的參數(shù)使用?
(下一節(jié)介紹虛擬文件系統(tǒng)和v-node,要休息了 )
?
FreeBSD核心探討.5.驅(qū)動程序篇
2.2 虛擬文件系統(tǒng)和v-node?
FreeBSD在disk上的除了ffs以外還可以操作各種各樣的文件系統(tǒng)。主要的如?
下:?
。cd9660?
可以對ISO9660形式的cd-rom的目錄/文件構(gòu)造的文件系統(tǒng)進行mount,?
locate等目錄層的操作?
。ms-dos?
對ms-dos文件系統(tǒng)進行目錄層次的mount,定位等操作?
。mfs?
通過使用虛擬內(nèi)存對swap區(qū)的一部分進行unix文件系統(tǒng)的構(gòu)造,定位?
作為目錄的一部分進行讀寫?
。nfs?
由nfs server提供的remote目錄級進行mount,定位的目錄層操作。?
。null?
對已經(jīng)存在的目錄層的使用別名?
。union?
對已有的目錄A(上層)在下層目錄B上進行重疊 (不大理解這的意思?
,大概是在下層目錄里面又嫁接了上層目錄的意思:譯者)。文件名的查?
找由上層優(yōu)先進行。沒有的話就轉(zhuǎn)道下層。如果對下層的文件進行寫操作?
,它的拷貝就在上層上進行。舉例說明,作業(yè)目錄在上層,但cd-rom的源?
在下層,兩個目錄重疊,那么編譯source的時候,就相當方便了。?
。procfs?
對于進程號的目錄作成mount point。通過文件名對各個目錄的進程進行?
控制。?
。kernfs?
為了對動作中的kernel有關(guān)的信息進行參考,而作成的mount point?
。fdesc?
對于各個進程,用它所打開的文件柄對應(yīng)的文件作成的mount point
實際上,在核心內(nèi)部,為了對它們進行統(tǒng)一操作,就對文件系統(tǒng)和v-node?
進行抽象化,實際的處理過程就是調(diào)用各類的文件系統(tǒng)的模塊進行處理。
2.2.1對虛擬文件系統(tǒng)的操作?
各個文件系統(tǒng)可以提供的操作的一覽如下,它在struct vfsops?
(@sys/mount.h)里面定義:?
。對文件系統(tǒng)進行mount的操作?
。本文件系統(tǒng)的開始動作的操作?
。本文件系統(tǒng)的umount操作?
。表達文件系統(tǒng)的根的v-node的查找操作?
。對一般用戶的權(quán)限控制?
。取得文件系統(tǒng)的狀態(tài)?
。內(nèi)存內(nèi)的管理信息寫入介質(zhì)中?
。從i-node到v-node的取得操作?
。v-node和nfs的文件柄的相互變換的操作?
。文件系統(tǒng)實際的模塊的初始化
對于文件系統(tǒng),各個實際的操作routine在vfsops的形式提供準備工作。各個文件系?
統(tǒng)的vfsops,在以下的表里的source進行定義:
--------------------------------------------------------------?
file system vfsops的定義 source?
--------------------------------------------------------------?
ufs ufs_vfsops ufs/ffs/ffs_vfsops.c?
cd9660 cd9660_vfsops isofs/cd9660/cd9660_vfsops.c?
msdos msdosfs_vfsops msdosfs/msdosfs_vfsops.c?
mfs mfs_vfsops ufs/mfs/mfs_vfops.c?
nfs nfs_vfsops nfs/nfs_vfsops.c?
null null_vfsops miscfs/nullfs/null_vfsops.c?
nuion union_vfsops miscfs/union/union_vfsops.c?
procfs procfs_vfsops miscfs/procfs/procfs_vfsops.c?
kernfs kernfs_vfsops miscfs/kernfs/kernfs_vfsops.c?
fdesc fdesc_vfsops miscfs/fdesc/fdesc_vfsops.c?
devfs devfs_vfsops miscfs/devfs/devfs_vfsops.c?
ext2fs ext2fs_vfsops gnu/ext2fs/ext2_vfsops.c?
lfs lfs_vfsops ufs/lfs/lfs_vfsops.c?
portal portal_vfsops miscfs/portal.portal_vfsops.c?
umap umap_vfsops miscfs/umapfs/umap_vfsops.c?
---------------------------------------------------------------?
這些就是文件系統(tǒng)的實際模塊(*_vfsops.c),文件系統(tǒng)名稱,文件系統(tǒng)號等等?
在struct vfsconf(@sys/mount.h)里面匯總,各個模塊里用宏VFS_SET()進入核?
心。?
根據(jù)main()(@kern/init_main.c),在kernel初始化的過程中,vfsinit()?
(@kern/vfs_init.c)里面有?
struct vfsconf *vfsconf[MOUNT_MAXTYPE+1];?
struct vfsops *vfssw[MOUNT_MAXTYPE+1];?
各種東西的設(shè)定,這些是,管理mount信息的struct mount(@sys/mount.h)的成員?
mnt_vfc和mnt_op要指定所對應(yīng)的文件系統(tǒng)的vfsconf,vfssw。還有宏VFS_操作名?
(struct mount *,..)里,可以各個操作的調(diào)用。
2.2.2對v-node的操作?
虛擬文件系統(tǒng)就是通過對i-node的抽象化之后的v-node的文件/目錄進行io處理。?
為了這個目的,作為對v-node的適用處理,有?
。從v-node到文件名的查找,返回v-node?
。打開/關(guān)閉v-node?
。檢查是否可能訪問v-node?
。得到-v-node的屬性?
。設(shè)定v-node的屬性?
。對v-node的輸入/輸出?
。擴展v-node的硬連接和符號連接?
。對v-node進行目錄的作成和刪除?
。。。。?
由這里開始,一共定義了41個。?
v-node由struct vnode(@sys/vnode.h)里定義,作為類別在enum vtype?
里面表示出來,一共是9種類。它包含著在各個文件系統(tǒng)上對各個的文件/目錄(包?
括特殊)文件進行統(tǒng)一識別的信息。為了實現(xiàn)這樣,v-node一連串的操作就是在各?
模塊里通過宏VNODEOP_SET()和核心通訊。這些操作名和實現(xiàn)的routine只需要必要?
的幾個對應(yīng)。在核心初始化里,vfs_opv_init()(@kern/vfs_init.c)就使從數(shù)據(jù)得?
到的號碼一一對應(yīng),收集了routine的地址的同一size的配列再進行組合。各個?
v-node就一個一個指向這些配列。對v-node的操作在vnode_if.h里定義:?
它以?
VOP_操作名(v-node,...)?
的統(tǒng)一形式記述。
下面是對v-node的操作的定義source:?
------------------------------------------------------------------------?
各個v-node操作(vnodeopv) source?
------------------------------------------------------------------------?
cd9660_fifoop_opv_desc isofs/cd9660/cd9660_vnops.c?
cd9660_specop_opv_desc isofs/cd9660/cd9660_vnops.c?
cd9660_vnodeop_opv_desc isofs/cd9660/cd9660_vnops.c?
dead_vnodop_opv_desc miscfs/deadfs/dead_devfs_vnops.c?
devfs_vnodeop_desc miscfs/devfs/devfs_vnops.c?
ext2fs_fifoop_opv_desc gnu/ext2fs/ext2fs_vnops.c?
ext2fs_specop_opv_desc gnu/ext2fs/ext2fs_vnops.c?
ext2fs_vnodeop_opv_desc gnu/ext2fs/ext2fs_vnops.c?
fdesc_vnodeop_opv_desc miscfs/fdesc/fdesc_vnops.c?
ffs_fifoop_opv_desc ufs/ffs/ffs_vnops.c?
ffs_specop_opv_desc ufs/ffs/ffs_vnops.c?
ffs_vnodeop_opv_desc ufs/ffs/ffs_vnops.c?
fifo_nfsv2nodeop_opv_desc nfs/nfs_vnops.c?
fifo_vnodeop_opv_desc miscfs/fifofs/fifo_vnops.c?
kernfs_vnodeop_opv_desc miscfs/kernfs/kernfs_vnops.c?
lfs_fifoop_opv_desc ufs/lfs/lfs_vnops.c?
lfs_specop_opv_desc ufs/lfs/lfs_vnops.c?
lfs_vnodeop_opv_desc ufs/lfs/lfs_vnops.c?
mfs_vnodeop_opv_desc ufs/mfs/mfs_vnops.c?
msdosfs_vnodeop_opv_desc msdosfs/msdosfs_vnops.c?
nfsv2_vnodeop_opv_desc nfs/nfs_vnops.c?
null_vnodeop_opv_desc miscfs/nullfs/null_vnops.c?
portal_vnodeop_opv_desc miscfs/portal/portal_vnops.c?
procfs_vnodeop_opv_desc miscfs/procfs/procfs_vnops.c?
spec_nfsv2nodeop_opv_desc nfs/nfs_vnops.c?
spec_vnodeop_opv_desc miscfs/specfs/spec_vnops.c?
umap_vnodeop_opv_desc miscfs/umapfs/umap_vnops.c?
union_vnodeop_opv_desc miscfs/union/union_vnops.c?
------------------------------------------------------------------------?
這個基礎(chǔ)上,spec_vnodeop_opv_spec里描述的操作群就是device driver?
interface的東西!!
( 本小節(jié)完,待本島主有空再繼續(xù) )
?
FreeBSD核心探討.6.驅(qū)動程序篇
2.3 mount根目錄之前的處理概要?
mount根目錄的時候,main()(@kern/init_main.c)的初始化的過程從xxx_vfs_mountroot()?
(@kern/init_mail.c)被調(diào)用開始。如果處理過程正常,就對rootvp設(shè)定包含了root的?
v-node。?
。main()的初始化過程中,configure()(@autoconf.c)被調(diào)用。在這個,io設(shè)備?
初始化完了后,就轉(zhuǎn)移到如下兩個變量的地址:一個是mountroot,是處理mount的routine,?
另一個是mountrootvfsops,是處理虛擬文件系統(tǒng)的routine。在本機磁盤中,就進入變量?
rootdev所指定的disk號中。這里就是,假定本機磁盤?
mountroot vfs_mountroot?
mountrootvfsop &ufs_vfsops?
rootdev boot disk number
。xxx_vfs_mountroot()(@kern/init_main.c)?
運行(*mountroot)(mountrootvfsops)后,就指明了root file system的mount.?
。vfs_mountroot()(@kern/vfs_conf.c)?
管理mount的了文件系統(tǒng)的信息的struct mount(@sys/mount.h),對它進行確認?
,然后設(shè)定傳遞過來的對虛擬文件系統(tǒng)的操作群(&ufs_vfsops),才進行"root"?
標記。根據(jù)VFS_MOUNT(mp,...)進行mount這個虛擬文件系統(tǒng)。mount成功后,就?
追加file system的list。這里,由于傳遞了&ufs_vfsops,就可以調(diào)用?
ffs_mount()(@ufs/ffs/ffs_vfsops.c)?
。ffs_mount()?
首先調(diào)用bdevvp()(@kern/vfs_subr.c),進行VBLK類別,spec_vnodeop_p?
(@misc/specfs/spec_vnops.c) v-node操作,保證設(shè)定了驅(qū)動號的rootdev的?
v-node的最新信息,然后設(shè)定rootvp。最后,通過ffs_mountfs()調(diào)用進行實際?
的mount rootvp操作。?
。ffs_mountfs()?
各種各樣的檢查完了后,調(diào)用VOP_OPEN(),打開rootvp的v-node。在這里,如果?
v-node的v_op成員在spec_vnodeop_p存在的話,就調(diào)用spec_open()(@misc/?
specfs/spec_vnops.c)。?
.spec_open?
由于VBLK里包含v-node的種類,從v-node指定的device號取得major的?
號,調(diào)用對應(yīng)driver的XXopen() routine
續(xù)上,由VOP_IOCTL()(還是的通過spec_ioctl()(@misc/specfs/spec_vnops.c))?
可以得到partition信息,然后該檢查super block的內(nèi)容。正確的話,就在struct?
ufsmount(@ufs/ufs/ufsmount.h)設(shè)定unix file system,這樣處理過程就完了。
2.2.4 struct buf 和block的輸入輸出routine?
前節(jié)的ffs_mountfs()提到使用bread()(@kern/vfs_bio.c)讀出partition的?
super block。這個接口函數(shù)很快就會解釋。它主要用于讀取block型的device到?
kernel內(nèi)部的buffer中。?
bread(struct vnode *vp, /*(in)輸入對象的v-node*/?
daddr_t blkno, /*(in)block號*/?
int size, /*(in)讀出的byte數(shù)量,block長的倍數(shù)*/?
struct ucred * cred,/*(in)權(quán)限信息*/?
struct buf ** bpp)/*(out)存儲讀來的data*/?
同樣的buffer link后的block輸出的子程序是bwrite()。?
bwrite(struct buf *bp) /*(out)可以輸出的struct buf*/?
兩者之間共同的地方就是struct buf(@/sys/buf.h),它用于io處理中給device driver?
做橋梁作用的數(shù)據(jù)結(jié)構(gòu)。它記錄了v-node,io的區(qū)別,可以io的block位置/byte數(shù),存?
儲實際data buffer的address,io處理的進展情況等。
bread則通過getblk()對block輸入的結(jié)構(gòu)struct buf進行操作。getblk()調(diào)用在核心?
管理buffer link和返回指定大小的block的struct buf。這個(緩沖區(qū))內(nèi)容在目的?
block是否存在與指定v-node的指定位置block是否已經(jīng)構(gòu)成緩沖環(huán)有關(guān)。struct buf?
里面有一個標志位,當緩沖環(huán)內(nèi)容變化是,這個標志位就會改變。bread()根據(jù)這個?
flag判斷block是否已經(jīng)緩沖,如果已經(jīng)完成,它就終止退出。如果不是這樣,則在?
struct buf的mark里面標志,然后調(diào)用VOP_STRATEGY()。在v-node登記的strategy?
routine記錄了io處理的過程,所以bread()當實際的處理完了后,就調(diào)用biowait()?
進入等待狀態(tài)。然后,就轉(zhuǎn)移到別的進程A。io處理完了后,調(diào)用biodone(),進程A?
也可以繼續(xù)進行。還有,調(diào)用bread()的一邊,當完成操作后,就調(diào)用brelse(),在?
里面對struct buf的flag重新設(shè)置,讓它對別的程序開放。
bwrite也是同樣的通過VOP_STRATEGY()對io處理要求進行登記,同時也調(diào)用biowait()?
進入等待狀態(tài),同樣,當實際操作完了后,也設(shè)置flag進行復(fù)位,使得其他程序可以?
使用io,當空閑的時候,io就掛起,轉(zhuǎn)向其他進程處理。?
進程等待進入的時候,當然不限于只是調(diào)用biowait()。在bread()或者bwrite()之前,?
系統(tǒng)必須分配足夠的資源供它使用,比如一些緩沖區(qū)等。當進行實際io時候,1個block?
也可以,多個block也可以,而且這樣可以獲得更高的效率,這樣看起來,就象實際上?
是連續(xù)操作了。?
(代續(xù))
?
FreeBSD核心探討.7.驅(qū)動程序篇
2.2.5系統(tǒng)調(diào)用open()的處理概要?
進程通過系統(tǒng)調(diào)用read()/write()進行io處理,它由文件描述符指定對哪里進?
行i/o,文件描述符是0以上的整數(shù),它在各個進程的struct proc的成員?
struct filedesc *p_fd(struct filedesc(@sys/filedesc.h))保留的struct file?
((@sys/file.h)進行選擇添加。對struct file,它含有從文件的頭的輸入輸出的byte?
位置,輸入操作,輸出操作,輸入輸出控制,輸入輸出的準備狀態(tài)的檢查,執(zhí)行close?
的routine,以及描述io處理對象的信息(v-node,socket,pipe) 。系統(tǒng)調(diào)用open()?
(@kern/vfs_syscalls.c)就是把包含路徑信息的v-node找尋出來,為了對它進行io處理,?
先要對struct file進行初始化,然后返回文件描述符。?
從路徑名查找v-nodehe和io準備操作由vn_open()(@kern/vfs_vnops.c)承擔。?
vn_open()通過namei()(@kern/vfs_lookup.c)查找路徑對應(yīng)的v-node名,由VOP_OPEN()?
調(diào)用不同的v-node定義的準備過程routine。例如,有如下的處理方法。?
。普通的file/directory?
調(diào)用ufs_open()(@ufs/ufs/ufs_vnops.c),檢查open的mode?
。特殊設(shè)備文件?
調(diào)用spec_open()(@miscfs/specfs/spec_vnops.c)?
文字型 調(diào)用device driver的open routine?
快型 mount的時候出錯。如果不是這樣,就調(diào)用device driver的?
open routine。
回過頭來,namei()的任務(wù)是就是,對于指定的路徑名,對應(yīng)于跟目錄或者當?
前目錄的v-node作為起點,通過lookup()(@kern/vfs_lookup.c)進行v-node查找。?
lookup()從路徑名開始的v-node(VDIR)開始查找。找到了的v-node作為新的起點繼續(xù)進行?
查找下一步的要素名,然后得到目的的v-node。這個時候,根據(jù)v-node的不同,目錄的檢?
索方法也就不同。各個要素的實際檢索由VOP_LOOKUP()來做。
2.2.6系統(tǒng)調(diào)用read()的處理概要?
open()取得文件描述符后,對它的輸入處理,有如下的流程。指定的文件描述符?
的struct file內(nèi)登記的處理routine有vn_read()(@kern/vfs_vnops.c),vn_write(),?
vn_ioctl(),vn_select(),vn_closefile(),v_node?
登記的操作routine不能分開使用。vn_*()里,只有在合適的前綴操作下,才能正確調(diào)用。?
read()首先在struct uio(@sys/uio.h)登記進程指定的buffer的位置和長度。?
執(zhí)行read()后,vn_read()向struct file設(shè)定登記的文件的讀寫位置,然后調(diào)用VOP_READ()。?
根據(jù)讀出來的byte數(shù),讀寫位置相應(yīng)增加。?
VOP_READ()的call routine則是與v-node有關(guān),就象下圖一樣。
vn_read()?
文字型/塊型 |?
/------------------?
| | file/directory?
spec_read() ---------ffs_read()-------VOP_READ()?
block型 | |?
/---------------|char型 |?
bread() device driver bread()?
| |?
spec_strategy() ---------------ufs_strategy() --VOP_STRATEGY()?
| | |?
| | |?
device driver spec_strategy() -------------/?
|?
|?
device driver
。普通的file/directory?
調(diào)用ffs_read()(@ufs/ufs/ufs_readwrite.c)。對應(yīng)指定的讀寫位置,計算block?
的位置,然后用bread()讀出來。讀出來的數(shù)據(jù)送到進程所準備的緩沖區(qū)。從bread()?
傳遞過來的block并不是物理block的位置,而是把file作為block列的一個理論值。?
從理論塊到物理塊的變換由VOP_STARATEGY()完成。也就是說,ufs_strategy()先把?
文件內(nèi)位置轉(zhuǎn)化為物理block位置,然后從v-node記錄的i-node把表示物理設(shè)備的?
v-node 去出來,這個VOP_STRATEGY就調(diào)用spec()(@miscfs/specfs/spec_vnops.c)?
讓它進行輸入要求。?
。特殊設(shè)備文件?
通過調(diào)用spec_read()(@miscfs/specfs/spec_vnops.c),把它分為文字型和塊型兩類。?
文字型 調(diào)用device driver的輸入routine?
塊型 通過bread()進行輸入處理
對文件的系統(tǒng)調(diào)用write()的場合也是類似的處理流程(ufs_write()->bwrite()),?
ufs_write()則要考慮到文件大小的延伸。
?
FreeBSD核心探討.8.驅(qū)動程序篇
2.3 Device Driver?
進程的io要求到這里說的差不多了。上面也解說了對于文字型,塊型的驅(qū)動程序接口,就?
是dev_spec_vnodeop_opv_desc里定義的子函數(shù)那些。參考設(shè)備驅(qū)動程序,在sys/conf.h?
里定義的結(jié)構(gòu)體。block型是?
struct bdevsw{?
d_open_t *d_open;?
d_close_t *d_close;?
d_strategy_t *d_strategy;?
d_ioctl_t *d_ioctl;?
d_dump_t *d_dump;?
d_psize_t *d_psize; /*得到容量*/?
int *d_flags;?
char *d_name; /*device 名*/?
struct cdesw *d_cdev; /*對應(yīng)的文字型*/?
int d_maj; /*major號*/?
}?
文字型的則是?
struct cdevsw{?
d_open_t *d_open;?
d_close_t *d_close;?
d_read_t *d_read; /* rawread() */?
d_write_t *d_write; /* rawwrite()*/?
d_ioctl_t *d_ioctl;?
d_stop_t *d_stop; /* nostop()*/?
d_reset_t *d_reset; /* nullreset()*/?
d_devtotty_t *d_devtotty; /* nodevtotty*/?
d_select_t *d_select; /* deltrue*/?
d_mmap_t *d_mmap; /* nommap*/?
d_strategy_t *d_strategy?
char *d_name; /*device名*/?
struct bdevsw *d_bdev; /*對應(yīng)block型*/?
int d_may; /*major號*/?
}
兩方面共同的部分有?
xx_open(dev_t dev,int oflags,int devtype,struct proc *p)?
xx_close(dev_t dev,int fflag,int devtype,struct proc *p)?
xx_ioctl(dev_t dev,int cmd,caddr_t data,int fflag,struct proc *p)?
xx_open()用于打開device號的設(shè)備。xx_close()則用于關(guān)閉它。xx_ioctl()則對設(shè)備的?
動作狀態(tài),機能的取得,設(shè)置等進行控制,它通過int cmd命令和參數(shù)caddr_t data對之?
進行處理。xx_open()的oflags則是系統(tǒng)調(diào)用open()里指定的標志。xx_close()和?
xx_ioctl()的fflag是每個文件描述符設(shè)定的標志。int devtype用來區(qū)別設(shè)備類型是文?
字型的還是塊型的。struct proc *p是本次要求的進程號。
在文字型的操作里,有這三個函數(shù)?
xx_read(dev_t dev,struct uio *uio,int ioflag)?
xx_write(dev_t dev,struct uio *uio,int ioflag)?
xx_select(dev_t dev,int which, struct proc *p)?
xx_read()/xx_write()是對device號的io,struct uio *uio 是io的buffer,int ioflag?
標志io動作的option。例如,輸入data沒準備好的場合不用進入等待狀態(tài)也可以。?
xx_select()檢查是否可以進行io要求。?
在塊設(shè)備的操作中,有一個函數(shù)?
xx_strategy(struct buf *bp)?
它處理io要求。struct buf *bp里面包含著device號,輸入還是輸出,io的buffer等。
device號中的major號,對文字型的struct cdevsw *cdevsw[],對塊型的struct?
bdevsw *bdevsw[],作為配列的添加字使用。向這些配列登記,就可以調(diào)出device driver?
的登記routine。?
對cdevsw[]登記的過程在kern/kern_conf.c,它使用?
int cdevsw_add(?
dev_t *descrip, /*收集device號的變量的指針*/?
struct cdevsw *newentry,/*設(shè)置struct cdevsw的指針*/?
struct cdevsw **oldentry,/*舊的設(shè)定內(nèi)容的返回領(lǐng)域*/?
)?
另一方面,對bdevsw[]的登記過程則使用?
int bdevsw_add_generic(?
int bdev, /*block型的major號*/?
int cdev, /*文字型的major浩*/?
struct bdevsw *bdevsw, /*設(shè)定struct bdevsw的指針,對應(yīng)d_cdev*/?
)?
block型的device和char型的device有著一定的對應(yīng)關(guān)系。這些結(jié)構(gòu)體相互參考。?
bdevsw_add_generic()從block的結(jié)構(gòu)體開始,對作為char型的device的結(jié)構(gòu)體進行初始化。?
還有,network interface的devive driver,并沒有向cdevsw[]和bdevsw[]登記。而且也沒有?
device號。網(wǎng)絡(luò)間的package流,和進程間與網(wǎng)絡(luò)間的package流也沒有特別指明。?
調(diào)用登記routine的時候,可以把文件系統(tǒng)的modules作為特殊設(shè)備文件參考。登記?
routine在什么地方都可以調(diào)用。?
。main()(@kern/init_mail.c)的初始化過程中登記的routine調(diào)用的時候,各個?
device driver的modules里由宏SYSINIT()準備進行。?
。確認device driver里的io設(shè)備的存在的時候,調(diào)用登記routine。?
當調(diào)用登記程序段的時候,如果major號和/dev/MAKEDEV的major號有沖突的時候,?
就調(diào)用全部無關(guān)性device file的處理routine,也可能沒有預(yù)期的的災(zāi)難事情。還有別的?
以外事情,就是當/dev里沒有對應(yīng)的特殊設(shè)備文件的時候,也就不能從進程進行參考。
?
FreeBSD核心探討.9.驅(qū)動程序篇
2.3.1驅(qū)動程序初始化?
從文件系統(tǒng)的模塊可以看出來,如果要對驅(qū)動程序的物理設(shè)備進行io,必須?
先對它們進行初始化,否則不能處理process的io。核心初始化的過程里,一共登記?
了兩個基本的操作過程。?
1.probe 確認io設(shè)備?
2.attach 設(shè)置device driver內(nèi)部的數(shù)據(jù)結(jié)構(gòu),使它能夠?qū)o設(shè)備?
進行操作。登記中斷子程序。?
在device driver中的處理過程有:?
1.i/o地址?
i/o命令使用的地址,使io設(shè)備的控制硬件和數(shù)據(jù)交換。?
2.中斷號?
io設(shè)備的狀態(tài)變化的時候,向cpu發(fā)出通知。?
3.共有內(nèi)存地址?
根據(jù)設(shè)備的不同,使用一部分內(nèi)存空間進行cpu和數(shù)據(jù)的交換。?
4.DMA通道?
不用通過cpu做中介,設(shè)備和內(nèi)存直接交換數(shù)據(jù)時候采用的通道的識別號。?
cpu可以在數(shù)據(jù)傳送的時候同時執(zhí)行它的機器語言。?
前兩種是必須有的。設(shè)備根據(jù)他連接的總線設(shè)備不一樣,處理過程也就不同。?
這個在核心的configure中反映出來。
各種總線設(shè)備的device driver的初始化?
驅(qū)動程序的初始化在main()初始化的過程中調(diào)用configure()?
(@i386/i386autoconf.c).
EISA bus?
連接EISA bus的io設(shè)備用的device driver的初始化在eisa_configure()?
(@i386/eisa/eisaconf.c)。各個device driver在module里對struct eisa_driver?
XXX(@i386/eisa/eisaconf.h)進行probe,attach等的設(shè)置,準備在宏DATA_SET?
(eisadriver_set,XXX)進行登記。?
eisa_configure()(@i386/eisa/eisaconf.c)對連接EISA bus的全部io設(shè)備?
標志和i/o地址進行檢測。之后便調(diào)用登記的probe子程序。在probe子程序中,通過?
eisa_match_dev()(@i386/eisa/eisaconf.c)對自身檢測,查找io設(shè)備,檢測i/o中斷?
號,然后進行使用預(yù)定,之后用eisa_registerdev()(@i386/eisa/eisaconf.c)在?
struct eisa_driver XXX對這個設(shè)備操作,作為device driver登記。全部的io設(shè)備?
的控制device driver登記完畢后,eisa_configure()就調(diào)用device driver的attach?
子程序。attach子程序則進行中斷處理程序的登記和device driver的數(shù)據(jù)的初始化。
核心的configure文件登記了以下的一些device driver:?
--------------------------------------------------------------------------?
device device driver的情報 source 參考?
--------------------------------------------------------------------------?
mainboard_drv i386/eisa/eisaconf.c?
ahb ahb_eisa_driver i386/eisa/aha1742.c scsi adapt?
ahc ahc_eisa_driver i386/eisa/aic7770.c scsi adapt?
bt bt_eisa_driver i386/eisa/bt74x.c scsi adapt?
ep ep_eisa_driver i386/eisa/3c5x9.c network interface?
fea pdq_eisa_driver i386/eisa/if_fea.c network interface?
vx vx_eisa_driver i386/eida/if_vx_eisa.c network interface?
--------------------------------------------------------------------------
PCI bus?
連接pci bus的設(shè)備的初始化在pci_configure()(@pci/pci.c)進行。各個?
device driver在module內(nèi)的struct pci_device XXX(@pci/pcivar.h)設(shè)置probe和?
attach,在通過宏DATA_SET(pcidevice_est,XXX)進行登記。?
DATA_SET(pcibus_set,i386pci)(@i386/isa/pcibus.c)登記的子程序可以?
得到有關(guān)pci bus的一些信息。之后和eisa bus處理過程一樣進行各種各樣的調(diào)用。?
核心的configure文件登記了以下的一些device driver:?
--------------------------------------------------------------------------?
device device driver的情報 source 參考?
--------------------------------------------------------------------------?
ahc ahc_pci_driver pci/aic7870.c scsi adapt?
bt bt_pci_driver pci/bt9xx.c scsi adapt?
ncr ncr_device pci/ncr.c scsi adapt?
amd trmamd_device pci/tek390.c scsi adapt?
cy cy_device pci/cy_pci.c serial port?
meteor met_device pci/meteor.c meteor通道?
stl stlpcidriver i386/isa/stallion.c serial port?
wdc wdc_pci_driver pci/wdc_p.c ide control?
de dedevice pci/if_de.c network interface?
ed ed_pci_driver pci/if_ed_p.c network interface?
fpa pfadevice pci/if_pfa.c network interface?
fxp fxp_device pci/if_pxp.c network interface?
lnc lnc_pci_driver pci/if_lnc_p.c network interface?
sr sr_pci_driver pci/if_sr_p.c network interface?
vx vxdevice pci/if_vx_pci.c network interface?
-------------------------------------------------------------------------
ISA bus?
連接ISA bus的io設(shè)備的device driver的初始化在isa_configure()(@i386/?
isa/isa.c)進行。和EISA,PCI很大的一個區(qū)別就是,在核心的配置文件中,要指定所?
有的io地址等。?
configure文件中,有象如下的記錄?
controller 控制設(shè)備名 at isa?...?
device device名 at isa?...?
這些內(nèi)容在編譯核心的目錄下作為ioconf.c的struct isa_device?
isa_devtab_XXX[]的初始值由config命令寫進去。在struct isa_device(@i386/isa?
/isa_device.h)的上,其次的成員變量由configure文件的記錄內(nèi)容進行設(shè)定。但是?
,“名字”是控制設(shè)備名/device名的數(shù)字除外的部分。?
-------------------------------------------------------------------------?
member名 configure的記述內(nèi)容?
-------------------------------------------------------------------------?
id_driver 名字drvier?
id_iobase prot I/O address?
id_irq irq號?
id_drq drq DMA通道號?
id_maddr iomem共有memory address?
id_msize iosiz共有memory長度?
id_intr vector device driver的中斷處理程序名?
id_unit 名字的后的數(shù)字(?)?
id_flags flags?
-------------------------------------------------------------------------
但是,和控制設(shè)備/device名有關(guān)的一些東西如bio,net,tty出現(xiàn)的場合,這?
些一般成為isa_devtab_bio[],isa_devtab_net[],isa_devtab_tty[]數(shù)組的初始值。?
沒有的情況,則成為isa_tab_null[]的初始值。還有一個就是名字driver,它是各個?
device driver的module內(nèi)部的struct isa_driver(@i386/isa/isa_device.h)一個東?
西。對isa bus設(shè)備的device driver,這個是一個固定值。?
象這樣的記錄:?
------------------------------------------------------------?
disk device名 at 控制設(shè)備名 driver 數(shù)字?
tape device名 at 控制設(shè)備名 driver 數(shù)字?
------------------------------------------------------------?
每個數(shù)字除外控制設(shè)備名(wdc或者fdc),總結(jié)起來就是寫進一個叫做?
isa_biotab_控制設(shè)備名[]的數(shù)組的某個元素的初始設(shè)定值。但對unit成員填入數(shù)字?
外,其他的也就和isa_devtab_bio[]的內(nèi)容一樣。?
isa_configure()依照isa_devtab_bio[],isa_devtab_net[],?
isa_devtab_tty[]的設(shè)定值調(diào)用probe子程序?qū)υO(shè)備的有無進行確認。有的話就繼續(xù)?
調(diào)用attach子程序。?
probe子程序?qū)υO(shè)備進行確認,不同的probe子程序也有可能對同樣的io地址?
進行操作。所以為了防止這個問題,isa_configure()對已經(jīng)確認過的的io地址不再?
給別的probe進行動作。?
同樣,錯認的可能性也有的。必要的時候沒連接的設(shè)備的probe要禁止使用,?
(在boot的參數(shù)的時候)。
========
freebsd完全攻略
http://www4.it168.com/jtzt/shenlan/server/freebsd/freebsd.htm總結(jié)
以上是生活随笔為你收集整理的FreeBSD学习总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓开发网络资源汇总
- 下一篇: iOS之WebView的使用总结