diff options
Diffstat (limited to 'zh/FAQ/hackers.sgml')
-rw-r--r-- | zh/FAQ/hackers.sgml | 485 |
1 files changed, 0 insertions, 485 deletions
diff --git a/zh/FAQ/hackers.sgml b/zh/FAQ/hackers.sgml deleted file mode 100644 index ea74e51e49..0000000000 --- a/zh/FAQ/hackers.sgml +++ /dev/null @@ -1,485 +0,0 @@ -<!-- $Id: hackers.sgml,v 1.6 1999-08-11 14:43:28 foxfair Exp $ --> -<!-- The FreeBSD Documentation Project --> -<!-- Translate into Chinese by jtjang@gcn.net.tw --> -<!-- English Version: 1.11 --> - - <sect> - <heading>給有心深入研究的 FreeBSD hacker <label id="hackers"></heading> - - <sect1> - <heading>SNAPs 和 RELEASEs 是什麼?</heading> - - <p>目前有三個活躍/半活躍的分支在 FreeBSD 的 - <url url="http://www.FreeBSD.org/cgi/cvsweb.cgi" name="CVS Repository">: - - <itemize> - <item><bf/RELENG_2_2/ 即 <bf/2.2-stable/ 即 <bf/"2.2 branch"/ - <item><bf/RELENG_3/ 即 <bf/3.x-stable/ 即 <bf/"3.0 branch"/ - <item><bf/HEAD/ 即 <bf/-current/ 即 <bf/4.0-current/ - </itemize> - - <p>如同其他兩個,<bf/HEAD/ 並不是真正的 branch tag,它只是一個符號 - 常數,指向 <em/"current:尚未分支的發展中版本"/ ,簡記為 - <bf/-current/。 - - <p>以現在來說,<bf/-current/ 朝向 4.0 發展,而 <bf/3.0-stable/ 這 - 個分支,也就是 <bf/RELENG_3/,在 1999 年 1 月從 <bf/-current/ 分出 - 來。 - - <p><bf/2.2-stable/ 這個分支,也就是 <bf/RELENG_2_2/,是在 1996 年 - 11 月從 -current 分出來。 - - <p><bf/2.1-stable/ 這個分支,也就是 <bf/RELENG_2_1_0/,則是在 - 1994 年 9 月從 -current 分支出來,這個分支已經完全退休了。 - - <sect1> - <heading> - 我要怎麼作出自己的 release?<label id="custrel"> - </heading> - - <p>做 release 包括下面這三個步驟:首先,做出有 <htmlurl - url="http://www.FreeBSD.org/cgi/man.cgi?vn" name="vn"> 這個驅動程 - 式的可用 kernel。把下面這一行加到 kernel 設定檔,然後做出新的 - kernel 重新開機: - - <verb> - pseudo-device vn #Vnode driver (turns a file into a device) - </verb> - - <p>接著,你手上要有整個 CVS repository。可以參考 <url - url="../../handbook/synching.html#CVSUP" name="CVSUP"> 這篇文章,但在 - supfile 中把 release 名稱設成 cvs,再刪掉所有 tag 或 date 的欄位,如 - 下: - - <verb> - *default prefix=/home/ncvs - *default base=/a - *default host=cvsup.FreeBSD.org - *default release=cvs - *default delete compress use-rel-suffix - - ## Main Source Tree - src-all - src-eBones - src-secure - - # Other stuff - ports-all - www - doc-all - </verb> - - <p>然後執行 <tt/cvsup -g supfile/ 把所有東西都抓下來... - - <p>最後,硬碟要有相當大的空間來做 release。假設你想把它放在 - <tt>/some/big/filesystem</tt> 這裡,上面這個例子也把 CVS - repository 放在 <tt>/home/ncvs</tt> 了,接著: - - <verb> - setenv CVSROOT /home/ncvs # or export CVSROOT=/home/ncvs - cd /usr/src/release - make release BUILDNAME=3.0-MY-SNAP CHROOTDIR=/some/big/filesystem/release - </verb> - - <p>整個 release 會做在 <tt>/some/big/filesystem/release</tt>。結束 - 時 <tt>/some/big/filesystem/release/R/ftp</tt> 這個目錄可以直接用 - 來做為 FTP 安裝方式的來源。如果想做出 -current 以外分支的 SNAP, - 在上面 make release 這一行加 <tt/RELEASETAG=SOMETAG/。舉例來說, - <tt/RELEASETAG=RELENG_2_2/ 這個參數會做個即時的 2.2-STABLE snapshot。 - - <sect1> - <heading>怎樣才能做出自己用的安裝磁片?</heading> - - <p>建立安裝磁片、還有做出 source/binary archive,都是由 - <tt>/usr/src/release/Makefile</tt> 裡面的各種 target 自動產生,這 - 個檔案裡的資訊應該足以開始。但是這個過程牽涉到 make world,所以會 - 用到相當多的時間和硬碟空間。 - - <sect1> - <heading>``make world'' 把原來裝的 binary 檔都換掉了。</heading> - - <p>沒錯,就是這樣子。如名字所示,``make world'' 會重新編譯系統內建 - 的每個 binary 檔,這樣在結束時就可確定有個一致且乾淨的環境(所以要 - 花上好一段時間)。 - - <p>在執行 ``<tt/make world/'' 或 ``<tt/make install/'' 時,如果有 - 設 <tt/DESTDIR/ 這個環境變數,新產生的 binary 將會裝在 - <tt>${DESTDIR}</tt> 下的同樣目錄樹中。但在某些修 - 改 shared library 和重建 binary 的無特定情況下,這樣做可能會使 - ``<tt/make world/'' 失敗。 - - <sect1> - <heading> - 在系統開機時,出現 ``(bus speed defaulted)''。 - </heading> - - <p>Adaptec 1542 SCSI 卡允許使用者用軟體調整匯流排的存取速度。早 - 期的 1542 驅動程式試圖將它設成可用的最快速度,但後來發現在一些 - 機器上不能用,所以現在要在 kernel 設定中加 ``<tt/TUNE_1542/'' - 這個選項來啟動這個功能。在支援的機器上用這個選項會使硬碟存取更 - 快,但在不支援的機器上有可能會毀掉資料。 - - <sect1> - <heading> - 我的網路連線不快,那可以跟著 current 的發展嗎?<label id="ctm"> - </heading> - - <p>可以,藉著 <url url="../../handbook/synching.html#CTM" name="CTM"> 就 - 可以不用下傳所有的原始碼目錄樹。 - - <sect1> - <heading>你是怎麼把發行版本中的檔案切成一個個 240k 的小檔案?</heading> - - <p>在以 BSD 為主的較新系統中,split 有個 ``<tt/-b/'' 選項,是用來 - 把檔案以任意數目 byte 切開。 - - <p>這裡是 <tt>/usr/src/Makefile</tt> 中的一個例子: - - <verb> - bin-tarball: - (cd ${DISTDIR}; \ - tar cf - . \ - gzip --no-name -9 -c | \ - split -b 240640 - \ - ${RELEASEDIR}/tarballs/bindist/bin_tgz.) - </verb> - - <sect1> - <heading>我在 kernel 裡加了些新功能,要把它寄給誰?</heading> - - <p>請看一下 <url url="../../handbook/contrib.html" - name="Handbook 中加入程式碼的部份">。 - - <p>同時也感謝你的費心! - - <sect1> - <heading>ISA 的 Plug N Play 卡是怎麼偵測和初始化的?</heading> - - <p>由 <url url="mailto:uhclem@nemesis.lonestar.org" - name="Frank Durda IV"> 所寫: - - <p>簡單的說,當主機發出是否有 PnP 卡的詢問訊號時,所有的 PnP - 會在幾個固定的 I/O port 作回應。所以當偵測 PnP 的程式開始時,它 - 會先問有沒有 PnP 卡在,接著所有 PnP 卡會在它所讀的 port 以自己 - 的型號 # 作回答,這樣偵測程式就會得到一個 wired-OR ``yes'' - 的數字,其中至少會有一個 bit 是打開的。然後偵測程式會要求型號 - (由 Microsoft/Intel指定)小於 X 的卡``離線'',再去看是否還有卡回 - 答同樣的詢問,如果得到 ``<tt/0/'',就表示沒有型號大於 X 的卡。 - 現在程式會問是否有型號小於 X 的卡,如果有的話,程式再要型號大於 - X-(limit/4) 的卡離線,然後重覆上面的動作。用這種類似 binary - search 的方法,在某範圍內找個幾次後,偵測程式最後會在機器中區分 - 出所有的 PnP 卡,搜尋次數也遠低於一個個找的 2^64 次。 - - <p>一張卡的 ID 由兩個 32-bit(所以上面是 2ˆ64) + 8bit 偵錯 - 碼組成,第一個 32 bits 是用來區分各家廠商的。這些廠商沒有出來澄 - 清過,但看來應假設同一家出的不同種類的卡的廠商 ID 有可能不同。 - 用 32 bits 只來表示不同廠商的想法實在有點過頭了。 - - <p>第二個 32 bits 則是型號 &num、乙太網路位址、或一些使這張卡獨 - 特的資料。除非第一個 32 bits 不同,否則廠商不可能作出第二個 32 - bit 相同的兩張卡。所以在一台機器中可以有同樣的好幾張卡,然而他們 - 整個 64 bits 還是會都不一樣。 - - <p>這兩個 32 bit 永遠都不可能為零,這使得最開始 binary search 中 - 的 wired-OR 會得到一個非零數字。 - - <p>一旦系統區分出所有卡的 ID,接著會經由同樣的 port 一個個重新啟 - 動每張卡,接著找出已知介面卡所需的資源、有那些可以選的 interrupt - 等等。所有卡都會被掃描一次,來收集這些資料。 - - <p>這些資訊接著和硬碟上的 ECU 檔案、或 MLB BIOS 裡的資料結合在一 - 起,通常是綜合 ECU 和 MLB 裡的 BIOS PnP 資料,這些週邊並不支援真 - 正的 PnP,然而偵測程式在檢查 BIOS 和 ECU 資料後,它可以避免 PnP - 週邊和那些偵測不到的相衝突。 - - <p>接著再度拜訪這些 PnP 週邊,這次會把可用的 I/O、DMA、IRQ 和記 - 憶體映射的位址都指定給它們。這些週邊就會出現在所指定的地方,直到 - 下一次重新開機為止,不過也沒有人說不能把它們隨時移來移去。 - - <p>上面有相當多的簡化,但你應該已經了解大致的過程。 - - <p>Microsoft 把表示印表機狀態的幾個主要 port 拿來作 PnP,他們的 - 邏輯是沒有一張卡會在這些地方解碼作相反的 I/O cycles。但是我找到 - 一款早期仍在評估 PnP 提案時的 IBM 原廠 printer board,它的確去解 - 對這些狀態 port 的寫入資料,但是 MS ``說了就算''。所以它們的確有 - 對印表機狀態 port 寫入,還有讀取該位址 + <tt/0x800/、和另一個在 - <tt/0x200/ 及 <tt/0x3ff/ 之間的 port。 - - <sect1> - <heading>FreeBSD 是否有支援 x86 以外的機器架構?</heading> - - <p>有幾群人士已經表示對發展多平台 FreeBSD 的興趣,其中 - FreeBSD/AXP (ALPHA) 即是其中相當成功的例子,可以在 <url - url="ftp://ftp.FreeBSD.org/pub/FreeBSD/alpha/" - name="ftp://ftp.FreeBSD.org/pub/FreeBSD/alpha"> 這裡取得它的 - 3.0 SNAPshot 版本。ALPHA 版的 FreeBSD 在越來越多的 ALPHA 機器上 - 使用,其中包括了 AlphaStation、AXPpci、PC164、Miata 和 Multia - 這幾種。要等到系統安裝工具完全、能用光碟安裝、以及有足夠能用的 - port/package 之後,我們才打算把它當作完整的版本,所以現在應該把 - FreeBSD/AXP 當作 BETA 品質的軟體。若要相關狀況的消息,請加入 - <tt><freebsd-alpha@FreeBSD.org></tt><ref id="mailing" - name="mailing list">. - - 也有人表示過將 FreeBSD SPARC 版本的興趣,如果你想參加這個計畫, - 請加入 <tt><freebsd-sparc@FreeBSD.org> - </tt><ref id="mailing" name="mailing list">。如果想要知道關於 - 新平台的討論,請加入 <tt><freebsd-platforms@FreeBSD.org></tt> - <ref id="mailing" name="mailing list">。 - - <sect1> - <heading>我剛剛寫了某個設備的驅動程式,能不能給它一個 major number? - </heading> - - <p>這要看你是否打算將這個驅動程式公開使用,如果是的話,請把它的原始 - 碼送一份給我們,還有 <tt>files.i386</tt> 修改的部份、kernel 設定 - 檔樣本、以及用來產生設備檔的 <htmlurl - url="http://www.FreeBSD.org/cgi/man.cgi?MAKEDEV" name="MAKEDEV">。 - 如果你不打算、或因為版權問題而不能公開的話,我們有特地保留 - character major number 32 和 block major number 8 給這方面的使用, - 直接用這兩個就好了。不論如何,我們都會很感激你能在 - <tt><freebsd-hackers@FreeBSD.org></tt> 發表驅動程式的消息。 - - <sect1> - <heading>關於放置目錄和檔案 inode 作法上的相異</heading> - - <p>在回答有關目錄放置方式不同的問題上,我在 1983 年寫好目前的作法 - 後就沒有再改變過,這種方式是針對原先的 FFS 檔案系統,後來也沒 - 有對它作任何更動。它在避免 cylinder group 被填滿這方面做得相當 - 成功,但是就像有些人已經注意到,它和 `find' 就配合得不大好。大 - 部份的檔案系統是由那些用 depth first search(aka ftw) 產生的 - archive 製造出來,解出來的目錄 inode 會橫跨好幾個 cylinder - group,如果以後要做 depth first search 的話,這是最糟糕的情況之 - 一。如果我們知道總共會產生多少目錄的話,解法是在做任何存取/寫 - 入動作之前,在每個 cylinder group 上先造出(所有目錄數/cylinder - greoup 的數目)這麼多的目錄。很明顯的,我們必須要有根據地去猜這 - 個數字,就算一個像 10 的很小固定數目也會使效率以級數成長。區分 - restore (即解開上述的 archive) 和一般檔案操作的方法可以是(現在 - 用的演算法可能要更敏感):如果一些目錄(最多 10 個)都在 10 秒內產 - 生的話,那麼就把這些目錄聚集在同一個 cylinder group。不管怎樣, - 我的經驗指出這是一個已經充份實驗過的部份。</p> - - <p>Kirk McKusick, September 1998</p> - - <sect1> - <heading>如何從 kernel panic 得到最多資訊?</heading> - - <p> - <em>[這節是從 <url url="mailto:wpaul@FreeBSD.org" name="Bill Paul"> - 在 freebsd-current <ref id="mailing" name="mailing list"> 上發表 - 的信中節錄,<url url="mailto:des@FreeBSD.org" - name="Dag-Erling Coïdan Smørgrav"> 修正了打字錯誤、再 - 加上括弧裡的注解。]</em> - - <p> - <verb> -From: Bill Paul <wpaul@skynet.ctr.columbia.edu> -Subject: Re: the fs fun never stops -To: ben@rosengart.com -Date: Sun, 20 Sep 1998 15:22:50 -0400 (EDT) -Cc: current@FreeBSD.org - </verb> - - <p> - <em>[<ben@rosengart.com> 發表了下面的 panic 訊息]</em> - <verb> -> Fatal trap 12: page fault while in kernel mode -> fault virtual address = 0x40 -> fault code = supervisor read, page not present -> instruction pointer = 0x8:0xf014a7e5 - ^^^^^^^^^^ -> stack pointer = 0x10:0xf4ed6f24 -> frame pointer = 0x10:0xf4ed6f28 -> code segment = base 0x0, limit 0xfffff, type 0x1b -> = DPL 0, pres 1, def32 1, gran 1 -> processor eflags = interrupt enabled, resume, IOPL = 0 -> current process = 80 (mount) -> interrupt mask = -> trap number = 12 -> panic: page fault - </verb> - - <p>當你看到像這樣的訊息時,只把它拷一份送上來是不夠的。我在上 - 面特地標明的 instruction pointer 值相當重要,不幸的是它會因設 - 定而不同。換句話說,這個值會跟你用的 kernel image 檔而變動。如 - 果是用某個 snapshot 版本的 GENERIC kernel,也許其他人可以追蹤 - 到出問題的函式,但如果你是用自訂的 kernel,那麼只有<em/你/才能 - 告訴我們問題出在那裡。 - - <p>要做的事包括這些: - - <itemize> - <item>把 instruction pointer 的值記下來。注意在前面的 <tt/0x8:/ - 在這個情況中並不重要,我們要的是 <tt/0xf0xxxxxx/。 - - <item>當系統重新開機後,執行這道命令: - <verb> -% nm /(造成 panic 的 kernel 檔案) | grep f0xxxxxx - </verb> - 其中 <tt/f0xxxxxx/ 就是記下來的 instruction pointer 值。有可能 - 不會剛好找到完整的這個字串,這是因為 kernel symbol table 裡的各 - 個 symbol 只是函式的進入點,但 instruction pointer 所指的位址有 - 可能是在函式內的某一處,而不一定在開頭。所以如果找不到整個字串, - 那麼把 instruction pointer 值的最後一個數字拿掉,再試一次: - - <verb> -% nm /kernel.that.caused.the.panic | grep f0xxxxx - </verb> - 如果這樣也找不到,那就把另一個數字去掉再找,一直重複到找到為止, - 結果是一串可能造成 panic 的函式列表。這樣比直接找到出問題的函式 - 來得差,但至少好過什麼都沒有。 - </itemize> - - <p>我常常看到人們顯示一大片 panic 訊息,但很少看到有人花一點時間 - 把 instruction pointer 和 kernel symbol table 中的函式比較一下。 - - <p>要追蹤出造成 panic 原因的最好方法是先做出 crash dump,然後用 - <tt/gdb(1)/ 在上面做 stack trace。當然,這要靠 -current 中的 - <tt/gdb(1)/ 能運作正常,然而我無法保證這一點。(記得有人說 ELF 的 - <tt/gdb(1)/ 在 kernel 的 crash dump 上不能正常操作,在 3.0 脫離 - BETA 階段時最好有人先檢查這方面的狀況,免得很多人在收到 3.0 光碟 - 後脹紅了臉。) - - <p> - 不管是那一種,我通常是用這個方法: - - <itemize> - <item>寫好 kernel 設定檔。如果你需要用 kernel debugger,在設定 - 檔中加上 `options DDB' 這個選項。(當我懷疑有出現無窮迴圈時,通 - 常會用這個來設定中斷點。) - <item>用 <tt/config -g KERNELCONFIG/ 做出用來編譯的目錄 - <item><tt>cd /sys/compile/KERNELCONFIG; make</tt> - <item>等 kernel 編譯出來 - <item><tt/cp kernel kernel.debug/ - <item><tt/strip -d kernel/ - <item><tt/mv /kernel /kernel.orig/ - <item><tt>cp kernel /</tt> - <item>重新開機 - </itemize> - - <p> <em>[注意:現在 FreeBSD 3.x kernel 內定是 ELF 格式,所以應該 - 用 <tt/strip -g/ 而不是 <tt/strip -d/。如果你的 kernel 因某種原 - 因仍是 a.out 格式的話,則用 <tt/strip -aout -d/。]</em> - - <p>注意你<em/不會/真的用包括所有 debug symbol 的 kernel 來開機, - 用 <tt/-g/ 編譯出來的 kernel 大小很容易就超過 10MB。不需要用這麼 - 大的 kernel 開機,晚一點 <tt/gdb(1)/ 才會需要它(<tt/gdb(1)/ 會用 - 到裡面的 symbol table)。所以我們才會把完整的 kernel 複製一份,接 - 著用 <tt/strip -d/ 刪掉 debug symbol,做出第二個 kernel,這個才真 - 正拿來開機。 - - <p>要確定能抓到 crash dump,先編輯 <tt>/etc/rc.conf</tt>,將 - <tt/dumpdev/ 指到 swap 分割區。這樣 <tt/rc(8)/ 會用 <tt/dumpon(8)/ - 來啟動 crash dump,你也可以手動用 <tt/dumpon(8)/。在 panic 之後, - crash dump 可以用 <tt/savecore(8)/ 存起來;如果 <tt>/etc/rc.conf</tt> - 裡有設 <tt/dumpdev/,那麼重新開機後 <tt/rc(8)/ 會自動執行 - <tt/savecore(8)/ 把 crash dump 存在 <tt>/var/crash</tt>。 - - <p>注意:FreeBSD 的 crash dump 通常和機器裡的實際記憶體一樣大, - 就像如果有 64MB 記憶體,crash dump 大小就是 64MB。所以要確定 - <tt>/var/crash</tt> 下有足夠的空間,或是可以手動執行 <tt/savecore(8)/ - 把 crash dump 放到另一個空間較夠的目錄下。另一種也許可以限制 crash - dump 的方法,是在 kernel 設定檔中用 <tt/options MAXMEM=(foo)/, - 將 kernel 可用的記憶體限制在合理的大小。舉例來說,如果你有 128MB - 的記憶體,但是可以限制 kernel 只能用 16MB 的記憶體,這樣 crash - dump 就是 16MB 而不是 128MB 了。 - - <p>一旦發現有了 crash dump,就可以用 <tt/gdb(1)/ 來做 stack trace - ,如下所示: - - <p> - <verb> -% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0 -(gdb) where - </verb> - - <p>要注意可能會出現好幾個螢幕的可用資訊,你可以用 <tt/script(1)/ - 把所有輸出都存起來。用包括所有 debug symbol 的 kernel 來除錯, - 這樣應該可以直接顯示 panic 是發生在那一行。通常是由下往上讀 stack - strace,這樣才能一個個追蹤出有那些動作引到 crash。也可以用 - <tt/gdb(1)/ 把各種變數或結構的內容印出來,以檢查系統 crash 時的 - 實際狀態。 - - <p>好啦,如果你有第二台電腦而且有夠瘋狂,可以將 <tt/gdb(1)/ 設定 - 成遠端除錯。這樣你可以在一台機器中用 <tt/gdb(1)/ 去除錯另一台裡的 - kernel,可以執行的包括設定中斷點、在 kernel 原始碼中一步步執行等 - 等,就像在一般使用者程式上除錯一樣。由於沒有什麼機會為除錯而設置 - 兩台並鄰電腦,所以我還沒有這樣玩過。 - - <p><em>[Bill 附注:我忘了提到一點:如果你有啟動 DDB 而 kernel 也 - 已經進入除錯器,可以在 DDB 命令列下打 `panic',強迫產生 panic(還 - 有 crash dump)。也有可能在 panic 階段時再進入除錯器,如果這樣的話 - ,輸入 `continue',接著它就會完成 crash dump。 -ed]</em> - - <sect1> - <heading>dlsym() 對 ELF 執行檔不能用!</heading> - - <p>在 ELF 一系列的工具中,內定是不會讓 dynamic linker 看到執行檔 - 裡定義了那些 symbol。所以 <tt>dlsym()</tt> 沒有辦法用藉由呼叫 - <tt>dlopen(NULL, flags)</tt> 取得的 handle,用它去搜尋有那些 - symbol 一定會失敗。 - - <p>如果你想要用 <tt>dlsym()</tt> 找出某個 process 的主執行檔中 - 有那些 symbol,則要在 link 時對 - <htmlurl url="http://www.FreeBSD.org/cgi/man.cgi?ld" - name="ELF linker"> 加上 <tt>-export-dynamic</tt> 這個參數。 - - <sect1> - <heading>增加或減少 kernel 能定址的空間</heading> - - <p>系統的內定是,FreeBSD 3.x kernel 能定址到 256 MB,4.x 則是 - 1 GB。如果是網路負荷相當重的伺服器(就像大型 FTP 或 HTTP 伺服器), - 256 MB 可能會不大夠。 - - <p>要怎麼增加定址空間呢? 要從兩方面著手。首先告訴 kernel 本身要 - 保留較大空間; 其次,既然是在定址空間的最上面載入 kernel,所以還 - 要調低載入的位址,否則就會超過定址範圍。 - - <p>增加 <tt>src/sys/i386/include/pmap.h</tt> 裡的 <tt/NKPDE/ 值 - 便可達成第一個目標。1 GB 的定址空間會像這樣: - - <verb> -#ifndef NKPDE -#ifdef SMP -#define NKPDE 254 /* addressable number of page tables/pde's */ -#else -#define NKPDE 255 /* addressable number of page tables/pde's */ -#endif /* SMP */ -#endif - </verb> - - <p>要算出 <tt/NKPDE/ 的正確值,將想要的空間大小(以 megabyte 為單 - 位)除以 4,接著單 CPU 機器減 1,雙 CPU 則是減 2。 - - <p>要解決第二個問題,必須自行算出 kernel 被載入的位址:求出 - 0x100100000 減掉定址空間大小的值(以 byte 為單位),如 1 GB 大小就 - 是 0xc0100000。把 <tt>src/sys/i386/conf/Makefile.i386</tt> 裡的 - <tt/LOAD_ADDRESS/ 設成這個值,接著在 - <tt>src/sys/i386/conf/kernel.script</tt> 中,將 section 列表最前面的 - location counter 設成相同的值,如下: - - <verb> -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(btext) -SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/obj/elf/home/src/tmp/usr/i386-unknown-freebsdelf/lib); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0xc0100000 + SIZEOF_HEADERS; - .interp : { *(.interp) } - </verb> - - <p>然後重新 config 和做出新的 kernel。在執行像 <tt/ps(1)/、 - <tt/top(1)/ 這類程式時可能會碰到問題,做一次 <tt/make world/ - 應該就可以解決(或把改過的 <tt/pmap.h/ 拷到 <tt>/usr/include/vm/</tt> - 下,再手動編譯 <tt/libkvm/、<tt/ps/ 和 <tt/top/)。 - - <p>注意:kernel 所能定址的空間大小必須是 4 megabytes 的倍數。 - - <p>[<url url="mailto:dg@FreeBSD.org" name="David Greenman"> 加上 - 這一段:<em>我認為 kernel 定址空間大小應該是 2 的乘冪,但不大確 - 定這一點。舊的啟動程式會動到 high order address bits,記得它假設 - 至少有 256 MB。]</em> - - </sect> - |