aboutsummaryrefslogtreecommitdiff
path: root/en_US.ISO_8859-1/books/handbook/linuxemu/chapter.sgml
blob: 0a937d5c88e4e20b4b26c752e11efe8b54721deb (plain) (blame)
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
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
<!--
     The FreeBSD Documentation Project

     $FreeBSD$
-->

<chapter id="linuxemu">
  <title>Linux Emulation</title>
  
  <para><emphasis>Contributed by &a.handy; and &a.rich;</emphasis></para>
  
  <sect1>
    <title>How to Install the Linux Emulator</title>
    
    <para>Linux emulation in FreeBSD has reached a point where it is possible
      to run a large fraction of Linux binaries in both a.out and ELF format.
      The linux emulation in the 2.1-STABLE branch is capable of running Linux
      DOOM and Mathematica; the version present in &rel.current;-RELEASE is
      vastly more capable and runs all these as well as Quake, Abuse, IDL,
      netrek for Linux and a whole host of other programs.</para>
	
    <para>There are some Linux-specific operating system features that are not
      supported on FreeBSD.  Linux binaries will not work on FreeBSD if they
      use the Linux <filename>/proc</filename> filesystem (which is different
      from the optional FreeBSD <filename>/proc</filename> filesystem) or
      i386-specific calls, such as enabling virtual 8086 mode.</para>
	
    <para>Depending on which version of FreeBSD you are running, how you get
      Linux-emulation up will vary slightly:</para>
	
    <sect2>
      <title>Installing Linux Emulation in 2.1-STABLE</title>
      
      <para>The <filename>GENERIC</filename> kernel in 2.1-STABLE is not
	configured for linux compatibility so you must reconfigure your kernel
	for it.  There are two ways to do this: 1.  linking the emulator
	statically in the kernel itself and 2.  configuring your kernel to
	dynamically load the linux loadable kernel module (LKM).</para>
	  
      <para>To enable the emulator, add the following to your configuration
	file (c.f. <filename>/sys/i386/conf/LINT</filename>):</para>

      <programlisting>
options COMPAT_LINUX</programlisting>

      <para>If you want to run doom or other applications that need shared
	memory, also add the following.</para>

      <programlisting>
options SYSVSHM</programlisting>

      <para>The linux system calls require 4.3BSD system call compatibility.
	So make sure you have the following.</para>

      <programlisting>
options "COMPAT_43"</programlisting>
	  
      <para>If you prefer to statically link the emulator in the kernel rather
	than use the loadable kernel module (LKM), then add</para>

      <programlisting>
options  LINUX</programlisting>

      <para>Then run config and install the new kernel as described in the
	<link linkend="kernelconfig">kernel configuration</link>
	section.</para>
	  
      <para>If you decide to use the LKM you must also install the loadable
	module.  A mismatch of versions between the kernel and loadable module
	can cause the kernel to crash, so the safest thing to do is to
	reinstall the LKM when you install the kernel.</para>

      <screen>&prompt.root; <userinput>cd /usr/src/lkm/linux</userinput>
