aboutsummaryrefslogblamecommitdiff
path: root/zh_TW.Big5/FAQ/hackers.sgml
blob: 7a5071a57bf191c58975bfdf121e9c08031747de (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492











































































































































































































































































































































































































































































































                                                                                 
<!-- $Id: hackers.sgml,v 1.1.1.1 1999-01-30 23:20:34 vanilla Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!-- Translate into Chinese by -->
<!-- English Version: 1.11 -->

  <sect>
    <heading>For serious FreeBSD hackers only<label id="hackers"></heading>

    <sect1>
      <heading>
        What are SNAPs and RELEASEs?
      </heading>

      <p>There are currently three active/semi-active branches in the 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/
      </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>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>The <bf/2.2-stable/ branch, <bf/RELENG_2_2/, departed -current in
      November 1996.

      <p>The <bf/2.1-stable/ branch, <bf/RELENG_2_1_0/, departed -current in
      September of 1994.  This branch has been fully retired.

    <sect1>
      <heading>
        How do I make my own custom 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:

      <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:

      <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>Then run <tt/cvsup -g supfile/ to suck all the good bits onto your
      box...

      <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>:

      <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>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.

    <sect1>
      <heading>How do I create customized installation disks?</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.

    <sect1>
      <heading>``make world'' clobbers my existing installed binaries.</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>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.

    <sect1>
      <heading>
        When my system boots, it says ``(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.

    <sect1>
      <heading>
        Can I follow current with limited Internet access?<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.">

    <sect1>
      <heading>How did you split the distribution into 240k files?</heading>

      <p>Newer BSD based systems have a ``<tt/-b/'' option to split that
      allows them to split files on arbitrary byte boundaries.

      <p>Here is an example from <tt>/usr/src/Makefile</tt>.

      <verb>
        bin-tarball:
        (cd $&lcub;DISTDIR&rcub;; \
        tar cf - . \
        gzip --no-name -9 -c | \
        split -b 240640 - \
        $&lcub;RELEASEDIR&rcub;/tarballs/bindist/bin_tgz.)
      </verb>

    <sect1>
      <heading>I've written a kernel extension, who do I send it to?</heading>

      <p>Please take a look at <url url="../handbook/contrib.html"
      name="The Handbook entry on how to submit code.">

      <p>And thanks for the thought!

    <sect1>
      <heading>How are Plug N Play ISA cards detected and initialized?</heading>

      <p>By: <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>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>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>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>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>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>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>There is a lot of oversimplification above, but you should get
      the general idea.

      <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/.

    <sect1>
      <heading>Does FreeBSD support architectures other than the 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
      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
      <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">.

    <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>.


    <sect1>
      <heading>Alternative layout policies for directories</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>Kirk McKusick, September 1998</p>

    <sect1>
      <heading>Making the most of a 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>

      <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>[&lt;ben@rosengart.com&gt; posted the following panic
      message]</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> [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> What you should do is this:

      <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:
	  <verb>
% nm /kernel.that.caused.the.panic | 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.:
	  <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.
      </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> 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>
      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><tt>cd /sys/compile/KERNELCONFIG; make</tt>
        <item>Wait for kernel to finish compiling.
        <item><tt/cp kernel kernel.debug/
        <item><tt/strip -d kernel/
        <item><tt/mv /kernel /kernel.orig/
        <item><tt>cp kernel /</tt>
        <item>reboot
      </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> 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> 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> 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> Once you have recovered the crash dump, you can get a stack
      trace with <tt/gdb(1)/ as follows:

      <p>
      <verb>
% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
(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> 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> <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>

  </sect>