Introduce the final part of Chinese(big5) FAQ, the next step I'd like to

let Simplified Chinese(GB2312) FAQ show up.

These two files was submitted by:
	J.T. Jang <jtjang@gcn.net.tw>

The translation of Handbook(new DocBook) is in progress , too.
This commit is contained in:
Foxfair Hu 1999-04-21 05:26:08 +00:00
parent 1288a84194
commit 4eccc1e987
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=4721
4 changed files with 1522 additions and 1652 deletions

View file

@ -1,58 +1,54 @@
<!-- $Id: hackers.sgml,v 1.2 1999-03-21 16:25:40 wosch Exp $ -->
<!-- $Id: hackers.sgml,v 1.3 1999-04-21 05:26:07 foxfair Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!-- Translate into Chinese by -->
<!-- Translate into Chinese by jtjang@gcn.net.tw -->
<!-- English Version: 1.11 -->
<sect>
<heading>For serious FreeBSD hackers only<label id="hackers"></heading>
<heading>只給正經的 FreeBSD hacker 看<label id="hackers"></heading>
<sect1>
<heading>
What are SNAPs and RELEASEs?
</heading>
<heading>SNAPs 和 RELEASEs 是什麼?</heading>
<p>There are currently three active/semi-active branches in the FreeBSD
<p>目前有三個活躍/半活躍的分支在 FreeBSD 的
<url url="http://www.freebsd.org/cgi/cvsweb.cgi" name="CVS Repository">:
<itemize>
<item><bf/RELENG_2_2/ AKA <bf/2.2-stable/ AKA <bf/"2.2 branch"/
<item><bf/RELENG_3/ AKA <bf/3.x-stable/ AKA <bf/"3.0 branch"/
<item><bf/HEAD/ AKA <bf/-current/ AKA <bf/4.0-current/
<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/ is not an actual branch tag, like the other two, it's
simply a symbolic constant for
<em/"the current, non-branched development stream"/ which we simply
refer to as <bf/-current/.
<p>如同其他兩個,<bf/HEAD/ 並不是真正的 branch tag它只是一個符號
常數,指向 <em/"current尚未分支的發展中版本"/ ,簡記為
<bf/-current/。
<p>Right now, <bf/-current/ is the 4.0 development stream and the
<bf/3.0-stable/ branch, <bf/RELENG_3/, forked off from
<bf/-current/ in Jan 1999.
<p>以現在來說,<bf/-current/ 朝向 4.0 發展,而 <bf/3.0-stable/ 這
個分支,也就是 <bf/RELENG_3/,在 1999 年 1 月從 <bf/-current/ 分出
來。
<p>The <bf/2.2-stable/ branch, <bf/RELENG_2_2/, departed -current in
November 1996.
<p><bf/2.2-stable/ 這個分支,也就是 <bf/RELENG_2_2/,是在 1996 年
11 月從 -current 分出來。
<p>The <bf/2.1-stable/ branch, <bf/RELENG_2_1_0/, departed -current in
September of 1994. This branch has been fully retired.
<p><bf/2.1-stable/ 這個分支,也就是 <bf/RELENG_2_1_0/,則是在
1994 年 9 月從 -current 分支出來,這個分支已經完全退休了。
<sect1>
<heading>
How do I make my own custom release?<label id="custrel">
我要怎麼作出自己的 release<label id="custrel">
</heading>
<p>To make a release you need to do three things: First, you need to
be running a kernel with the <htmlurl
url="http://www.freebsd.org/cgi/man.cgi?vn" name="vn"> driver configured
in. Add this to your kernel config file and build a new kernel:
<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>Second, you have to have the whole CVS repository at hand.
To get this you can use <url url="../../handbook/cvsup.html" name="CVSUP">
but in your supfile set the release name to cvs and remove any tag or
date fields:
<p>接著,你手上要有整個 CVS repository。可以參考 <url
url="../handbook/cvsup.html" name="CVSUP"> 這篇文章,但在 supfile
中把 release 名稱設成 cvs再刪掉所有 tag 或 date 的欄位,如下:
<verb>
*default prefix=/home/ncvs
@ -72,12 +68,11 @@
doc-all
</verb>
<p>Then run <tt/cvsup -g supfile/ to suck all the good bits onto your
box...
<p>然後執行 <tt/cvsup -g supfile/ 把所有東西都抓下來...
<p>Finally, you need a chunk of empty space to build into. Let's
say it's in <tt>/some/big/filesystem</tt>, and from the example
above you've got the CVS repository in <tt>/home/ncvs</tt>:
<p>最後,硬碟要有相當大的空間來做 release。假設你想把它放在
<tt>/some/big/filesystem</tt> 這裡,上面這個例子也把 CVS
repository 放在 <tt>/home/ncvs</tt> 了,接著:
<verb>
setenv CVSROOT /home/ncvs # or export CVSROOT=/home/ncvs
@ -85,70 +80,59 @@
make release BUILDNAME=3.0-MY-SNAP CHROOTDIR=/some/big/filesystem/release
</verb>
<p>An entire release will be built in
<tt>/some/big/filesystem/release</tt> and you will have a full FTP-type
installation in <tt>/some/big/filesystem/release/R/ftp</tt> when you're
done. If you want to build your SNAP along some other branch than
-current, you can also add <tt/RELEASETAG=SOMETAG/ to
the make release command line above, e.g. <tt/RELEASETAG=RELENG_2_2/
would build an up-to-the- minute 2.2-STABLE snapshot.
<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>How do I create customized installation disks?</heading>
<heading>怎樣才能做出自己用的安裝磁片?</heading>
<p>The entire process of creating installation disks and source and
binary archives is automated by various targets in
<tt>/usr/src/release/Makefile</tt>. The information there should
be enough to get you started. However, it should be said that this
involves doing a ``make world'' and will therefore take up a lot of
time and disk space.
<p>建立安裝磁片、還有做出 source/binary archive都是由
<tt>/usr/src/release/Makefile</tt> 裡面的各種 target 自動產生,這
個檔案裡的資訊應該足以開始。但是這個過程牽涉到 make world所以會
用到相當多的時間和硬碟空間。
<sect1>
<heading>``make world'' clobbers my existing installed binaries.</heading>
<heading>``make world'' 把原來裝的 binary 檔都換掉了。</heading>
<p>Yes, this is the general idea; as its name might suggest,
``make world'' rebuilds every system binary from scratch, so you can be
certain of having a clean and consistent environment at the end (which
is why it takes so long).
<p>沒錯,就是這樣子。如名字所示,``make world'' 會重新編譯系統內建
的每個 binary 檔,這樣在結束時就可確定有個一致且乾淨的環境(所以要
花上好一段時間)。
<p>If the environment variable <tt/DESTDIR/ is defined while running
``<tt/make world/'' or ``<tt/make install/'', the newly-created
binaries will be deposited in a directory tree identical to the
installed one, rooted at <tt>&dollar;&lcub;DESTDIR&rcub;</tt>.
Some random combination of shared libraries modifications and
program rebuilds can cause this to fail in ``<tt/make world/'',
however.
<p>在執行 ``<tt/make world/'' 或 ``<tt/make install/'' 時,如果有
設 <tt/DESTDIR/ 這個環境變數,新產生的 binary 將會裝在
<tt>&dollar;&lcub;DESTDIR&rcub;</tt> 下的同樣目錄樹中。但在某些修
改 shared library 和重建 binary 的無特定情況下,這樣做可能會使
``<tt/make world/'' 失敗。
<sect1>
<heading>
When my system boots, it says ``(bus speed defaulted)''.
在系統開機時,出現 ``(bus speed defaulted)''。
</heading>
<p>The Adaptec 1542 SCSI host adapters allow the user to configure
their bus access speed in software. Previous versions of the
1542 driver tried to determine the fastest usable speed and set
the adapter to that. We found that this breaks some users'
systems, so you now have to define the ``<tt/TUNE&lowbar;1542/'' kernel
configuration option in order to have this take place. Using it
on those systems where it works may make your disks run faster,
but on those systems where it doesn't, your data could be
corrupted.
<p>Adaptec 1542 SCSI 卡允許使用者用軟體調整匯流排的存取速度。早
期的 1542 驅動程式試圖將它設成可用的最快速度,但後來發現在一些
機器上不能用,所以現在要在 kernel 設定中加 ``<tt/TUNE&lowbar;1542/''
這個選項來啟動這個功能。在支援的機器上用這個選項會使硬碟存取更
快,但在不支援的機器上有可能會毀掉資料。
<sect1>
<heading>
Can I follow current with limited Internet access?<label id="ctm">
我的網路連線不快,那可以跟著 current 的發展嗎?<label id="ctm">
</heading>
<p>Yes, you can do this <tt /without/ downloading the whole source tree
by using the <url url="../../handbook/ctm.html" name="CTM facility.">
<p>可以,藉著 <url url="../handbook/ctm.html" name="CTM"> 就
可以不用下傳所有的原始碼目錄樹。
<sect1>
<heading>How did you split the distribution into 240k files?</heading>
<heading>你是怎麼把發行版本中的檔案切成一個個 240k 的小檔案?</heading>
<p>Newer BSD based systems have a ``<tt/-b/'' option to split that
allows them to split files on arbitrary byte boundaries.
<p>在以 BSD 為主的較新系統中split 有個 ``<tt/-b/'' 選項,是用來
把檔案以任意數目 byte 切開。
<p>Here is an example from <tt>/usr/src/Makefile</tt>.
<p>這裡是 <tt>/usr/src/Makefile</tt> 中的一個例子:
<verb>
bin-tarball:
@ -160,166 +144,130 @@
</verb>
<sect1>
<heading>I've written a kernel extension, who do I send it to?</heading>
<heading>我在 kernel 裡加了些新功能,要把它寄給誰?</heading>
<p>Please take a look at <url url="../../handbook/contrib.html"
name="The Handbook entry on how to submit code.">
<p>請看一下 <url url="../handbook/contrib.html"
name="Handbook 中加入程式碼的部份">。
<p>And thanks for the thought!
<p>同時也感謝你的費心!
<sect1>
<heading>How are Plug N Play ISA cards detected and initialized?</heading>
<heading>ISA 的 Plug N Play 卡是怎麼偵測和初始化的?</heading>
<p>By: <url url="mailto:uhclem@nemesis.lonestar.org"
name="Frank Durda IV">
<p> <url url="mailto:uhclem@nemesis.lonestar.org"
name="Frank Durda IV"> 所寫:
<p>In a nutshell, there a few I/O ports that all of the PnP boards
respond to when the host asks if anyone is out there. So when
the PnP probe routine starts, he asks if there are any PnP boards
present, and all the PnP boards respond with their model &num; to
a I/O read of the same port, so the probe routine gets a wired-OR
``yes'' to that question. At least one bit will be on in that
reply. Then the probe code is able to cause boards with board
model IDs (assigned by Microsoft/Intel) lower than X to go
``off-line''. It then looks to see if any boards are still
responding to the query. If the answer was ``<tt/0/'', then
there are no boards with IDs above X. Now probe asks if there
are any boards below ``X''. If so, probe knows there are boards
with a model numbers below X. Probe then asks for boards greater
than X-(limit/4) to go off-line. If repeats the query. By
repeating this semi-binary search of IDs-in-range enough times,
the probing code will eventually identify all PnP boards present
in a given machine with a number of iterations that is much lower
than what 2^64 would take.
<p>簡單的說,當主機發出是否有 PnP 卡的詢問訊號時,所有的 PnP
會在幾個固定的 I/O port 作回應。所以當偵測 PnP 的程式開始時,它
會先問有沒有 PnP 卡在,接著所有 PnP 卡會在它所讀的 port 以自己
的型號 &num; 作回答,這樣偵測程式就會得到一個 wired-OR ``yes''
的數字,其中至少會有一個 bit 是打開的。然後偵測程式會要求型號
(由 Microsoft/Intel指定)小於 X 的卡``離線'',再去看是否還有卡回
答同樣的詢問,如果得到 ``<tt/0/'',就表示沒有型號大於 X 的卡。
現在程式會問是否有型號小於 X 的卡,如果有的話,程式再要型號大於
X-(limit/4) 的卡離線,然後重覆上面的動作。用這種類似 binary
search 的方法,在某範圍內找個幾次後,偵測程式最後會在機器中區分
出所有的 PnP 卡,搜尋次數也遠低於一個個找的 2^64 次。
<p>The IDs are two 32-bit fields (hence 2&circ;64) + 8 bit checksum.
The first 32 bits are a vendor identifier. They never come out
and say it, but it appears to be assumed that different types of
boards from the same vendor could have different 32-bit vendor
ids. The idea of needing 32 bits just for unique manufacturers
is a bit excessive.
<p>一張卡的 ID 由兩個 32-bit(所以上面是 2&circ;64) + 8bit 偵錯
碼組成,第一個 32 bits 是用來區分各家廠商的。這些廠商沒有出來澄
清過,但看來應假設同一家出的不同種類的卡的廠商 ID 有可能不同。
用 32 bits 只來表示不同廠商的想法實在有點過頭了。
<p>The lower 32 bits are a serial &num;, ethernet address, something
that makes this one board unique. The vendor must never produce
a second board that has the same lower 32 bits unless the upper
32 bits are also different. So you can have multiple boards of
the same type in the machine and the full 64 bits will still be
unique.
<p>第二個 32 bits 則是型號 &num、乙太網路位址、或一些使這張卡獨
特的資料。除非第一個 32 bits 不同,否則廠商不可能作出第二個 32
bit 相同的兩張卡。所以在一台機器中可以有同樣的好幾張卡,然而他們
整個 64 bits 還是會都不一樣。
<p>The 32 bit groups can never be all zero. This allows the
wired-OR to show non-zero bits during the initial binary search.
<p>這兩個 32 bit 永遠都不可能為零,這使得最開始 binary search 中
的 wired-OR 會得到一個非零數字。
<p>Once the system has identified all the board IDs present, it will
reactivate each board, one at a time (via the same I/O ports),
and find out what resources the given board needs, what interrupt
choices are available, etc. A scan is made over all the boards
to collect this information.
<p>一旦系統區分出所有卡的 ID接著會經由同樣的 port 一個個重新啟
動每張卡,接著找出已知介面卡所需的資源、有那些可以選的 interrupt
等等。所有卡都會被掃描一次,來收集這些資料。
<p>This info is then combined with info from any ECU files on the
hard disk or wired into the MLB BIOS. The ECU and BIOS PnP
support for hardware on the MLB is usually synthetic, and the
peripherals don't really do genuine PnP. However by examining
the BIOS info plus the ECU info, the probe routines can cause the
devices that are PnP to avoid those devices the probe code cannot
relocate.
<p>這些資訊接著和硬碟上的 ECU 檔案、或 MLB BIOS 裡的資料結合在一
起,通常是綜合 ECU 和 MLB 裡的 BIOS PnP 資料,這些週邊並不支援真
正的 PnP然而偵測程式在檢查 BIOS 和 ECU 資料後,它可以避免 PnP
週邊和那些偵測不到的相衝突。
<p>Then the PnP devices are visited once more and given their I/O,
DMA, IRQ and Memory-map address assignments. The devices will
then appear at those locations and remain there until the next
reboot, although there is nothing that says you can't move them
around whenever you want.
<p>接著再度拜訪這些 PnP 週邊,這次會把可用的 I/O、DMA、IRQ 和記
憶體映射的位址都指定給它們。這些週邊就會出現在所指定的地方,直到
下一次重新開機為止,不過也沒有人說不能把它們隨時移來移去。
<p>There is a lot of oversimplification above, but you should get
the general idea.
<p>上面有相當多的簡化,但你應該已經了解大致的過程。
<p>Microsoft took over some of the primary printer status ports to
do PnP, on the logic that no boards decoded those addresses for
the opposing I/O cycles. I found a genuine IBM printer board
that did decode writes of the status port during the early PnP
proposal review period, but MS said ``tough''. So they do a
write to the printer status port for setting addresses, plus that
use that address + <tt/0x800/, and a third I/O port for reading
that can be located anywhere between <tt/0x200/ and <tt/0x3ff/.
<p>Microsoft 把表示印表機狀態的幾個主要 port 拿來作 PnP他們的
邏輯是沒有一張卡會在這些地方解碼作相反的 I/O cycles。但是我找到
一款早期仍在評估 PnP 提案時的 IBM 原廠 printer board它的確去解
對這些狀態 port 的寫入資料,但是 MS ``說了就算''。所以它們的確有
對印表機狀態 port 寫入,還有讀取該位址 + <tt/0x800/、和另一個在
<tt/0x200/ 及 <tt/0x3ff/ 之間的 port。
<sect1>
<heading>Does FreeBSD support architectures other than the x86?</heading>
<heading>FreeBSD 是否有支援 x86 以外的機器架構?</heading>
<p>Several groups of people have expressed interest in working on
multi-architecture ports for FreeBSD and the FreeBSD/AXP (ALPHA)
port is one such effort which has been quite successful, now
available in 3.0 SNAPshot release form at <url
<p>有幾群人士已經表示對發展多平台 FreeBSD 的興趣,其中
FreeBSD/AXP (ALPHA) 即是其中相當成功的例子,可以在 <url
url="ftp://ftp.freebsd.org/pub/FreeBSD/alpha/"
name="ftp://ftp.freebsd.org/pub/FreeBSD/alpha">. The ALPHA
port currently runs on a growing number of ALPHA machine
types, among them the AlphaStation, AXPpci, PC164, Miata and Multia
models. This port is not yet considered a full release and won't be
until a full compliment of system installation tools and a distribution
on CDROM installation media is available, including a reasonable
number of working ports and packages.
FreeBSD/AXP should be considered BETA quality software at this
time. For status information, please join the
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>&lt;freebsd-alpha@FreeBSD.ORG&gt;</tt><ref id="mailing"
name="mailing list">.
Interest has also been expressed in a port of FreeBSD to
the SPARC architecture, join the <tt>&lt;freebsd-sparc@FreeBSD.ORG&gt;
</tt><ref id="mailing" name="mailing list"> if you are interested
in joining that project. For general discussion on new architectures,
join the <tt>&lt;freebsd-platforms@FreeBSD.ORG&gt;</tt>
<ref id="mailing" name="mailing list">.
也有人表示過將 FreeBSD SPARC 版本的興趣,如果你想參加這個計畫,
請加入 <tt>&lt;freebsd-sparc@FreeBSD.ORG&gt;
</tt><ref id="mailing" name="mailing list">。如果想要知道關於
新平台的討論,請加入 <tt>&lt;freebsd-platforms@FreeBSD.ORG&gt;</tt>
<ref id="mailing" name="mailing list">。
<sect1>
<heading>I need a major number for a device driver I've written.</heading>
<p>This depends on whether or not you plan on making the driver
publicly available. If you do, then please send us a copy of the
driver source code, plus the appropriate modifications to
<tt>files.i386</tt>, a sample configuration file entry, and the
appropriate <htmlurl url="http://www.freebsd.org/cgi/man.cgi?MAKEDEV"
name="MAKEDEV"> code to create any special files your device uses. If
you do not, or are unable to because of licensing restrictions, then
character major number 32 and block major number 8 have been reserved
specifically for this purpose; please use them. In any case, we'd
appreciate hearing about your driver on
<tt>&lt;freebsd-hackers@FreeBSD.ORG&gt;</tt>.
<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>&lt;freebsd-hackers@FreeBSD.ORG&gt;</tt> 發表驅動程式的消息。
<sect1>
<heading>Alternative layout policies for directories</heading>
<heading>關於放置目錄和檔案 inode 作法上的相異</heading>
<p>
In answer to the question of alternative layout policies for
directories, the scheme that is currently in use is unchanged
from what I wrote in 1983. I wrote that policy for the original
fast filesystem, and never revisited it. It works well at keeping
cylinder groups from filling up. As several of you have noted,
it works poorly for find. Most filesystems are created from
archives that were created by a depth first search (aka ftw).
These directories end up being striped across the cylinder groups
thus creating a worst possible senario for future depth first
searches. If one knew the total number of directories to be
created, the solution would be to create (total / fs_ncg) per
cylinder group before moving on. Obviously, one would have to
create some heuristic to guess at this number. Even using a
small fixed number like say 10 would make an order of magnitude
improvement. To differentiate restores from normal operation
(when the current algorithm is probably more sensible), you
could use the clustering of up to 10 if they were all done
within a ten second window. Anyway, my conclusion is that this
is an area ripe for experimentation.</p>
<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>Making the most of a kernel panic</heading>
<heading>如何從 kernel panic 得到最多資訊?</heading>
<p>
<em>[This section was extracted from a mail written by <url
url="mailto:wpaul@FreeBSD.ORG" name="Bill Paul"> on the
freebsd-current <ref id="mailing" name="mailing list"> by <url
url="mailto:des@FreeBSD.ORG" name="Dag-Erling Co&iuml;dan
Sm&oslash;rgrav">, who fixed a few typos and added the bracketed
comments]</em>
<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&iuml;dan Sm&oslash;rgrav"> 修正了打字錯誤、再
加上括弧裡的注解。]</em>
<p>
<verb>
@ -331,8 +279,7 @@ Cc: current@FreeBSD.ORG
</verb>
<p>
<em>[&lt;ben@rosengart.com&gt; posted the following panic
message]</em>
<em>[&lt;ben@rosengart.com&gt; 發表了下面的 panic 訊息]</em>
<verb>
> Fatal trap 12: page fault while in kernel mode
> fault virtual address = 0x40
@ -350,112 +297,93 @@ Cc: current@FreeBSD.ORG
> panic: page fault
</verb>
<p> [When] you see a message like this, it's not enough to just
reproduce it and send it in. The instruction pointer value that
I highlighted up there is important; unfortunately, it's also
configuration dependent. In other words, the value varies
depending on the exact kernel image that you're using. If you're
using a GENERIC kernel image from one of the snapshots, then
it's possible for somebody else to track down the offending
function, but if you're running a custom kernel then only
<em/you/ can tell us where the fault occured.
<p>當你看到像這樣的訊息時,只把它拷一份送上來是不夠的。我在上
面特地標明的 instruction pointer 值相當重要,不幸的是它會因設
定而不同。換句話說,這個值會跟你用的 kernel image 檔而變動。如
果是用某個 snapshot 版本的 GENERIC kernel也許其他人可以追蹤
到出問題的函式,但如果你是用自訂的 kernel那麼只有<em/你/才能
告訴我們問題出在那裡。
<p> What you should do is this:
<p>要做的事包括這些:
<itemize>
<item>Write down the instruction pointer value. Note that the
<tt/0x8:/ part at the begining is not significant in this case:
it's the <tt/0xf0xxxxxx/ part that we want.
<item>When the system reboots, do the following:
<item>把 instruction pointer 的值記下來。注意在前面的 <tt/0x8:/
在這個情況中並不重要,我們要的是 <tt/0xf0xxxxxx/。
<item>當系統重新開機後,執行這道命令:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
% nm /(造成 panic 的 kernel 檔案) | grep f0xxxxxx
</verb>
where <tt/f0xxxxxx/ is the instruction pointer value. The
odds are you will not get an exact match since the symbols
in the kernel symbol table are for the entry points of
functions and the instruction pointer address will be
somewhere inside a function, not at the start. If you don't
get an exact match, omit the last digit from the instruction
pointer value and try again, i.e.:
其中 <tt/f0xxxxxx/ 就是記下來的 instruction pointer 值。有可能
不會剛好找到完整的這個字串,這是因為 kernel symbol table 裡的各
個 symbol 只是函式的進入點,但 instruction pointer 所指的位址有
可能是在函式內的某一處,而不一定在開頭。所以如果找不到整個字串,
那麼把 instruction pointer 值的最後一個數字拿掉,再試一次:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxx
</verb>
If that doesn't yield any results, chop off another digit.
Repeat until you get some sort of output. The result will be
a possible list of functions which caused the panic. This is
a less than exact mechanism for tracking down the point of
failure, but it's better than nothing.
如果這樣也找不到,那就把另一個數字去掉再找,一直重複到找到為止,
結果是一串可能造成 panic 的函式列表。這樣比直接找到出問題的函式
來得差,但至少好過什麼都沒有。
</itemize>
<p> I see people constantly show panic messages like this but
rarely do I see someone take the time to match up the
instruction pointer with a function in the kernel symbol table.
<p>我常常看到人們顯示一大片 panic 訊息,但很少看到有人花一點時間
把 instruction pointer 和 kernel symbol table 中的函式比較一下。
<p> The best way to track down the cause of a panic is by
capturing a crash dump, then using <tt/gdb(1)/ to to a stack
trace on the crash dump. Of course, this depends on <tt/gdb(1)/
in -current working correctly, which I can't guarantee (I recall
somebody saying that the new ELF-ized <tt/gdb(1)/ didn't handle
kernel crash dumps correctly: somebody should check this before
3.0 goes out of beta or there'll be a lot of red faces after the
CDs ship).
<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>
In any case, the method I normally use is this:
不管是那一種,我通常是用這個方法:
<itemize>
<item>Set up a kernel config file, optionally adding 'options DDB' if you
think you need the kernel debugger for something. (I use this mainly
for setting beakpoints if I suspect an infinite loop condition of
some kind.)
<item>Use <tt/config -g KERNELCONFIG/ to set up the build directory.
<item>寫好 kernel 設定檔。如果你需要用 kernel debugger在設定
檔中加上 `options DDB' 這個選項。(當我懷疑有出現無窮迴圈時,通
常會用這個來設定中斷點。)
<item>用 <tt/config -g KERNELCONFIG/ 做出用來編譯的目錄
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
<item>Wait for kernel to finish compiling.
<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>reboot
<item>重新開機
</itemize>
<p> <em>[Note: Now that FreeBSD 3.x kernels are Elf by default,
you should use <tt/strip -g/ instead of <tt/strip -d/. If for some
reason your kernel is still a.out, use <tt/strip -aout -d/.]</em>
<p> <em>[注意:現在 FreeBSD 3.x kernel 內定是 ELF 格式,所以應該
用 <tt/strip -g/ 而不是 <tt/strip -d/。如果你的 kernel 因某種原
因仍是 a.out 格式的話,則用 <tt/strip -aout -d/。]</em>
<p> Note that YOU DO <em/NOT/ WANT TO ACTUALLY BOOT THE KERNEL
WITH ALL THE DEBUG SYMBOLS IN IT. A kernel compiled with <tt/-g/
can easily be close to 10MB in size. You don't have to actually
boot this massive image: you only need it later for <tt/gdb(1)/
(<tt/gdb(1)/ wants the symbol table). Instead, you want to keep
a copy of the full image and create a second image with the
debug symbols stripped out using <tt/strip -d/. It is this
second stripped image that you want to boot.
<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> To make sure you capture a crash dump, you need edit
<tt>/etc/rc.conf</tt> and set <tt/dumpdev/ to point to your swap
partition. This will cause the <tt/rc(8)/ scripts to use the
<tt/dumpon(8)/ command to enable crash dumps. You can also run
<tt/dumpon(8)/ manually. After a panic, the crash dump can be
recovered using <tt/savecore(8)/; if <tt/dumpdev/ is set in
<tt>/etc/rc.conf</tt>, the <tt/rc(8)/ scripts will run
<tt/savecore(8)/ automatically and put the crash dump in
<tt>/var/crash</tt>.
<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> NOTE: FreeBSD crash dumps are usually the same size as the
physical RAM size of your machine. That is, if you have 64MB of
RAM, you will get a 64MB crash dump. Therefore you must make sure
there's enough space in <tt>/var/crash</tt> to hold the dump.
Alternatively, you run <tt/savecore(8)/ manually and have it
recover the crash dump to another directory where you have more
room. It's possible to limit the size of the crash dump by using
<tt/options MAXMEM=(foo)/ to set the amount of memory the kernel
will use to something a little more sensible. For example, if
you have 128MB of RAM, you can limit the kernel's memory usage
to 16MB so that your crash dump size will be 16MB instead of
128MB.
<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> Once you have recovered the crash dump, you can get a stack
trace with <tt/gdb(1)/ as follows:
<p>一旦發現有了 crash dump就可以用 <tt/gdb(1)/ 來做 stack trace
,如下所示:
<p>
<verb>
@ -463,30 +391,94 @@ Cc: current@FreeBSD.ORG
(gdb) where
</verb>
<p> Note that there may be several screens worth of information;
ideally you should use <tt/script(1)/ to capture all of them.
Using the unstripped kernel image with all the debug symbols
should show the exact line of kernel source code where the panic
occured. Usually you have to read the stack trace from the
bottom up in order to trace the exact sequence of events that
lead to the crash. You can also use <tt/gdb(1)/ to print out the
contents of various variables or structures in order to examine
the system state at the time of the crash.
<p>要注意可能會出現好幾個螢幕的可用資訊,你可以用 <tt/script(1)/
把所有輸出都存起來。用包括所有 debug symbol 的 kernel 來除錯,
這樣應該可以直接顯示 panic 是發生在那一行。通常是由下往上讀 stack
strace這樣才能一個個追蹤出有那些動作引到 crash。也可以用
<tt/gdb(1)/ 把各種變數或結構的內容印出來,以檢查系統 crash 時的
實際狀態。
<p> Now, if you're really insane and have a second computer, you
can also configure <tt/gdb(1)/ to do remote debugging such that
you can use <tt/gdb(1)/ on one system to debug the kernel on
another system, including setting breakpoints, single-stepping
through the kernel code, just like you can do with a normal
user-mode program. I haven't played with this yet as I don't
often have the chance to set up two machines side by side for
debugging purposes.
<p>好啦,如果你有第二台電腦而且有夠瘋狂,可以將 <tt/gdb(1)/ 設定
成遠端除錯。這樣你可以在一台機器中用 <tt/gdb(1)/ 去除錯另一台裡的
kernel可以執行的包括設定中斷點、在 kernel 原始碼中一步步執行等
等,就像在一般使用者程式上除錯一樣。由於沒有什麼機會為除錯而設置
兩台並鄰電腦,所以我還沒有這樣玩過。
<p> <em>[Bill adds: "I forgot to mention one thing: if you have
DDB enabled and the kernel drops into the debugger, you can
force a panic (and a crash dump) just by typing 'panic' at the
ddb prompt. It may stop in the debugger again during the panic
phase. If it does, type 'continue' and it will finish the crash
dump." -ed]</em>
<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 MB4.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/ 設成這個值,接著將 section 列表最前面的
location counter 設成相同的值(譯注:在
<tt>src/sys/i386/conf/kernel.script</tt> 中),如下:
<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><em>[<url url="mailto:dg@freebsd.org" name="David Greenman">
加上這一段:我認為 kernel 定址空間大小應該是 2 的乘冪,但不大確
定這一點。舊的啟動程式會動到 high order address bits記得它假設
至少有 256 MB。]</em>
</sect>

File diff suppressed because it is too large Load diff

View file

@ -1,58 +1,54 @@
<!-- $Id: hackers.sgml,v 1.2 1999-03-21 16:25:40 wosch Exp $ -->
<!-- $Id: hackers.sgml,v 1.3 1999-04-21 05:26:07 foxfair Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!-- Translate into Chinese by -->
<!-- Translate into Chinese by jtjang@gcn.net.tw -->
<!-- English Version: 1.11 -->
<sect>
<heading>For serious FreeBSD hackers only<label id="hackers"></heading>
<heading>只給正經的 FreeBSD hacker 看<label id="hackers"></heading>
<sect1>
<heading>
What are SNAPs and RELEASEs?
</heading>
<heading>SNAPs 和 RELEASEs 是什麼?</heading>
<p>There are currently three active/semi-active branches in the FreeBSD
<p>目前有三個活躍/半活躍的分支在 FreeBSD 的
<url url="http://www.freebsd.org/cgi/cvsweb.cgi" name="CVS Repository">:
<itemize>
<item><bf/RELENG_2_2/ AKA <bf/2.2-stable/ AKA <bf/"2.2 branch"/
<item><bf/RELENG_3/ AKA <bf/3.x-stable/ AKA <bf/"3.0 branch"/
<item><bf/HEAD/ AKA <bf/-current/ AKA <bf/4.0-current/
<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/ is not an actual branch tag, like the other two, it's
simply a symbolic constant for
<em/"the current, non-branched development stream"/ which we simply
refer to as <bf/-current/.
<p>如同其他兩個,<bf/HEAD/ 並不是真正的 branch tag它只是一個符號
常數,指向 <em/"current尚未分支的發展中版本"/ ,簡記為
<bf/-current/。
<p>Right now, <bf/-current/ is the 4.0 development stream and the
<bf/3.0-stable/ branch, <bf/RELENG_3/, forked off from
<bf/-current/ in Jan 1999.
<p>以現在來說,<bf/-current/ 朝向 4.0 發展,而 <bf/3.0-stable/ 這
個分支,也就是 <bf/RELENG_3/,在 1999 年 1 月從 <bf/-current/ 分出
來。
<p>The <bf/2.2-stable/ branch, <bf/RELENG_2_2/, departed -current in
November 1996.
<p><bf/2.2-stable/ 這個分支,也就是 <bf/RELENG_2_2/,是在 1996 年
11 月從 -current 分出來。
<p>The <bf/2.1-stable/ branch, <bf/RELENG_2_1_0/, departed -current in
September of 1994. This branch has been fully retired.
<p><bf/2.1-stable/ 這個分支,也就是 <bf/RELENG_2_1_0/,則是在
1994 年 9 月從 -current 分支出來,這個分支已經完全退休了。
<sect1>
<heading>
How do I make my own custom release?<label id="custrel">
我要怎麼作出自己的 release<label id="custrel">
</heading>
<p>To make a release you need to do three things: First, you need to
be running a kernel with the <htmlurl
url="http://www.freebsd.org/cgi/man.cgi?vn" name="vn"> driver configured
in. Add this to your kernel config file and build a new kernel:
<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>Second, you have to have the whole CVS repository at hand.
To get this you can use <url url="../../handbook/cvsup.html" name="CVSUP">
but in your supfile set the release name to cvs and remove any tag or
date fields:
<p>接著,你手上要有整個 CVS repository。可以參考 <url
url="../handbook/cvsup.html" name="CVSUP"> 這篇文章,但在 supfile
中把 release 名稱設成 cvs再刪掉所有 tag 或 date 的欄位,如下:
<verb>
*default prefix=/home/ncvs
@ -72,12 +68,11 @@
doc-all
</verb>
<p>Then run <tt/cvsup -g supfile/ to suck all the good bits onto your
box...
<p>然後執行 <tt/cvsup -g supfile/ 把所有東西都抓下來...
<p>Finally, you need a chunk of empty space to build into. Let's
say it's in <tt>/some/big/filesystem</tt>, and from the example
above you've got the CVS repository in <tt>/home/ncvs</tt>:
<p>最後,硬碟要有相當大的空間來做 release。假設你想把它放在
<tt>/some/big/filesystem</tt> 這裡,上面這個例子也把 CVS
repository 放在 <tt>/home/ncvs</tt> 了,接著:
<verb>
setenv CVSROOT /home/ncvs # or export CVSROOT=/home/ncvs
@ -85,70 +80,59 @@
make release BUILDNAME=3.0-MY-SNAP CHROOTDIR=/some/big/filesystem/release
</verb>
<p>An entire release will be built in
<tt>/some/big/filesystem/release</tt> and you will have a full FTP-type
installation in <tt>/some/big/filesystem/release/R/ftp</tt> when you're
done. If you want to build your SNAP along some other branch than
-current, you can also add <tt/RELEASETAG=SOMETAG/ to
the make release command line above, e.g. <tt/RELEASETAG=RELENG_2_2/
would build an up-to-the- minute 2.2-STABLE snapshot.
<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>How do I create customized installation disks?</heading>
<heading>怎樣才能做出自己用的安裝磁片?</heading>
<p>The entire process of creating installation disks and source and
binary archives is automated by various targets in
<tt>/usr/src/release/Makefile</tt>. The information there should
be enough to get you started. However, it should be said that this
involves doing a ``make world'' and will therefore take up a lot of
time and disk space.
<p>建立安裝磁片、還有做出 source/binary archive都是由
<tt>/usr/src/release/Makefile</tt> 裡面的各種 target 自動產生,這
個檔案裡的資訊應該足以開始。但是這個過程牽涉到 make world所以會
用到相當多的時間和硬碟空間。
<sect1>
<heading>``make world'' clobbers my existing installed binaries.</heading>
<heading>``make world'' 把原來裝的 binary 檔都換掉了。</heading>
<p>Yes, this is the general idea; as its name might suggest,
``make world'' rebuilds every system binary from scratch, so you can be
certain of having a clean and consistent environment at the end (which
is why it takes so long).
<p>沒錯,就是這樣子。如名字所示,``make world'' 會重新編譯系統內建
的每個 binary 檔,這樣在結束時就可確定有個一致且乾淨的環境(所以要
花上好一段時間)。
<p>If the environment variable <tt/DESTDIR/ is defined while running
``<tt/make world/'' or ``<tt/make install/'', the newly-created
binaries will be deposited in a directory tree identical to the
installed one, rooted at <tt>&dollar;&lcub;DESTDIR&rcub;</tt>.
Some random combination of shared libraries modifications and
program rebuilds can cause this to fail in ``<tt/make world/'',
however.
<p>在執行 ``<tt/make world/'' 或 ``<tt/make install/'' 時,如果有
設 <tt/DESTDIR/ 這個環境變數,新產生的 binary 將會裝在
<tt>&dollar;&lcub;DESTDIR&rcub;</tt> 下的同樣目錄樹中。但在某些修
改 shared library 和重建 binary 的無特定情況下,這樣做可能會使
``<tt/make world/'' 失敗。
<sect1>
<heading>
When my system boots, it says ``(bus speed defaulted)''.
在系統開機時,出現 ``(bus speed defaulted)''。
</heading>
<p>The Adaptec 1542 SCSI host adapters allow the user to configure
their bus access speed in software. Previous versions of the
1542 driver tried to determine the fastest usable speed and set
the adapter to that. We found that this breaks some users'
systems, so you now have to define the ``<tt/TUNE&lowbar;1542/'' kernel
configuration option in order to have this take place. Using it
on those systems where it works may make your disks run faster,
but on those systems where it doesn't, your data could be
corrupted.
<p>Adaptec 1542 SCSI 卡允許使用者用軟體調整匯流排的存取速度。早
期的 1542 驅動程式試圖將它設成可用的最快速度,但後來發現在一些
機器上不能用,所以現在要在 kernel 設定中加 ``<tt/TUNE&lowbar;1542/''
這個選項來啟動這個功能。在支援的機器上用這個選項會使硬碟存取更
快,但在不支援的機器上有可能會毀掉資料。
<sect1>
<heading>
Can I follow current with limited Internet access?<label id="ctm">
我的網路連線不快,那可以跟著 current 的發展嗎?<label id="ctm">
</heading>
<p>Yes, you can do this <tt /without/ downloading the whole source tree
by using the <url url="../../handbook/ctm.html" name="CTM facility.">
<p>可以,藉著 <url url="../handbook/ctm.html" name="CTM"> 就
可以不用下傳所有的原始碼目錄樹。
<sect1>
<heading>How did you split the distribution into 240k files?</heading>
<heading>你是怎麼把發行版本中的檔案切成一個個 240k 的小檔案?</heading>
<p>Newer BSD based systems have a ``<tt/-b/'' option to split that
allows them to split files on arbitrary byte boundaries.
<p>在以 BSD 為主的較新系統中split 有個 ``<tt/-b/'' 選項,是用來
把檔案以任意數目 byte 切開。
<p>Here is an example from <tt>/usr/src/Makefile</tt>.
<p>這裡是 <tt>/usr/src/Makefile</tt> 中的一個例子:
<verb>
bin-tarball:
@ -160,166 +144,130 @@
</verb>
<sect1>
<heading>I've written a kernel extension, who do I send it to?</heading>
<heading>我在 kernel 裡加了些新功能,要把它寄給誰?</heading>
<p>Please take a look at <url url="../../handbook/contrib.html"
name="The Handbook entry on how to submit code.">
<p>請看一下 <url url="../handbook/contrib.html"
name="Handbook 中加入程式碼的部份">。
<p>And thanks for the thought!
<p>同時也感謝你的費心!
<sect1>
<heading>How are Plug N Play ISA cards detected and initialized?</heading>
<heading>ISA 的 Plug N Play 卡是怎麼偵測和初始化的?</heading>
<p>By: <url url="mailto:uhclem@nemesis.lonestar.org"
name="Frank Durda IV">
<p> <url url="mailto:uhclem@nemesis.lonestar.org"
name="Frank Durda IV"> 所寫:
<p>In a nutshell, there a few I/O ports that all of the PnP boards
respond to when the host asks if anyone is out there. So when
the PnP probe routine starts, he asks if there are any PnP boards
present, and all the PnP boards respond with their model &num; to
a I/O read of the same port, so the probe routine gets a wired-OR
``yes'' to that question. At least one bit will be on in that
reply. Then the probe code is able to cause boards with board
model IDs (assigned by Microsoft/Intel) lower than X to go
``off-line''. It then looks to see if any boards are still
responding to the query. If the answer was ``<tt/0/'', then
there are no boards with IDs above X. Now probe asks if there
are any boards below ``X''. If so, probe knows there are boards
with a model numbers below X. Probe then asks for boards greater
than X-(limit/4) to go off-line. If repeats the query. By
repeating this semi-binary search of IDs-in-range enough times,
the probing code will eventually identify all PnP boards present
in a given machine with a number of iterations that is much lower
than what 2^64 would take.
<p>簡單的說,當主機發出是否有 PnP 卡的詢問訊號時,所有的 PnP
會在幾個固定的 I/O port 作回應。所以當偵測 PnP 的程式開始時,它
會先問有沒有 PnP 卡在,接著所有 PnP 卡會在它所讀的 port 以自己
的型號 &num; 作回答,這樣偵測程式就會得到一個 wired-OR ``yes''
的數字,其中至少會有一個 bit 是打開的。然後偵測程式會要求型號
(由 Microsoft/Intel指定)小於 X 的卡``離線'',再去看是否還有卡回
答同樣的詢問,如果得到 ``<tt/0/'',就表示沒有型號大於 X 的卡。
現在程式會問是否有型號小於 X 的卡,如果有的話,程式再要型號大於
X-(limit/4) 的卡離線,然後重覆上面的動作。用這種類似 binary
search 的方法,在某範圍內找個幾次後,偵測程式最後會在機器中區分
出所有的 PnP 卡,搜尋次數也遠低於一個個找的 2^64 次。
<p>The IDs are two 32-bit fields (hence 2&circ;64) + 8 bit checksum.
The first 32 bits are a vendor identifier. They never come out
and say it, but it appears to be assumed that different types of
boards from the same vendor could have different 32-bit vendor
ids. The idea of needing 32 bits just for unique manufacturers
is a bit excessive.
<p>一張卡的 ID 由兩個 32-bit(所以上面是 2&circ;64) + 8bit 偵錯
碼組成,第一個 32 bits 是用來區分各家廠商的。這些廠商沒有出來澄
清過,但看來應假設同一家出的不同種類的卡的廠商 ID 有可能不同。
用 32 bits 只來表示不同廠商的想法實在有點過頭了。
<p>The lower 32 bits are a serial &num;, ethernet address, something
that makes this one board unique. The vendor must never produce
a second board that has the same lower 32 bits unless the upper
32 bits are also different. So you can have multiple boards of
the same type in the machine and the full 64 bits will still be
unique.
<p>第二個 32 bits 則是型號 &num、乙太網路位址、或一些使這張卡獨
特的資料。除非第一個 32 bits 不同,否則廠商不可能作出第二個 32
bit 相同的兩張卡。所以在一台機器中可以有同樣的好幾張卡,然而他們
整個 64 bits 還是會都不一樣。
<p>The 32 bit groups can never be all zero. This allows the
wired-OR to show non-zero bits during the initial binary search.
<p>這兩個 32 bit 永遠都不可能為零,這使得最開始 binary search 中
的 wired-OR 會得到一個非零數字。
<p>Once the system has identified all the board IDs present, it will
reactivate each board, one at a time (via the same I/O ports),
and find out what resources the given board needs, what interrupt
choices are available, etc. A scan is made over all the boards
to collect this information.
<p>一旦系統區分出所有卡的 ID接著會經由同樣的 port 一個個重新啟
動每張卡,接著找出已知介面卡所需的資源、有那些可以選的 interrupt
等等。所有卡都會被掃描一次,來收集這些資料。
<p>This info is then combined with info from any ECU files on the
hard disk or wired into the MLB BIOS. The ECU and BIOS PnP
support for hardware on the MLB is usually synthetic, and the
peripherals don't really do genuine PnP. However by examining
the BIOS info plus the ECU info, the probe routines can cause the
devices that are PnP to avoid those devices the probe code cannot
relocate.
<p>這些資訊接著和硬碟上的 ECU 檔案、或 MLB BIOS 裡的資料結合在一
起,通常是綜合 ECU 和 MLB 裡的 BIOS PnP 資料,這些週邊並不支援真
正的 PnP然而偵測程式在檢查 BIOS 和 ECU 資料後,它可以避免 PnP
週邊和那些偵測不到的相衝突。
<p>Then the PnP devices are visited once more and given their I/O,
DMA, IRQ and Memory-map address assignments. The devices will
then appear at those locations and remain there until the next
reboot, although there is nothing that says you can't move them
around whenever you want.
<p>接著再度拜訪這些 PnP 週邊,這次會把可用的 I/O、DMA、IRQ 和記
憶體映射的位址都指定給它們。這些週邊就會出現在所指定的地方,直到
下一次重新開機為止,不過也沒有人說不能把它們隨時移來移去。
<p>There is a lot of oversimplification above, but you should get
the general idea.
<p>上面有相當多的簡化,但你應該已經了解大致的過程。
<p>Microsoft took over some of the primary printer status ports to
do PnP, on the logic that no boards decoded those addresses for
the opposing I/O cycles. I found a genuine IBM printer board
that did decode writes of the status port during the early PnP
proposal review period, but MS said ``tough''. So they do a
write to the printer status port for setting addresses, plus that
use that address + <tt/0x800/, and a third I/O port for reading
that can be located anywhere between <tt/0x200/ and <tt/0x3ff/.
<p>Microsoft 把表示印表機狀態的幾個主要 port 拿來作 PnP他們的
邏輯是沒有一張卡會在這些地方解碼作相反的 I/O cycles。但是我找到
一款早期仍在評估 PnP 提案時的 IBM 原廠 printer board它的確去解
對這些狀態 port 的寫入資料,但是 MS ``說了就算''。所以它們的確有
對印表機狀態 port 寫入,還有讀取該位址 + <tt/0x800/、和另一個在
<tt/0x200/ 及 <tt/0x3ff/ 之間的 port。
<sect1>
<heading>Does FreeBSD support architectures other than the x86?</heading>
<heading>FreeBSD 是否有支援 x86 以外的機器架構?</heading>
<p>Several groups of people have expressed interest in working on
multi-architecture ports for FreeBSD and the FreeBSD/AXP (ALPHA)
port is one such effort which has been quite successful, now
available in 3.0 SNAPshot release form at <url
<p>有幾群人士已經表示對發展多平台 FreeBSD 的興趣,其中
FreeBSD/AXP (ALPHA) 即是其中相當成功的例子,可以在 <url
url="ftp://ftp.freebsd.org/pub/FreeBSD/alpha/"
name="ftp://ftp.freebsd.org/pub/FreeBSD/alpha">. The ALPHA
port currently runs on a growing number of ALPHA machine
types, among them the AlphaStation, AXPpci, PC164, Miata and Multia
models. This port is not yet considered a full release and won't be
until a full compliment of system installation tools and a distribution
on CDROM installation media is available, including a reasonable
number of working ports and packages.
FreeBSD/AXP should be considered BETA quality software at this
time. For status information, please join the
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>&lt;freebsd-alpha@FreeBSD.ORG&gt;</tt><ref id="mailing"
name="mailing list">.
Interest has also been expressed in a port of FreeBSD to
the SPARC architecture, join the <tt>&lt;freebsd-sparc@FreeBSD.ORG&gt;
</tt><ref id="mailing" name="mailing list"> if you are interested
in joining that project. For general discussion on new architectures,
join the <tt>&lt;freebsd-platforms@FreeBSD.ORG&gt;</tt>
<ref id="mailing" name="mailing list">.
也有人表示過將 FreeBSD SPARC 版本的興趣,如果你想參加這個計畫,
請加入 <tt>&lt;freebsd-sparc@FreeBSD.ORG&gt;
</tt><ref id="mailing" name="mailing list">。如果想要知道關於
新平台的討論,請加入 <tt>&lt;freebsd-platforms@FreeBSD.ORG&gt;</tt>
<ref id="mailing" name="mailing list">。
<sect1>
<heading>I need a major number for a device driver I've written.</heading>
<p>This depends on whether or not you plan on making the driver
publicly available. If you do, then please send us a copy of the
driver source code, plus the appropriate modifications to
<tt>files.i386</tt>, a sample configuration file entry, and the
appropriate <htmlurl url="http://www.freebsd.org/cgi/man.cgi?MAKEDEV"
name="MAKEDEV"> code to create any special files your device uses. If
you do not, or are unable to because of licensing restrictions, then
character major number 32 and block major number 8 have been reserved
specifically for this purpose; please use them. In any case, we'd
appreciate hearing about your driver on
<tt>&lt;freebsd-hackers@FreeBSD.ORG&gt;</tt>.
<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>&lt;freebsd-hackers@FreeBSD.ORG&gt;</tt> 發表驅動程式的消息。
<sect1>
<heading>Alternative layout policies for directories</heading>
<heading>關於放置目錄和檔案 inode 作法上的相異</heading>
<p>
In answer to the question of alternative layout policies for
directories, the scheme that is currently in use is unchanged
from what I wrote in 1983. I wrote that policy for the original
fast filesystem, and never revisited it. It works well at keeping
cylinder groups from filling up. As several of you have noted,
it works poorly for find. Most filesystems are created from
archives that were created by a depth first search (aka ftw).
These directories end up being striped across the cylinder groups
thus creating a worst possible senario for future depth first
searches. If one knew the total number of directories to be
created, the solution would be to create (total / fs_ncg) per
cylinder group before moving on. Obviously, one would have to
create some heuristic to guess at this number. Even using a
small fixed number like say 10 would make an order of magnitude
improvement. To differentiate restores from normal operation
(when the current algorithm is probably more sensible), you
could use the clustering of up to 10 if they were all done
within a ten second window. Anyway, my conclusion is that this
is an area ripe for experimentation.</p>
<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>Making the most of a kernel panic</heading>
<heading>如何從 kernel panic 得到最多資訊?</heading>
<p>
<em>[This section was extracted from a mail written by <url
url="mailto:wpaul@FreeBSD.ORG" name="Bill Paul"> on the
freebsd-current <ref id="mailing" name="mailing list"> by <url
url="mailto:des@FreeBSD.ORG" name="Dag-Erling Co&iuml;dan
Sm&oslash;rgrav">, who fixed a few typos and added the bracketed
comments]</em>
<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&iuml;dan Sm&oslash;rgrav"> 修正了打字錯誤、再
加上括弧裡的注解。]</em>
<p>
<verb>
@ -331,8 +279,7 @@ Cc: current@FreeBSD.ORG
</verb>
<p>
<em>[&lt;ben@rosengart.com&gt; posted the following panic
message]</em>
<em>[&lt;ben@rosengart.com&gt; 發表了下面的 panic 訊息]</em>
<verb>
> Fatal trap 12: page fault while in kernel mode
> fault virtual address = 0x40
@ -350,112 +297,93 @@ Cc: current@FreeBSD.ORG
> panic: page fault
</verb>
<p> [When] you see a message like this, it's not enough to just
reproduce it and send it in. The instruction pointer value that
I highlighted up there is important; unfortunately, it's also
configuration dependent. In other words, the value varies
depending on the exact kernel image that you're using. If you're
using a GENERIC kernel image from one of the snapshots, then
it's possible for somebody else to track down the offending
function, but if you're running a custom kernel then only
<em/you/ can tell us where the fault occured.
<p>當你看到像這樣的訊息時,只把它拷一份送上來是不夠的。我在上
面特地標明的 instruction pointer 值相當重要,不幸的是它會因設
定而不同。換句話說,這個值會跟你用的 kernel image 檔而變動。如
果是用某個 snapshot 版本的 GENERIC kernel也許其他人可以追蹤
到出問題的函式,但如果你是用自訂的 kernel那麼只有<em/你/才能
告訴我們問題出在那裡。
<p> What you should do is this:
<p>要做的事包括這些:
<itemize>
<item>Write down the instruction pointer value. Note that the
<tt/0x8:/ part at the begining is not significant in this case:
it's the <tt/0xf0xxxxxx/ part that we want.
<item>When the system reboots, do the following:
<item>把 instruction pointer 的值記下來。注意在前面的 <tt/0x8:/
在這個情況中並不重要,我們要的是 <tt/0xf0xxxxxx/。
<item>當系統重新開機後,執行這道命令:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
% nm /(造成 panic 的 kernel 檔案) | grep f0xxxxxx
</verb>
where <tt/f0xxxxxx/ is the instruction pointer value. The
odds are you will not get an exact match since the symbols
in the kernel symbol table are for the entry points of
functions and the instruction pointer address will be
somewhere inside a function, not at the start. If you don't
get an exact match, omit the last digit from the instruction
pointer value and try again, i.e.:
其中 <tt/f0xxxxxx/ 就是記下來的 instruction pointer 值。有可能
不會剛好找到完整的這個字串,這是因為 kernel symbol table 裡的各
個 symbol 只是函式的進入點,但 instruction pointer 所指的位址有
可能是在函式內的某一處,而不一定在開頭。所以如果找不到整個字串,
那麼把 instruction pointer 值的最後一個數字拿掉,再試一次:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxx
</verb>
If that doesn't yield any results, chop off another digit.
Repeat until you get some sort of output. The result will be
a possible list of functions which caused the panic. This is
a less than exact mechanism for tracking down the point of
failure, but it's better than nothing.
如果這樣也找不到,那就把另一個數字去掉再找,一直重複到找到為止,
結果是一串可能造成 panic 的函式列表。這樣比直接找到出問題的函式
來得差,但至少好過什麼都沒有。
</itemize>
<p> I see people constantly show panic messages like this but
rarely do I see someone take the time to match up the
instruction pointer with a function in the kernel symbol table.
<p>我常常看到人們顯示一大片 panic 訊息,但很少看到有人花一點時間
把 instruction pointer 和 kernel symbol table 中的函式比較一下。
<p> The best way to track down the cause of a panic is by
capturing a crash dump, then using <tt/gdb(1)/ to to a stack
trace on the crash dump. Of course, this depends on <tt/gdb(1)/
in -current working correctly, which I can't guarantee (I recall
somebody saying that the new ELF-ized <tt/gdb(1)/ didn't handle
kernel crash dumps correctly: somebody should check this before
3.0 goes out of beta or there'll be a lot of red faces after the
CDs ship).
<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>
In any case, the method I normally use is this:
不管是那一種,我通常是用這個方法:
<itemize>
<item>Set up a kernel config file, optionally adding 'options DDB' if you
think you need the kernel debugger for something. (I use this mainly
for setting beakpoints if I suspect an infinite loop condition of
some kind.)
<item>Use <tt/config -g KERNELCONFIG/ to set up the build directory.
<item>寫好 kernel 設定檔。如果你需要用 kernel debugger在設定
檔中加上 `options DDB' 這個選項。(當我懷疑有出現無窮迴圈時,通
常會用這個來設定中斷點。)
<item>用 <tt/config -g KERNELCONFIG/ 做出用來編譯的目錄
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
<item>Wait for kernel to finish compiling.
<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>reboot
<item>重新開機
</itemize>
<p> <em>[Note: Now that FreeBSD 3.x kernels are Elf by default,
you should use <tt/strip -g/ instead of <tt/strip -d/. If for some
reason your kernel is still a.out, use <tt/strip -aout -d/.]</em>
<p> <em>[注意:現在 FreeBSD 3.x kernel 內定是 ELF 格式,所以應該
用 <tt/strip -g/ 而不是 <tt/strip -d/。如果你的 kernel 因某種原
因仍是 a.out 格式的話,則用 <tt/strip -aout -d/。]</em>
<p> Note that YOU DO <em/NOT/ WANT TO ACTUALLY BOOT THE KERNEL
WITH ALL THE DEBUG SYMBOLS IN IT. A kernel compiled with <tt/-g/
can easily be close to 10MB in size. You don't have to actually
boot this massive image: you only need it later for <tt/gdb(1)/
(<tt/gdb(1)/ wants the symbol table). Instead, you want to keep
a copy of the full image and create a second image with the
debug symbols stripped out using <tt/strip -d/. It is this
second stripped image that you want to boot.
<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> To make sure you capture a crash dump, you need edit
<tt>/etc/rc.conf</tt> and set <tt/dumpdev/ to point to your swap
partition. This will cause the <tt/rc(8)/ scripts to use the
<tt/dumpon(8)/ command to enable crash dumps. You can also run
<tt/dumpon(8)/ manually. After a panic, the crash dump can be
recovered using <tt/savecore(8)/; if <tt/dumpdev/ is set in
<tt>/etc/rc.conf</tt>, the <tt/rc(8)/ scripts will run
<tt/savecore(8)/ automatically and put the crash dump in
<tt>/var/crash</tt>.
<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> NOTE: FreeBSD crash dumps are usually the same size as the
physical RAM size of your machine. That is, if you have 64MB of
RAM, you will get a 64MB crash dump. Therefore you must make sure
there's enough space in <tt>/var/crash</tt> to hold the dump.
Alternatively, you run <tt/savecore(8)/ manually and have it
recover the crash dump to another directory where you have more
room. It's possible to limit the size of the crash dump by using
<tt/options MAXMEM=(foo)/ to set the amount of memory the kernel
will use to something a little more sensible. For example, if
you have 128MB of RAM, you can limit the kernel's memory usage
to 16MB so that your crash dump size will be 16MB instead of
128MB.
<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> Once you have recovered the crash dump, you can get a stack
trace with <tt/gdb(1)/ as follows:
<p>一旦發現有了 crash dump就可以用 <tt/gdb(1)/ 來做 stack trace
,如下所示:
<p>
<verb>
@ -463,30 +391,94 @@ Cc: current@FreeBSD.ORG
(gdb) where
</verb>
<p> Note that there may be several screens worth of information;
ideally you should use <tt/script(1)/ to capture all of them.
Using the unstripped kernel image with all the debug symbols
should show the exact line of kernel source code where the panic
occured. Usually you have to read the stack trace from the
bottom up in order to trace the exact sequence of events that
lead to the crash. You can also use <tt/gdb(1)/ to print out the
contents of various variables or structures in order to examine
the system state at the time of the crash.
<p>要注意可能會出現好幾個螢幕的可用資訊,你可以用 <tt/script(1)/
把所有輸出都存起來。用包括所有 debug symbol 的 kernel 來除錯,
這樣應該可以直接顯示 panic 是發生在那一行。通常是由下往上讀 stack
strace這樣才能一個個追蹤出有那些動作引到 crash。也可以用
<tt/gdb(1)/ 把各種變數或結構的內容印出來,以檢查系統 crash 時的
實際狀態。
<p> Now, if you're really insane and have a second computer, you
can also configure <tt/gdb(1)/ to do remote debugging such that
you can use <tt/gdb(1)/ on one system to debug the kernel on
another system, including setting breakpoints, single-stepping
through the kernel code, just like you can do with a normal
user-mode program. I haven't played with this yet as I don't
often have the chance to set up two machines side by side for
debugging purposes.
<p>好啦,如果你有第二台電腦而且有夠瘋狂,可以將 <tt/gdb(1)/ 設定
成遠端除錯。這樣你可以在一台機器中用 <tt/gdb(1)/ 去除錯另一台裡的
kernel可以執行的包括設定中斷點、在 kernel 原始碼中一步步執行等
等,就像在一般使用者程式上除錯一樣。由於沒有什麼機會為除錯而設置
兩台並鄰電腦,所以我還沒有這樣玩過。
<p> <em>[Bill adds: "I forgot to mention one thing: if you have
DDB enabled and the kernel drops into the debugger, you can
force a panic (and a crash dump) just by typing 'panic' at the
ddb prompt. It may stop in the debugger again during the panic
phase. If it does, type 'continue' and it will finish the crash
dump." -ed]</em>
<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 MB4.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/ 設成這個值,接著將 section 列表最前面的
location counter 設成相同的值(譯注:在
<tt>src/sys/i386/conf/kernel.script</tt> 中),如下:
<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><em>[<url url="mailto:dg@freebsd.org" name="David Greenman">
加上這一段:我認為 kernel 定址空間大小應該是 2 的乘冪,但不大確
定這一點。舊的啟動程式會動到 high order address bits記得它假設
至少有 256 MB。]</em>
</sect>

File diff suppressed because it is too large Load diff