&prompt.root; <userinput>make all install</userinput></screen>
	    
      <para>Once you have installed the kernel and the LKM, you can invoke
	`linux' as root to load the LKM.</para>
	    
      <screen>&prompt.root; <userinput>linux</userinput>
Linux emulator installed
Module loaded as ID 0</screen>
	    
      <para>To see whether the LKM is loaded, run
	<command>modstat</command>.</para>
	  
      <screen>&prompt.user; modstat
Type     Id Off Loadaddr Size Info     Rev
Module Name EXEC      0   3 f0baf000 0018 f0bb4000   1 linux_emulator</screen>
	    
      <para>You can cause the LKM to be loaded when the system boots in either
	of two ways.  In FreeBSD 2.2.1-RELEASE and 2.1-STABLE enable it in
	<filename>/etc/sysconfig</filename>

	<programlisting>
linux=YES</programlisting>

	by changing it from NO to YES.  FreeBSD 2.1 RELEASE and earlier do not
	have such a line and on those you will need to edit
	<filename>/etc/rc.local</filename> to add the following line.</para>
      
      <programlisting>
linux</programlisting>
    </sect2>
    
    <sect2>
      <title>Installing Linux Emulation in 2.2.2-RELEASE and later</title>
      
      <para>It is no longer necessary to specify <literal>options
	  LINUX</literal> or <literal>options COMPAT_LINUX</literal>.  Linux
	emulation is done with an LKM (&ldquo;Loadable Kernel Module&rdquo;)
	so it can be installed on the fly without having to reboot.  You will
	need the following things in your startup files, however:</para>
      
      <orderedlist>
	<listitem>
	  <para>In <filename>/etc/rc.conf</filename>, you need the following
	    line:</para>

	  <programlisting>
linux_enable=YES</programlisting>
	</listitem>
	      
	<listitem>
	  <para>This, in turn, triggers the following action in
	    <filename>/etc/rc.i386</filename>:</para>
	  
	  <programlisting>
# Start the Linux binary emulation if requested.
if [ "X${linux_enable}" = X"YES" ]; then echo -n '
        linux';               linux &gt; /dev/null 2&gt;&amp;1
fi</programlisting>
	</listitem>
      </orderedlist>
      
      <para>If you want to verify it is running, modstat will do that:</para>

      <screen>&prompt.user; modstat
Type     Id Off Loadaddr Size Info     Rev Module Name
EXEC      0   4 f09e6000 001c f09ec010   1 linux_mod</screen>
      
      <para>However, there have been reports that this fails on some
	2.2-RELEASE and later systems.  If for some reason you cannot load the
	linux LKM, then statically link the emulator in the kernel by
	adding

	<programlisting>
options  LINUX</programlisting>

	to your kernel config file.  Then run config and install the new
	kernel as described in the <link linkend="kernelconfig">kernel
	  configuration</link> section.</para>
    </sect2>
    
    <sect2>
      <title>Installing Linux Runtime Libraries</title>
      
      <sect3>
	<title>Installing using the linux_base port</title>
	
	<para>Most linux applications use shared libraries, so you are still
	  not done until you install the shared libraries.  It is possible to
	  do this by hand, however, it is vastly simpler to just grab the
	  linux_base port:</para>

	<screen>&prompt.root; <userinput>cd /usr/ports/emulators/linux_base</userinput>
&prompt.root; <userinput>make all install</userinput></screen>
	      
	<para>and you should have a working linux emulator.  Legend (and the
	  mail archives <!-- smiley -->:-) seems to hold that Linux emulation
	  works best with linux binaries linked against the ZMAGIC libraries;
	  QMAGIC libraries (such as those used in Slackware V2.0) may tend to
	  give the Linuxulator heartburn.  Also, expect some programs to
	  complain about incorrect minor versions of the system libraries.  In
	  general, however, this does not seem to be a problem.</para>
      </sect3>
      
      <sect3>
	<title>Installing libraries manually</title>
	
	<para>If you do not have the &ldquo;ports&rdquo; distribution, you can
	  install the libraries by hand instead.  You will need the Linux
	  shared libraries that the program depends on and the runtime linker.
	  Also, you will need to create a "shadow root" directory,
	  <filename>/compat/linux</filename>, for Linux libraries on your
	  FreeBSD system.  Any shared libraries opened by Linux programs run
	  under FreeBSD will look in this tree first.  So, if a Linux program
	  loads, for example, <filename>/lib/libc.so</filename>, FreeBSD will
	  first try to open <filename>/compat/linux/lib/libc.so</filename>,
	  and if that does not exist then it will try
	  <filename>/lib/libc.so</filename>.  Shared libraries should be
	  installed in the shadow tree <filename>/compat/linux/lib</filename>
	  rather than the paths that the Linux <command>ld.so</command>
	  reports.</para>
	    
	<para>FreeBSD-2.2-RELEASE and later works slightly differently with
	  respect to <filename>/compat/linux</filename>: all files, not just
	  libraries, are searched for from the &ldquo;shadow root&rdquo;
	  <filename>/compat/linux</filename>.</para>
	    
	<para>Generally, you will need to look for the shared libraries that
	  Linux  binaries depend on only the first few times that you install
	  a Linux  program on your FreeBSD system.  After a while, you will
	  have a sufficient set of Linux shared libraries on your system to be
	  able to run newly  imported Linux binaries without any extra
	  work.</para>
      </sect3>
      
      <sect3>
	<title>How to install additional shared libraries</title>
	
	<para>What if you install the <filename>linux_base</filename> port and
	  your application still complains about missing shared libraries? How
	  do you know which shared libraries Linux binaries need, and where to
	  get them? Basically, there are 2 possibilities (when following these
	  instructions: you will need to be root on your FreeBSD system to do
	  the necessary installation steps).</para>
	    
	<para>If you have access to a Linux system, see what shared libraries
	  the application needs, and copy them to your FreeBSD system.
	  Example: you have just ftp'ed the Linux binary of Doom.  Put it on
	  the Linux system you have access to, and check which shared
	  libraries it needs by running <command>ldd
	    linuxxdoom</command>:</para>
	      
	<screen>&prompt.user; <userinput>ldd linuxxdoom</userinput>
libXt.so.3 (DLL Jump 3.1) =&gt; /usr/X11/lib/libXt.so.3.1.0
libX11.so.3 (DLL Jump 3.1) =&gt; /usr/X11/lib/libX11.so.3.1.0
libc.so.4 (DLL Jump 4.5pl26) =&gt; /lib/libc.so.4.6.29</screen>
	
	<para>You would need to get all the files from the last column, and
	  put them under <filename>/compat/linux</filename>, with the names in
	  the first column as symbolic links pointing to them. This means you
	  eventually have these files on your FreeBSD system:</para>
	      
	<screen>/compat/linux/usr/X11/lib/libXt.so.3.1.0
/compat/linux/usr/X11/lib/libXt.so.3 -&gt; libXt.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3 -&gt; libX11.so.3.1.0
/compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.29</screen>
	      
	<note>
	  <para>Note that if you already have a Linux shared library with a
	    matching major revision number to the first column of the
	    <command>ldd</command> output, you will not need to copy the file
	    named in the last column to your system, the one you already have
	    should work.  It is advisable to copy the shared library anyway if
	    it is a newer version, though.  You can remove the old one, as
	    long as you make the symbolic link point to the new one.  So, if
	    you have these libraries on your system:</para>

	  <screen>/compat/linux/lib/libc.so.4.6.27
/compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.27</screen>
		
	  <para>and you find a new binary that claims to require a later
	    version according to the output of <command>ldd</command>:</para>

	  <screen>libc.so.4 (DLL Jump 4.5pl26) -&gt; libc.so.4.6.29</screen>
		
	  <para>If it is only one or two versions out of date in the in the
	    trailing digit then do not worry about copying
	    <filename>/lib/libc.so.4.6.29</filename> too, because the program
	    should work fine with the slightly older version. However, if you
	    like you can decide to replace the <filename>libc.so</filename>
	    anyway, and that should leave you with:</para>

	  <screen>/compat/linux/lib/libc.so.4.6.29
/compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.29</screen>
	</note>
	
	<note>
	  <para>The symbolic link mechanism is <emphasis>only</emphasis>
	    needed for Linux binaries.  The FreeBSD runtime linker takes care
	    of looking for matching major revision numbers itself and you do
	    not need to worry about it.</para>
	</note>
      </sect3>
      
      <sect3>
	<title>Configuring the <filename>ld.so</filename> &mdash; for FreeBSD
	  2.2-RELEASE and later</title>
	
	<para>This section applies only to FreeBSD 2.2-RELEASE and later.
	  Those running 2.1-STABLE should skip this section.</para>
	    
	<para>Finally, if you run FreeBSD 2.2-RELEASE you must make sure that
	  you have the Linux runtime linker and its config files on your
	  system.  You should copy these files from the Linux system to their
	  appropriate place on your FreeBSD system (to the
	  <filename>/compat/linux</filename> tree):</para>
	      
	<screen>/compat/linux/lib/ld.so
/compat/linux/etc/ld.so.config</screen>
	      
	<para>If you do not have access to a Linux system, you should get the
	  extra files you need from various ftp sites.  Information on where
	  to look for the various files is appended below.  For now, let us
	  assume you know where to get the files.</para>
	
	<para>Retrieve the following files (all from the same ftp site to
	  avoid any version mismatches), and install them under
	  <filename>/compat/linux</filename> (i.e.
	  <filename>/foo/bar</filename> is installed as
	  <filename>/compat/linux/foo/bar</filename>):</para>

	<screen>/sbin/ldconfig
/usr/bin/ldd
/lib/libc.so.x.y.z
/lib/ld.so</screen>
	      
	<para><command>ldconfig</command> and <command>ldd</command> do not
	  necessarily need to be under <filename>/compat/linux</filename>; you
	  can install them elsewhere in the system too.  Just make sure they
	  do not conflict with their FreeBSD counterparts.  A good idea would
	  be to install them in <filename>/usr/local/bin</filename> as
	  <command>ldconfig-linux</command> and
	  <command>ldd-linux</command>.</para>
	    
	<para>Create the file
	  <filename>/compat/linux/etc/ld.so.conf</filename>, containing the
	  directories in which the Linux runtime linker should look for shared
	  libs.  It is a plain text file, containing a directory name on each
	  line.  <filename>/lib</filename> and <filename>/usr/lib</filename>
	  are standard, you could add the following:</para>

	<programlisting>
/usr/X11/lib
/usr/local/lib</programlisting>
	    
	<para>When a linux binary opens a library such as
	  <filename>/lib/libc.so</filename> the emulator maps the name to
	  <filename>/compat/linux/lib/libc.so</filename> internally.  All
	  linux libraries should be installed under /compat/linux (e.g.
	  <filename>/compat/linux/lib/libc.so</filename>,
	  <filename>/compat/linux/usr/X11/lib/libX11.so</filename>, etc.) in
	  order for the emulator to find them.</para>
	    
	<para>Those running FreeBSD 2.2-RELEASE should run the Linux ldconfig
	  program.</para>
	      
	<screen>&prompt.root <userinput>cd /compat/linux/lib</userinput>
&prompt.root; <userinput>/compat/linux/sbin/ldconfig</userinput></screen>
	    
	<para><command>ldconfig</command> is statically linked, so it does not
	  need any shared libraries to run.  It creates the file
	  <filename>/compat/linux/etc/ld.so.cache</filename> which contains
	  the names of all the shared libraries and should be rerun to
	  recreate this file whenever you install additional shared
	  libraries.</para>
	
	<para>On 2.1-STABLE do not install
	  <filename>/compat/linux/etc/ld.so.cache</filename> or run
	  <command>ldconfig</command>; in 2.1-STABLE the syscalls are
	  implemented differently and <command>ldconfig</command> is not
	  needed or used.</para>
	    
	<para>You should now be set up for Linux binaries which only need a
	  shared libc.  You can test this by running the Linux
	  <command>ldd</command> on itself.  Supposing that you have it
	  installed as <command>ldd-linux</command>, it should produce
	  something like:</para>

	<screen>&prompt.root; <userinput>ldd-linux `which ldd-linux`</userinput>
libc.so.4 (DLL Jump 4.5pl26) =&gt; /lib/libc.so.4.6.29</screen>
	      
	<para>This being done, you are ready to install new Linux binaries.
	  Whenever you install a new Linux program, you should check if it
	  needs shared libraries, and if so, whether you have them installed
	  in the <filename>/compat/linux</filename> tree. To do this, you run
	  the Linux version <command>ldd</command> on the new program, and
	  watch its output.  <command>ldd</command> (see also the manual page
	  for &man.ldd.1;) will print a list of shared libraries
	  that the program depends on, in the form
	  <literal><replaceable>majorname</replaceable>
	    (<replaceable>jumpversion</replaceable>) =&gt;
	    <replaceable>fullname</replaceable></literal>.</para>
	    
	<para>If it prints <literal>not found</literal> instead of
	  <replaceable>fullname</replaceable> it means that you need an extra
	  library.  The library needed is shown in majorname and will be of
	  the form
	  <literal>lib<replaceable>XXXX</replaceable>.so.<replaceable>N</replaceable></literal>.
	  You will need to find a
	  <filename>lib<replaceable>XXXX</replaceable>.so.N.mm</filename> on a
	  Linux ftp site, and install it on your system.  The
	  <replaceable>XXXX</replaceable> (name) and
	  <replaceable>N</replaceable> (major revision number) should match;
	  the minor number(s) <replaceable>mm</replaceable> are less
	  important, though it is advised to take the most recent
	  version.</para>
      </sect3>
    </sect2>
    
    <sect2>
      <title>Installing Linux ELF binaries</title>
      
      <para>ELF binaries sometimes require an extra step of
	&ldquo;branding&rdquo;.  If you attempt to run an unbranded ELF
	binary, you will get an error message like the following;</para>

      <screen>&prompt.user; <userinput>./my-linux-elf-binary</userinput>
ELF binary type not known
Abort</screen>

      <para>To help the FreeBSD kernel distinguish between a FreeBSD ELF
	binary from a Linux binary, use the &man.brandelf.1; utility.</para>

      <screen>&prompt.user; <userinput>brandelf -t Linux my-linux-elf-binary</userinput></screen>
      
      <para>The GNU toolchain now places the appropriate branding information
	into ELF binaries automatically, so you should be needing to do this
	step increasingly rarely in future.</para>
    </sect2>
    
    <sect2>
      <title>Configuring the host name resolver</title>
      
      <para>If DNS does not work or you get the messages
	
	<screen>resolv+: "bind" is an invalid keyword resolv+:
"hosts" is an invalid keyword</screen>
	
	then you need to configure a
	<filename>/compat/linux/etc/host.conf</filename> file containing:

	<programlisting>
order hosts, bind
multi on</programlisting>
	  
	where the order here specifies that <filename>/etc/hosts</filename> is
	searched first and DNS is searched second.  When
	<filename>/compat/linux/etc/host.conf</filename> is not installed
	linux applications find FreeBSD's <filename>/etc/host.conf</filename>
	and complain about the incompatible FreeBSD syntax.  You should remove
	<literal>bind</literal> if you have not configured a name-server using
	the <filename>/etc/resolv.conf</filename> file.</para>
      
      <para>Lastly, those who run 2.1-STABLE need to set an the
	<envar>RESOLV_HOST_CONF</envar> environment variable so that
	applications will know how to search the host tables.  If you run
	FreeBSD 2.2-RELEASE or later, you can skip this.  For the
	<filename>/bin/csh</filename> shell use:</para>
      
      <screen>&prompt.user; <userinput>setenv RESOLV_HOST_CONF /compat/linux/etc/host.conf</userinput></screen>
	    
      <para>For <filename>/bin/sh</filename> use:</para>
      
      <screen>&prompt.user; <userinput>RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF</userinput></screen>
    </sect2>
    
    <sect2>
      <title>Finding the necessary files</title>
      
      <note>
	<para>The information below is valid as of the time this document was
	  written, but certain details such as names of ftp sites, directories
	  and distribution names may have changed by the time you read
	  this.</para>
      </note>
      
      <para>Linux is distributed by several groups that make their own set of
	binaries that they distribute.  Each distribution has its own name,
	like &ldquo;Slackware&rdquo; or &ldquo;Yggdrasil&rdquo;.  The
	distributions are available on a lot of ftp sites.  Sometimes the
	files are unpacked, and you can get the individual files you need, but
	mostly they are stored in distribution sets, usually consisting of
	subdirectories with gzipped tar files in them.  The primary ftp sites
	for the distributions are:</para>
      
      <orderedlist>
	<listitem>
	  <para>sunsite.unc.edu:/pub/Linux/distributions</para>
	</listitem>
	
	<listitem>
	  <para>tsx-11.mit.edu:/pub/linux/distributions</para>
	</listitem>
      </orderedlist>
      
      <para>Some European mirrors:</para>
      
      <orderedlist>
	<listitem>
	  <para>ftp.luth.se:/pub/linux/distributions</para>
	</listitem>
	
	<listitem>
	  <para>ftp.demon.co.uk:/pub/unix/linux</para>
	</listitem>
	
	<listitem>
	  <para>src.doc.ic.ac.uk:/packages/linux/distributions</para>
	</listitem>
      </orderedlist>
      
      <para>For simplicity, let us concentrate on Slackware here.  This
	distribution consists of a number of subdirectories, containing
	separate packages.  Normally, they are controlled by an install
	program, but you can retrieve files &ldquo;by hand&rdquo; too.  First
	of all, you will need to look in the <filename>contents</filename>
	subdir of the distribution.  You will find a lot of small text files
	here describing the contents of the separate packages.  The fastest
	way to look something up is to retrieve all the files in the contents
	subdirectory, and grep through them for the file you need.  Here is an
	example of a list of files that you might need, and in which
	contents-file you will find it by grepping through them:</para>

      <informaltable frame="none">
	<tgroup cols="2">
	  <thead>
	    <row>
	      <entry>Library</entry>
	      <entry>Package</entry>
	    </row>
	  </thead>
	  
	  <tbody>
	    <row>
	      <entry><filename>ld.so</filename></entry>
	      <entry>ldso</entry>
	    </row>

	    <row>
	      <entry><filename>ldconfig</filename></entry>
	      <entry>ldso</entry>
	    </row>

	    <row>
	      <entry><filename>ldd</filename></entry>
	      <entry>ldso</entry>
	    </row>

	    <row>
	      <entry><filename>libc.so.4</filename></entry>
	      <entry>shlibs</entry>
	    </row>

	    <row>
	      <entry><filename>libX11.so.6.0</filename></entry>
	      <entry>xf_lib</entry>
	    </row>

	    <row>
	      <entry><filename>libXt.so.6.0</filename></entry>
	      <entry>xf_lib</entry>
	    </row>

	    <row>
	      <entry><filename>libX11.so.3</filename></entry>
	      <entry>oldlibs</entry>
	    </row>

	    <row>
	      <entry><filename>libXt.so.3</filename></entry>
	      <entry>oldlibs</entry>
	    </row>
	  </tbody>
	</tgroup>
      </informaltable>
      
      <para>So, in this case, you will need the packages ldso, shlibs, xf_lib
	and oldlibs.  In each of the contents-files for these packages, look
	for a line saying <literal>PACKAGE LOCATION</literal>, it will tell
	you on which &ldquo;disk&rdquo; the package is, in our case it will
	tell us in which subdirectory we need to look.  For our example, we
	would find the following locations:</para>

      <informaltable frame="none">
	<tgroup cols="2">
	  <thead
	    <row>
	      <entry>Package</entry>
	      <entry>Location</entry>
	    </row>
	  </thead>
	  
	  <tbody>
	    <row>
	      <entry>ldso</entry>
	      <entry>diska2</entry>
	    </row>

	    <row>
	      <entry>shlibs</entry>
	      <entry>diska2</entry>
	    </row>

	    <row>
	      <entry>oldlibs</entry>
	      <entry>diskx6</entry>
	    </row>

	    <row>
	      <entry>xf_lib</entry>
	      <entry>diskx9</entry>
	    </row>
	  </tbody>
	</tgroup>
      </informaltable>
      
      <para>The locations called
	&ldquo;disk<replaceable>XX</replaceable>&rdquo; refer to the
	<filename>slakware/<replaceable>XX</replaceable></filename>
	subdirectories of the distribution, others may be found in the
	<filename>contrib</filename> subdirectory.  In this case, we could now
	retrieve the packages we need by retrieving the following files
	(relative to the root of the Slackware distribution tree):</para>
      
      <itemizedlist>
	<listitem>
	  <para><filename>slakware/a2/ldso.tgz</filename></para>
	</listitem>
	
	<listitem>
	  <para><filename>slakware/a2/shlibs.tgz</filename></para>
	</listitem>
	
	<listitem>
	  <para><filename>slakware/x6/oldlibs.tgz</filename></para>
	</listitem>
	
	<listitem>
	  <para><filename>slakware/x9/xf_lib.tgz</filename></para>
	</listitem>
      </itemizedlist>
      
      <para>Extract the files from these gzipped tarfiles in your
	<filename>/compat/linux</filename> directory (possibly omitting or
	afterwards removing files you do not need), and you are done.</para>
	  
      <para><emphasis>See also:</emphasis>
	<filename>ftp://ftp.FreeBSD.org/pub/FreeBSD/2.0.5-RELEASE/xperimnt/linux-emu/README</filename> and <filename>/usr/src/sys/i386/ibcs2/README.iBCS2</filename></para>
    </sect2>
  </sect1>
  
  <sect1 id="mathematica">
    <title>How to Install Mathematica on FreeBSD</title>
    
    <para><emphasis>Contributed by &a.rich; and &a.chuck;</emphasis></para>
    
    <para>This document shows how to install the Linux binary distribution of
      Mathematica 2.2 on FreeBSD 2.1.</para>
    
    <para>Mathematica supports Linux but not FreeBSD as it stands.  So once
      you have configured your system for Linux compatibility you have most of
      what you need to run Mathematica.</para>
    
    <para>For those who already have the student edition of Mathematica for
      DOS the cost of upgrading to the Linux version at the time this was
      written, March 1996, was &#36;45.00.  It can be ordered directly from
      Wolfram at (217) 398-6500 and paid for by credit card.</para>
	
    <sect2>
      <title>Unpacking the Mathematica distribution</title>
	  
      <para>The binaries are currently distributed by Wolfram on CDROM. The
	CDROM has about a dozen tar files, each of which is a binary
	distribution for one of the supported architectures.  The one for
	Linux is named <filename>LINUX.TAR</filename>.  You can, for example,
	unpack this into <filename>/usr/local/Mathematica</filename>:</para>
      
      <screen>&prompt.root; <userinput>cd /usr/local</userinput>
&prompt.root; <userinput>mkdir Mathematica</userinput>
&prompt.root; <userinput>cd Mathematica</userinput>
&prompt.root; <userinput>tar -xvf /cdrom/LINUX.TAR</userinput></screen>
    </sect2>
    
    <sect2>
      <title>Obtaining your Mathematica Password</title>
      
      <para>Before you can run Mathematica you will have to obtain a password
	from Wolfram that corresponds to your &ldquo;machine ID&rdquo;.</para>
	  
      <para>Once you have installed the linux compatibility runtime libraries
	and unpacked the mathematica you can obtain the &ldquo;machine
	ID&rdquo; by running the program <command>mathinfo</command> in the
	Install directory.</para>

      <screen>&prompt.root; <userinput>cd /usr/local/Mathematica/Install</userinput>
&prompt.root; <userinput>mathinfo</userinput>
LINUX: 'ioctl' fd=5, typ=0x89(), num=0x27 not implemented
richc.isdn.bcm.tmc.edu   9845-03452-90255</screen>
      
      <para>So, for example, the &ldquo;machine ID&rdquo; of
	<hostid>richc</hostid> is <literal>9845-03452-90255</literal>.  You
	can ignore the message about the ioctl that is not implemented.  It
	will not prevent Mathematica from running in any way and you can
	safely ignore it, though you will see the message every time you run
	Mathematica.</para>
	  
      <para>When you register with Wolfram, either by email, phone or fax, you
	will give them the &ldquo;machine ID&rdquo; and they will respond with
	a corresponding password consisting of groups of numbers.  You need to
	add them both along with the machine name and license number in your
	mathpass file.</para>
	  
      <para>You can do this by invoking:</para>
      
      <screen>&prompt.root; <userinput>cd /usr/local/Mathematica/Install</userinput>
&prompt.root; <userinput>math.install</userinput></screen>
	    
      <para>It will ask you to enter your license number and the Wolfram
	supplied password.  If you get them mixed up or for some reason the
	math.install fails, that is OK; you can simply edit the file
	<filename>mathpass</filename> in this same directory to correct the
	info manually.</para>
	  
      <para>After getting past the password, math.install will ask you if you
	accept the install defaults provided, or if you want to use your own.
	If you are like us and distrust all install programs, you probably
	want to specify the actual directories.  Beware. Although the
	math.install program asks you to specify directories, it will not
	create them for you, so you should perhaps have a second window open
	with another shell so that you can create them before you give them to
	the install program.  Or, if it fails, you can create the directories
	and then restart the <command>math.install</command> program.  The
	directories we chose to create beforehand and specify to
	<command>math.install</command> were:</para>

      <informaltable frame="none">
	<tgroup cols="2">
	  <tbody>
	    <row>
	      <entry><filename>/usr/local/Mathematica/bin</filename></entry>
	      <entry>for binaries</entry>
	    </row>
	    
	    <row>
	      <entry><filename>/usr/local/Mathematica/man/man1</filename></entry>
	      <entry>for man pages</entry>
	    </row>
	    
	    <row>
	      <entry>/usr/local/Mathematica/lib/X11</entry>
	      <entry>for the XKeysymb file</entry>
	    </row>
	  </tbody>
	</tgroup>
      </informaltable>
      
      <para>You can also tell it to use <filename>/tmp/math.record</filename>
	for the system record file, where it puts logs of sessions.  After
	this <command>math.install</command> will continue on to unpacking
	things and placing everything where it should go.</para>
	  
      <para>The Mathematica Notebook feature is included separately, as the X
	Front End, and you have to install it separately.  To get the X Front
	End stuff correctly installed, cd into the
	<filename>/usr/local/Mathematica/FrontEnd</filename> directory and
	execute the <command>xfe.install</command> shell script.  You will
	have to tell it where to put things, but you do not have to create any
	directories because it will use the same directories that had been
	created for math.install.  When it finishes, there should be a new
	shell script in <filename>/usr/local/Mathematica/bin</filename> called
	<filename>mathematica</filename>.</para>
	  
      <para>Lastly, you need to modify each of the shell scripts that
	Mathematica has installed.  At the beginning of every shell script in
	<filename>/usr/local/Mathematica/bin</filename> add the following
	line:</para>

      <screen>&prompt.user; <userinput>XKEYSYMDB=/usr/local/Mathematica/lib/X11/XKeysymDB; export XKEYSYMDB</userinput></screen>
	    
      <para>This tells Mathematica were to find its own
	version of the key mapping file <filename>XKeysymDB</filename>.
	Without this you will get pages of error messages about missing
	key mappings.</para>
      
      <para>On 2.1-STABLE you need to add the following as well:</para>
      
      <screen>&prompt.user; <userinput>RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF</userinput></screen>
	    
      <para>This tells Mathematica to use the linux version of host.conf.
	This file has a different syntax from FreeBSD's host.conf, so you will
	get an error message about <filename>/etc/host.conf</filename> if you
	leave this out.</para>
	  
      <para>You might also want to modify your
	<filename>/etc/manpath.config</filename> file to read the new man
	directory, and you may need to edit your <filename>~/.cshrc</filename>
	file to add <filename>/usr/local/Mathematica/bin</filename> to your
	path.</para>
	  
      <para>That is about all it takes.  With this you should be able to type
	<command>mathematica</command> and get a really slick looking
	Mathematica Notebook screen up.  Mathematica has included the Motif
	user interfaces, but it is compiled in statically, so you do not need
	the Motif libraries.  Good luck doing this yourself!</para>
    </sect2>
    
    <sect2>
      <title>Bugs</title>
      
      <para>The Notebook front end is known to hang sometimes when reading
	notebook files with an error messages similar to:</para>
	  
      <screen><errorname>File .../Untitled-1.mb appears to be broken for OMPR.257.0</errorname></screen>
	    
      <para>We have not found the cause for this, but it only affects the
	Notebook's X Window front end, not the mathematica engine itself. So
	the command line interface invoked by 'math' is unaffected by this
	bug.</para>
    </sect2>
    
    <sect2>
      <title>Acknowledgments</title>
      
      <para>A well-deserved thanks should go to &a.sos; and &a.peter; who made
	linux emulation what it is today, and Michael Smith who drove these
	two guys like dogs to get it to the point where it runs Linux binaries
	better than linux! <!-- smiley -->:-)</para>
    </sect2>
  </sect1>

  <sect1>
    <title>How does the emulation work?</title>

    <para>This section is based heavily on an e-mail written to the
      <email>chat@FreeBSD.org</email> mailing list, written by Terry Lambert
      <email>tlambert@primenet.com</email> (Message ID:
      <literal>&lt;199906020108.SAA07001@usr09.primenet.com&gt;</literal>).</para>

    <para>FreeBSD has an abstraction called an &ldquo;execution class
      loader&rdquo;.  This is a wedge into the &man.execve.2; system
      call.</para>
    
    <para>What happens is that FreeBSD has a list of loaders, instead of a
      single loader with a fallback to the <literal>#!</literal> loader for
      running any shell interpreters or shell scripts.</para>
                       
    <para>Historically, the only loader on the UNIX platform examined the
      magic number (generally the first 4 or 8 bytes of the file) to see if it
      was a binary known to the system, and if so, invoked the binary
      loader.</para>
                       
    <para>If it was not the binary type for the system, the &man.execve.2;
      call returned a failure, and the shell attempted to start executing it
      as shell commands.</para>
                       
    <para>The assumption was a default of &ldquo;whatever the current shell
      is&rdquo;.</para>
    
    <para>Later, a hack was made for &man.sh.1; to examine the first two
      characters, and if they were <literal>:\n</literal>, then it invoked the
      &man.csh.1; shell instead (I believe SCO first made this hack, but am
      willing to be corrected).</para>
                       
    <para>What FreeBSD does now is go through a list of loaders, with a
      generic <literal>#!</literal> loader that knows about interpreters as
      the characters which follow to the next whitespace next to last,
      followed by a fallback to <filename>/bin/sh</filename>.</para>
                       
    <para>For the Linux binary emulation, FreeBSD sees the magic number as an
      ELF binary (it makes no distinction between FreeBSD, Solaris, Linux, or
      any other OS which has an ELF image type, at this point).</para>
                       
    <para>The ELF loader looks for a specialized <emphasis>brand</emphasis>,
      which is a comment section in the ELF image, and which is not present on
      SVR4/Solaris ELF binaries.</para>
                       
    <para>For Linux binaries to function, they must be
      <emphasis>branded</emphasis> as type <literal>Linux</literal>; from
      &man.brandelf.1;:</para>
                       
    <screen>&prompt.root; <userinput>brandelf -t Linux file</userinput></screen>
                       
    <para>When this is done, the ELF loader will see the
      <literal>Linux</literal> brand on the file.</para>
                       
    <para>When the ELF loader sees the <literal>Linux</literal> brand, the
      loader replaces a pointer in the <literal>proc</literal>
      structure.  All system calls are indexed through this pointer (in a
      traditional UNIX system, this would be the <literal>sysent[]</literal> structure array, containing the system
      calls).  In addition, the process is flagged for special handling of the
      trap vector for the signal trampoline code, and sever other (minor)
      fixups that are handled by the Linux kernel module.</para>

    <para>The Linux system call vector contains, among other things, a list of
      <literal>sysent[]</literal> entries whose addresses reside in the kernel
      module.</para>

    <para>When a system call is called by the Linux binary, the trap code
      dereferences the system call function pointer off the
      <literal>proc</literal> structure, and gets the Linux, not the FreeBSD,
      system call entry points.</para>
                       
    <para>In addition, the Linux emulation dynamically
      <emphasis>reroots</emphasis> lookups; this is, in effect, what the
      <literal>union</literal> option to FS mounts ( <emphasis>not</emphasis>
      the unionfs!) does.  First, an attempt is made to lookup the file in the
      <filename>/compat/linux/<replaceable>original-path</replaceable></filename>
      directory, <emphasis>then</emphasis> only if that fails, the lookup is
      done in the
      <filename>/<replaceable>original-path</replaceable></filename>
      directory.  This makes sure that binaries that require other binaries
      can run (e.g., the Linux toolchain can all run under emulation).  It
      also means that the Linux binaries can load and exec FreeBSD binaries,
      if there are no corresponding Linux binaries present, and that you could
      place a &man.uname.1; command in the <filename>/compat/linux</filename>
      directory tree to ensure that the Linux binaries could not tell they
      were not running on Linux.</para>
                       
    <para>In effect, there is a Linux kernel in the FreeBSD kernel; the
      various underlying functions that implement all of the services provided
      by the kernel are identical to both the FreeBSD system call table
      entries, and the Linux system call table entries: file system
      operations, virtual memory operations, signal delivery, System V IPC,
      etc&hellip;  The only difference is that FreeBSD binaries get the FreeBSD
      <emphasis>glue</emphasis> functions, and Linux binaries get the Linux
      <emphasis>glue</emphasis> functions (most older OS's only had their own
      <emphasis>glue</emphasis> functions: addresses of functions in a static
      global <literal>sysent[]</literal> structure array, instead of addresses
      of functions dereferenced off a dynamically initialized pointer in the
      <literal>proc</literal> structure of the process making the
      call).</para>
                       
    <para>Which one is the native FreeBSD ABI?  It does not matter.  Basically
      the only difference is that (currently; this could easily be changed in
      a future release, and probably will be after this) the FreeBSD
      <emphasis>glue</emphasis> functions are statically linked into the
      kernel, and the Linux glue functions can be statically linked, or they
      can be accessed via a kernel module.</para>
                       
    <para>Yeah, but is this really emulation?  No.  It is an ABI
      implementation, not an emulation.  There is no emulator (or simulator,
      to cut off the next question) involved.</para>
    
    <para>So why is it called &ldquo;Linux emulation&rdquo;?  To make it hard
      to sell FreeBSD!  <!-- smiley -->8-).  Really, it is because the
      historical implementation was done at a time when there was really no
      word other than that to describe what was going on; saying that FreeBSD
      ran Linux binaries was not true, if you did not compile the code in or
      load a module, and there needed to be a word to describe what was being
      loaded&mdash;hence &ldquo;the Linux emulator&rdquo;.</para>
  </sect1>
</chapter>

<!-- 
     Local Variables:
     mode: sgml
     sgml-declaration: "../chapter.decl"
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     sgml-parent-document: ("../book.sgml" "part" "chapter")
     End:
-->