home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 07 / 386bsd.791 next >
Text File  |  1991-06-11  |  35KB  |  800 lines

  1. _PORTING UNIX TO THE 386: A STRIPPED-DOWN KERNEL_
  2. by William Frederick Jolitz and Lynne Greer Jolitz
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7. /* locore.s: Copyright (c) 1990,1991 William Jolitz. All rights reserved.
  8.  * Written by William Jolitz 1/90
  9.  * Redistribution and use in source and binary forms are freely permitted
  10.  * provided that the above copyright notice and attribution and date of work
  11.  * and this paragraph are duplicated in all such forms.
  12.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  13.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  14.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  15.  */
  16.  
  17. /*  [Excerpted from i386/locore.s] */
  18. #define R(s) s - KERNEL_BASE    /* relocate references until mapping enabled */
  19.  
  20. /* Per-process region virtual address space is located at the top of user 
  21.  * space, growing down to the top of the user stack [set in the "high" kernel].
  22.  * At kernel startup time, the only per-process data we need is a kernel stack,
  23.  * so we allocate SPAGES of stack pages for the purpose before calling the 
  24.  * kernel initialization code. */
  25.     .data
  26.     .globl  _boothowto, _bootdev, _cyloffset
  27.  
  28.     /* Temporary stack */
  29.     .space 128
  30. tmpstk:
  31. _boothowto: .long 0     /* bootstrap options */
  32. _bootdev:   .long 0     /* bootstrap device */
  33. _cyloffset: .long 0     /* cylinder offset of bootstrap partition */
  34.     .text
  35.     .globl  start
  36. start:  
  37.     /* arrange for a warm boot from the BIOS at some point in the future */
  38.     movw    $0x1234, 0x472
  39.     jmp 1f
  40.     .space  0x500       # skip over BIOS data areas
  41.  
  42.     /* pass parameters on stack (howto, bootdev, cyloffset) 
  43.      * note: 0(%esp) is return address of bootstrap that loaded this kernel. */
  44. 1:  movl    4(%esp), %eax
  45.     movl    %eax, R(_boothowto)
  46.     movl    8(%esp), %eax
  47.     movl    %eax, R(_bootdev)
  48.     movl    12(%esp), %eax
  49.     movl    %eax, R(_cyloffset)
  50.  
  51.    /* use temporary stack till mapping enabled to insure it falls within map */
  52.     movl    $R(tmpstk), %esp
  53.  
  54.     /* find end of kernel image */
  55.     movl    $R(_end), %ecx
  56.     addl    $NBPG-1, %ecx
  57.     andl    $~(NBPG-1), %ecx
  58.     movl    %ecx, %esi
  59.  
  60.     /* clear bss and memory for bootstrap page tables. */
  61.     movl    $R(_edata), %edi
  62.     subl    %edi, %ecx
  63.     addl    $(SPAGES+1+1+1)*NBPG, %ecx
  64.     #   stack + page directory + kernel page table + stack page table
  65.     xorl    %eax, %eax  # pattern
  66.     cld
  67.     rep
  68.     stosb
  69.  
  70.     /* Map Kernel--N.B. don't bother with making kernel text RO, as 386
  71.      * ignores R/W AND U/S bits on kernel access (only valid bit works) !
  72.      * First step - build page tables */
  73.     movl    %esi, %ecx      # this much memory,
  74.     shrl    $PGSHIFT, %ecx      # for this many ptes
  75.     movl    $PG_V, %eax     #  having these bits set,
  76.     leal    (2+SPAGES)*NBPG(%esi), %ebx #   physical address of Sysmap
  77.     movl    %ebx, R(_KPTphys)   #    in the kernel page table,
  78.     call    fillpt
  79.  
  80.     /* map proc 0's kernel stack into user page table page */
  81.     movl    $SPAGES, %ecx       # for this many ptes,
  82.     leal    1*NBPG(%esi), %eax  # physical address of stack in proc 0
  83.     orl $PG_V|PG_URKW, %eax #  having these bits set,
  84.     leal    (1+SPAGES)*NBPG(%esi), %ebx # physical address of stack pt
  85.     addl    $(ptei(_PTmap)-1)*4, %ebx
  86.     call    fillpt
  87.  
  88.     /* Construct an initial page table directory */
  89.     /* install a pde for temporary double map of bottom of VA */
  90.     leal    (SPAGES+2)*NBPG(%esi), %eax # physical address of kernel pt 
  91.     orl $PG_V, %eax
  92.     movl    %eax, (%esi)
  93.  
  94.     /* kernel pde - same contents */
  95.     leal    pdei(KERNEL_BASE)*4(%esi), %ebx # offset of pde for kernel
  96.     movl    %eax, (%ebx)
  97.  
  98.     /* install a pde recursively mapping page directory as a page table! */
  99.     movl    %esi, %eax      # phys address of ptd in proc 0
  100.     orl $PG_V, %eax
  101.     movl    %eax, pdei(_PTD)*4(%esi)
  102.  
  103.     /* install a pde to map stack for proc 0 */
  104.     leal    (SPAGES+1)*NBPG(%esi), %eax # physical address of pt in proc 0
  105.     orl $PG_V, %eax
  106.     movl    %eax, (pdei(_PTD)-1)*4(%esi) # which is where per-process maps!
  107.  
  108.     /* load base of page directory, and enable mapping */
  109.     movl    %esi, %eax      # phys address of ptd in proc 0
  110.     orl $I386_CR3PAT, %eax
  111.     movl    %eax, %cr3      # load ptd addr into mmu
  112.     movl    %cr0, %eax      # get control word
  113.     orl $0x80000001, %eax   # and let s page!
  114.     movl    %eax, %cr0      # NOW!
  115.  
  116.     /* now running mapped */
  117.     pushl   $begin          # jump to high mem!
  118.     ret
  119.  
  120.     /* now running relocated at SYSTEM where the system is linked to run */
  121. begin:
  122.     /* set up bootstrap stack */
  123.     movl    $_PTD-SPAGES*NBPG, %esp # kernel stack virtual address top
  124.     xorl    %eax, %eax      # mark end of frames with a sentinal
  125.     movl    %eax, %ebp
  126.     movl    %eax, _PTD      # clear lower address space mapping
  127.     leal    (SPAGES+3)*NBPG(%esi), %esi # skip past stack + page tables.
  128.     pushl   %esi
  129.  
  130.     /* init386(startphys) main(startphys) */
  131.     call    _init386        # wire 386 chip for unix operation
  132.     call    _main
  133.     popl    %eax
  134.  
  135.     /* find process (proc 0) to be run */
  136.     movl    _curproc, %eax
  137.     movl    P_PCB(%eax), %eax
  138.  
  139.     /* build outer stack frame */
  140.     pushl   PCB_SS(%eax)    # user ss
  141.     pushl   PCB_ESP(%eax)   # user esp
  142.     pushl   PCB_CS(%eax)    # user cs
  143.     pushl   PCB_EIP(%eax)   # user pc
  144.     movw    PCB_DS(%eax), %ds
  145.     movw    PCB_ES(%eax), %es
  146.     lret            # goto user!
  147.  
  148. /* fill in pte/pde tables */
  149. fillpt:
  150.     movl    %eax, (%ebx)    /* stuff pte */
  151.     addl    $NBPG, %eax /* increment physical address */
  152.     addl    $4, %ebx    /* next pte */
  153.     loop    fillpt
  154.     ret
  155.  
  156.  
  157.  
  158.  
  159. [LISTING TWO]
  160.  
  161. /* machdep.c: Copyright (c) 1989,1991 William Jolitz. All rights reserved.
  162.  * Written by William Jolitz 7/89
  163.  * Redistribution and use in source and binary forms are freely permitted
  164.  * provided that the above copyright notice and attribution and date of work
  165.  * and this paragraph are duplicated in all such forms.
  166.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  167.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  168.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  169.  */
  170. /* [excerpted from i386/i386/machdep.c] * /
  171. /* Initialize segments & interrupt table */
  172.  
  173. #define GNULL_SEL   0   /* Null Descriptor */
  174. #define GCODE_SEL   1   /* Kernel Code Descriptor */
  175. #define GDATA_SEL   2   /* Kernel Data Descriptor */
  176. #define GLDT_SEL    3   /* LDT - eventually one per process */
  177. #define GTGATE_SEL  4   /* Process task switch gate */
  178. #define GPANIC_SEL  5   /* Task state to consider panic from */
  179. #define GPROC0_SEL  6   /* Task state process slot zero and up */
  180. #define NGDT    GPROC0_SEL+1
  181.  
  182. union descriptor gdt[GPROC0_SEL+1];
  183.  
  184. /* interrupt descriptor table */
  185. struct gate_descriptor idt[32+16];
  186.  
  187. /* local descriptor table */
  188. union descriptor ldt[5];
  189. #define LSYS5CALLS_SEL  0   /* forced by intel BCS */
  190. #define LSYS5SIGR_SEL   1
  191. #define L43BSDCALLS_SEL 2   /* notyet */
  192. #define LUCODE_SEL  3
  193. #define LUDATA_SEL  4
  194.  
  195. /* #define  LPOSIXCALLS_SEL 5   /* notyet */
  196. struct  i386tss tss, panic_tss;
  197.  
  198. /* software prototypes -- in more palitable form */
  199. struct soft_segment_descriptor gdt_segs[] = {
  200.     /* Null Descriptor */
  201. {   0x0,            /* segment base address  */
  202.     0x0,            /* length - all address space */
  203.     0,          /* segment type */
  204.     0,          /* segment descriptor priority level */
  205.     0,          /* segment descriptor present */
  206.     0,0,
  207.     0,          /* default 32 vs 16 bit size */
  208.     0           /* limit granularity (byte/page units)*/ },
  209.     /* Code Descriptor for kernel */
  210. {   0x0,            /* segment base address  */
  211.     0xfffff,        /* length - all address space */
  212.     SDT_MEMERA,     /* segment type */
  213.     0,          /* segment descriptor priority level */
  214.     1,          /* segment descriptor present */
  215.     0,0,
  216.     1,          /* default 32 vs 16 bit size */
  217.     1           /* limit granularity (byte/page units)*/ },
  218.     /* Data Descriptor for kernel */
  219. {   0x0,            /* segment base address  */
  220.     0xfffff,        /* length - all address space */
  221.     SDT_MEMRWA,     /* segment type */
  222.     0,          /* segment descriptor priority level */
  223.     1,          /* segment descriptor present */
  224.     0,0,
  225.     1,          /* default 32 vs 16 bit size */
  226.     1           /* limit granularity (byte/page units)*/ },
  227.     /* LDT Descriptor */
  228. {   (int) ldt,          /* segment base address  */
  229.     sizeof(ldt)-1,      /* length - all address space */
  230.     SDT_SYSLDT,     /* segment type */
  231.     0,          /* segment descriptor priority level */
  232.     1,          /* segment descriptor present */
  233.     0,0,
  234.     0,          /* unused - default 32 vs 16 bit size */
  235.     0           /* limit granularity (byte/page units)*/ },
  236.     /* Null Descriptor - Placeholder */
  237. {   0x0,            /* segment base address  */
  238.     0x0,            /* length - all address space */
  239.     0,          /* segment type */
  240.     0,          /* segment descriptor priority level */
  241.     0,          /* segment descriptor present */
  242.     0,0,
  243.     0,          /* default 32 vs 16 bit size */
  244.     0           /* limit granularity (byte/page units)*/ },
  245.     /* Panic Tss Descriptor */
  246. {   (int) &panic_tss,       /* segment base address  */
  247.     sizeof(tss)-1,      /* length - all address space */
  248.     SDT_SYS386TSS,      /* segment type */
  249.     0,          /* segment descriptor priority level */
  250.     1,          /* segment descriptor present */
  251.     0,0,
  252.     0,          /* unused - default 32 vs 16 bit size */
  253.     0           /* limit granularity (byte/page units)*/ },
  254.     /* Proc 0 Tss Descriptor */
  255. {   0,          /* segment base address  */
  256.     sizeof(tss)-1,      /* length - all address space */
  257.     SDT_SYS386TSS,      /* segment type */
  258.     0,          /* segment descriptor priority level */
  259.     1,          /* segment descriptor present */
  260.     0,0,
  261.     0,          /* unused - default 32 vs 16 bit size */
  262.     0           /* limit granularity (byte/page units)*/ }};
  263. struct soft_segment_descriptor ldt_segs[] = {
  264.     /* Null Descriptor - overwritten by call gate */
  265. {   0x0,            /* segment base address  */
  266.     0x0,            /* length - all address space */
  267.     0,          /* segment type */
  268.     0,          /* segment descriptor priority level */
  269.     0,          /* segment descriptor present */
  270.     0,0,
  271.     0,          /* default 32 vs 16 bit size */
  272.     0           /* limit granularity (byte/page units)*/ },
  273.     /* Null Descriptor - overwritten by call gate */
  274. {   0x0,            /* segment base address  */
  275.     0x0,            /* length - all address space */
  276.     0,          /* segment type */
  277.     0,          /* segment descriptor priority level */
  278.     0,          /* segment descriptor present */
  279.     0,0,
  280.     0,          /* default 32 vs 16 bit size */
  281.     0           /* limit granularity (byte/page units)*/ },
  282.     /* Null Descriptor - overwritten by call gate */
  283. {   0x0,            /* segment base address  */
  284.     0x0,            /* length - all address space */
  285.     0,          /* segment type */
  286.     0,          /* segment descriptor priority level */
  287.     0,          /* segment descriptor present */
  288.     0,0,
  289.     0,          /* default 32 vs 16 bit size */
  290.     0           /* limit granularity (byte/page units)*/ },
  291.     /* Code Descriptor for user */
  292. {   0x0,            /* segment base address  */
  293.     0xfffff,        /* length - all address space */
  294.     SDT_MEMERA,     /* segment type */
  295.     SEL_UPL,        /* segment descriptor priority level */
  296.     1,          /* segment descriptor present */
  297.     0,0,
  298.     1,          /* default 32 vs 16 bit size */
  299.     1           /* limit granularity (byte/page units)*/ },
  300.     /* Data Descriptor for user */
  301. {   0x0,            /* segment base address  */
  302.     0xfffff,        /* length - all address space */
  303.     SDT_MEMRWA,     /* segment type */
  304.     SEL_UPL,        /* segment descriptor priority level */
  305.     1,          /* segment descriptor present */
  306.     0,0,
  307.     1,          /* default 32 vs 16 bit size */
  308.     1           /* limit granularity (byte/page units)*/ } };
  309. /* table descriptors - used to load tables by microp */
  310. struct region_descriptor r_gdt = {
  311.     sizeof(gdt)-1,(char *)gdt
  312. };
  313. struct region_descriptor r_idt = {
  314.     sizeof(idt)-1,(char *)idt
  315. };
  316. setidt(idx, func, typ, dpl) char *func; {
  317.     struct gate_descriptor *ip = idt + idx;
  318.     ip->gd_looffset = (int)func;
  319.     ip->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
  320.     ip->gd_stkcpy = 0;
  321.     ip->gd_xx = 0;
  322.     ip->gd_type = typ;
  323.     ip->gd_dpl = dpl;
  324.     ip->gd_p = 1;
  325.     ip->gd_hioffset = ((int)func)>>16 ;
  326. }
  327. #define IDTVEC(name)    X/**/name
  328. extern  IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
  329.     IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
  330.     IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
  331.     IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0),
  332.     IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4),
  333.     IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8),
  334.     IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12),
  335.     IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(rsvd14), IDTVEC(syscall);
  336. int lcr0(), lcr3(), rcr0(), rcr2();
  337. int _udatasel, _ucodesel, _gsel_tss;
  338. init386() { extern ssdtosd(), lgdt(), lidt(), lldt(), etext; 
  339.     int x;
  340.     unsigned biosbasemem, biosextmem;
  341.     struct gate_descriptor *gdp;
  342.     extern int sigcode,szsigcode;
  343.     struct pcb *pb = proc0.p_addr;
  344.     /* initialize console */
  345.     cninit ();
  346.     /* make gdt memory segments */
  347.     gdt_segs[GCODE_SEL].ssd_limit = btoc((int) &etext + NBPG);
  348.     gdt_segs[GPROC0_SEL].ssd_base = pb;
  349.     for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
  350.     /* make ldt memory segments */
  351.     ldt_segs[LUCODE_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
  352.     ldt_segs[LUDATA_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
  353.     /* Note. eventually want private ldts per process */
  354.     for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
  355.     /* exceptions */
  356.     setidt(0, &IDTVEC(div),  SDT_SYS386TGT, SEL_KPL);
  357.     setidt(1, &IDTVEC(dbg),  SDT_SYS386TGT, SEL_KPL);
  358.     setidt(2, &IDTVEC(nmi),  SDT_SYS386TGT, SEL_KPL);
  359.     setidt(3, &IDTVEC(bpt),  SDT_SYS386TGT, SEL_UPL);
  360.     setidt(4, &IDTVEC(ofl),  SDT_SYS386TGT, SEL_KPL);
  361.     setidt(5, &IDTVEC(bnd),  SDT_SYS386TGT, SEL_KPL);
  362.     setidt(6, &IDTVEC(ill),  SDT_SYS386TGT, SEL_KPL);
  363.     setidt(7, &IDTVEC(dna),  SDT_SYS386TGT, SEL_KPL);
  364.     setidt(8, &IDTVEC(dble),  SDT_SYS386TGT, SEL_KPL);
  365.     setidt(9, &IDTVEC(fpusegm),  SDT_SYS386TGT, SEL_KPL);
  366.     setidt(10, &IDTVEC(tss),  SDT_SYS386TGT, SEL_KPL);
  367.     setidt(11, &IDTVEC(missing),  SDT_SYS386TGT, SEL_KPL);
  368.     setidt(12, &IDTVEC(stk),  SDT_SYS386TGT, SEL_KPL);
  369.     setidt(13, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL);
  370.     setidt(14, &IDTVEC(page),  SDT_SYS386TGT, SEL_KPL);
  371.     setidt(15, &IDTVEC(rsvd),  SDT_SYS386TGT, SEL_KPL);
  372.     setidt(16, &IDTVEC(fpu),  SDT_SYS386TGT, SEL_KPL);
  373.     setidt(17, &IDTVEC(rsvd0),  SDT_SYS386TGT, SEL_KPL);
  374.     setidt(18, &IDTVEC(rsvd1),  SDT_SYS386TGT, SEL_KPL);
  375.     setidt(19, &IDTVEC(rsvd2),  SDT_SYS386TGT, SEL_KPL);
  376.     setidt(20, &IDTVEC(rsvd3),  SDT_SYS386TGT, SEL_KPL);
  377.     setidt(21, &IDTVEC(rsvd4),  SDT_SYS386TGT, SEL_KPL);
  378.     setidt(22, &IDTVEC(rsvd5),  SDT_SYS386TGT, SEL_KPL);
  379.     setidt(23, &IDTVEC(rsvd6),  SDT_SYS386TGT, SEL_KPL);
  380.     setidt(24, &IDTVEC(rsvd7),  SDT_SYS386TGT, SEL_KPL);
  381.     setidt(25, &IDTVEC(rsvd8),  SDT_SYS386TGT, SEL_KPL);
  382.     setidt(26, &IDTVEC(rsvd9),  SDT_SYS386TGT, SEL_KPL);
  383.     setidt(27, &IDTVEC(rsvd10),  SDT_SYS386TGT, SEL_KPL);
  384.     setidt(28, &IDTVEC(rsvd11),  SDT_SYS386TGT, SEL_KPL);
  385.     setidt(29, &IDTVEC(rsvd12),  SDT_SYS386TGT, SEL_KPL);
  386.     setidt(30, &IDTVEC(rsvd13),  SDT_SYS386TGT, SEL_KPL);
  387.     setidt(31, &IDTVEC(rsvd14),  SDT_SYS386TGT, SEL_KPL);
  388. #include    "isa.h"
  389. #if NISA >0
  390.     isa_defaultirq();
  391. #endif
  392.     /* load descriptor tables into 386 */
  393.     lgdt(gdt, sizeof(gdt)-1);
  394.     lidt(idt, sizeof(idt)-1);
  395.     lldt(GSEL(GLDT_SEL, SEL_KPL));
  396.     /* resolve amount of memory present so we can scale kernel PT */
  397.     maxmem = probemem();
  398.     biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8);
  399.     biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8);
  400.     if (biosbasemem == 0xffff || biosextmem == 0xffff) {
  401.         if (biosbasemem == 0xffff && maxmem > RAM_END)
  402.             maxmem = IOM_BEGIN;
  403.         if (biosextmem == 0xffff && maxmem > RAM_END)
  404.             maxmem = IOM_BEGIN;
  405.     } else if (biosextmem > 0 && biosbasemem == IOM_BEGIN/1024) {
  406.         int totbios = (biosbasemem + 0x60000 + biosextmem);
  407.         if (totbios < maxmem) maxmem = totbios;
  408.     } else  maxmem = IOM_BEGIN;
  409.     /* call pmap initialization to make new kernel address space */
  410.     pmap_bootstrap ();
  411.     /* now running on new page tables, configured,and u/iom is accessible */
  412.     /* make a initial tss so microp can get interrupt stack on syscall! */
  413.     pb->pcbtss.tss_esp0 = UPT_MIN_ADDRESS;
  414.     pb->pcbtss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
  415.     _gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
  416.     ltr(_gsel_tss);
  417.     /* make a call gate to reenter kernel with */
  418.     gdp = &ldt[LSYS5CALLS_SEL].gd;
  419.     gdp->gd_looffset = (int) &IDTVEC(syscall);
  420.     gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
  421.     gdp->gd_stkcpy = 0;
  422.     gdp->gd_type = SDT_SYS386CGT;
  423.     gdp->gd_dpl = SEL_UPL;
  424.     gdp->gd_p = 1;
  425.     gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16;
  426.     /* transfer to user mode */
  427.     _ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
  428.     _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
  429.     /* setup per-process */
  430.     bcopy(&sigcode, pb->pcb_sigc, szsigcode);
  431.     pb->pcb_flags = 0;
  432.     pb->pcb_ptd = IdlePTD;
  433. }
  434.  
  435.  
  436.  
  437.  
  438. [LISTING THREE]
  439.  
  440. /* Machine dependent constants for 386.  */
  441.  
  442. /* user map constants */
  443. #define VM_MIN_ADDRESS      ((vm_offset_t)0)
  444. #define UPT_MIN_ADDRESS     ((vm_offset_t)0xFDC00000)
  445. #define UPT_MAX_ADDRESS     ((vm_offset_t)0xFDFF7000)
  446. #define VM_MAX_ADDRESS      UPT_MAX_ADDRESS
  447.  
  448. /* kernel map constants */
  449. #define VM_MIN_KERNEL_ADDRESS   ((vm_offset_t)0xFDFF7000)
  450. #define KPT_MIN_ADDRESS     ((vm_offset_t)0xFDFF8000)
  451. #define KPT_MAX_ADDRESS     ((vm_offset_t)0xFDFFF000)
  452. #define KERNEL_BASE     0xFE000000
  453. #define VM_MAX_KERNEL_ADDRESS   ((vm_offset_t)0xFF7FF000)
  454.  
  455. /* # of kernel PT pages (initial only, can grow dynamically) */
  456. #define VM_KERNEL_PT_PAGES  ((vm_size_t)1)
  457.  
  458.  
  459.  
  460.  
  461.  
  462. [LISTING FOUR]
  463.  
  464. /* param.h: Copyright (c) 1989,1990,1991 William Jolitz. All rights reserved.
  465.  * Written by William Jolitz 6/89
  466.  * Redistribution and use in source and binary forms are freely permitted
  467.  * provided that the above copyright notice and attribution and date of work
  468.  * and this paragraph are duplicated in all such forms.
  469.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  470.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  471.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  472.  */
  473. /* Machine dependent constants for Intel 386. */
  474.  
  475. #define MACHINE "i386"
  476.  
  477. #define NBPG        4096        /* bytes/page */
  478. #define PGOFSET     (NBPG-1)    /* byte offset into page */
  479. #define PGSHIFT     12      /* LOG2(NBPG) */
  480. #define NPTEPG      (NBPG/(sizeof (struct pte)))
  481. #define NBPDR       (1024*NBPG) /* bytes/page dir */
  482. #define PDROFSET    (NBPDR-1)   /* byte offset into page dir */
  483. #define PDRSHIFT    22      /* LOG2(NBPDR) */
  484. #define KERNBASE    0xFE000000  /* start of kernel virtual */
  485. #define DEV_BSIZE   512
  486. #define DEV_BSHIFT  9       /* log2(DEV_BSIZE) */
  487. #define CLSIZE      1
  488. #define CLSIZELOG2  0
  489. #define SSIZE   1       /* initial stack size/NBPG */
  490. #define SINCR   1       /* increment of stack/NBPG */
  491. #define SPAGES  2       /* pages of kernel stack area */
  492.  
  493. /* clicks to bytes */
  494. #define ctob(x) ((x)<<PGSHIFT)
  495.  
  496. /* bytes to clicks */
  497. #define btoc(x) (((unsigned)(x)+(NBPG-1))>>PGSHIFT)
  498. #define btodb(bytes)            /* calculates (bytes / DEV_BSIZE) */ \
  499.     ((unsigned)(bytes) >> DEV_BSHIFT)
  500. #define dbtob(db)           /* calculates (db * DEV_BSIZE) */ \
  501.     ((unsigned)(db) << DEV_BSHIFT)
  502.  
  503. /* Map a ``block device block'' to a file system block. This should be device 
  504.  * dependent, and will be if we add an entry to cdevsw/bdevsw for that purpose.
  505.  * For now though just use DEV_BSIZE. */
  506. #define bdbtofsb(bn)    ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
  507.  
  508. /* Mach derived conversion macros */
  509. #define i386_round_pdr(x)   ((((unsigned)(x)) + NBPDR - 1) & ~(NBPDR-1))
  510. #define i386_trunc_pdr(x)   ((unsigned)(x) & ~(NBPDR-1))
  511. #define i386_round_page(x)  ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1))
  512. #define i386_trunc_page(x)  ((unsigned)(x) & ~(NBPG-1))
  513. #define i386_btod(x)        ((unsigned)(x) >> PDRSHIFT)
  514. #define i386_dtob(x)        ((unsigned)(x) << PDRSHIFT)
  515. #define i386_btop(x)        ((unsigned)(x) >> PGSHIFT)
  516. #define i386_ptob(x)        ((unsigned)(x) << PGSHIFT)
  517.  
  518.  
  519.  
  520.  
  521.  
  522. [LISTING FIVE]
  523.  
  524. /* param.h: Copyright (c) 1989,1990,1991 William Jolitz. All rights reserved.
  525.  * Written by William Jolitz 6/89
  526.  * Redistribution and use in source and binary forms are freely permitted
  527.  * provided that the above copyright notice and attribution and date of work
  528.  * and this paragraph are duplicated in all such forms.
  529.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  530.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  531.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  532.  */
  533. /* Machine dependent constants for Intel 386. */
  534.  
  535. #define MACHINE "i386"
  536. #define NBPG        4096        /* bytes/page */
  537. #define PGOFSET     (NBPG-1)    /* byte offset into page */
  538. #define PGSHIFT     12      /* LOG2(NBPG) */
  539. #define NPTEPG      (NBPG/(sizeof (struct pte)))
  540. #define NBPDR       (1024*NBPG) /* bytes/page dir */
  541. #define PDROFSET    (NBPDR-1)   /* byte offset into page dir */
  542. #define PDRSHIFT    22      /* LOG2(NBPDR) */
  543. #define KERNBASE    0xFE000000  /* start of kernel virtual */
  544. #define DEV_BSIZE   512
  545. #define DEV_BSHIFT  9       /* log2(DEV_BSIZE) */
  546. #define CLSIZE      1
  547. #define CLSIZELOG2  0
  548. #define SSIZE   1       /* initial stack size/NBPG */
  549. #define SINCR   1       /* increment of stack/NBPG */
  550. #define SPAGES  2       /* pages of kernel stack area */
  551.  
  552. /* clicks to bytes */
  553. #define ctob(x) ((x)<<PGSHIFT)
  554.  
  555. /* bytes to clicks */
  556. #define btoc(x) (((unsigned)(x)+(NBPG-1))>>PGSHIFT)
  557. #define btodb(bytes)            /* calculates (bytes / DEV_BSIZE) */ \
  558.     ((unsigned)(bytes) >> DEV_BSHIFT)
  559. #define dbtob(db)           /* calculates (db * DEV_BSIZE) */ \
  560.     ((unsigned)(db) << DEV_BSHIFT)
  561.  
  562. /* Map a ``block device block'' to a file system block. This should be device 
  563.  * dependent, and will be if we add an entry to cdevsw/bdevsw for that purpose.
  564.  * For now though just use DEV_BSIZE. */
  565. #define bdbtofsb(bn)    ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
  566.  
  567. /* Mach derived conversion macros */
  568. #define i386_round_pdr(x)   ((((unsigned)(x)) + NBPDR - 1) & ~(NBPDR-1))
  569. #define i386_trunc_pdr(x)   ((unsigned)(x) & ~(NBPDR-1))
  570. #define i386_round_page(x)  ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1))
  571. #define i386_trunc_page(x)  ((unsigned)(x) & ~(NBPG-1))
  572. #define i386_btod(x)        ((unsigned)(x) >> PDRSHIFT)
  573. #define i386_dtob(x)        ((unsigned)(x) << PDRSHIFT)
  574. #define i386_btop(x)        ((unsigned)(x) >> PGSHIFT)
  575. #define i386_ptob(x)        ((unsigned)(x) << PGSHIFT)
  576.  
  577.  
  578.  
  579.  
  580.  
  581. Figure 1(a):
  582.  
  583.     Minimal Kernel Breakdown (by module)
  584. vmunix: text    data    bss    module name
  585.  
  586.         1152    32      0      clock.o            
  587.         0       500     0      conf.o                 
  588.         4548    740     32     cons.o             
  589.         1508    24      0      init_main.o        
  590.         0       1212    0      init_sysent.o      
  591.         1588    28      0      kern_clock.o       
  592.         2044    12      0      kern_descrip.o     
  593.         3296    80      0      kern_exec.o        
  594.         1840    48      0      kern_exit.o        
  595.         1600    36      0      kern_fork.o        
  596.         956     0       0      kern_mman.o            
  597.         312     0       0      kern_proc.o            
  598.         1280    0       0      kern_prot.o        
  599.         1216    0       0      kern_resource.o    
  600.         3564    32      0      kern_sig.o         
  601.         684     16      0      kern_subr.o            
  602.         1808    24      0      kern_synch.o       
  603.         1864    4       0      kern_time.o        
  604.         248     0       0      kern_xxx.o             
  605.         6176    20508   0      locore.o       
  606.         5596    596     0      machdep.o          
  607.         0       148     0      param.o                
  608.         2184    84      8      subr_prf.o         
  609.         1092    72      0      subr_rmap.o        
  610.         244     0       0      subr_xxx.o             
  611.         184     72      0      swapgeneric.o          
  612.         3340    0       0      sys_generic.o      
  613.         4156    68      0      sys_inode.o        
  614.         1096    56      0      sys_process.o      
  615.         784     16      0      sys_socket.o           
  616.         2260    224     0      trap.o             
  617.         9480    516     0      tty.o              
  618.         12      204     0      tty_conf.o             
  619.         3928    4       0      tty_pty.o          
  620.         1924    0       0      tty_subr.o         
  621.         8680    1220    0      ufs_alloc.o    
  622.         3312    116     0      ufs_bio.o          
  623.         1668    0       0      ufs_bmap.o         
  624.         1248    48      0      ufs_disksubr.o     
  625.         416     0       0      ufs_fio.o              
  626.         3968    68      0      ufs_inode.o        
  627.         436     0       0      ufs_machdep.o          
  628.         2048    0       0      ufs_mount.o        
  629.         6020    220     0      ufs_namei.o        
  630.         2288    208     0      ufs_subr.o         
  631.         7100    112     0      ufs_syscalls.o     
  632.         0       620     0      ufs_tables.o           
  633.         0       152     0      vers.o                 
  634.         2280    48      0      vm_drum.o          
  635.         2964    52      0      vm_machdep.o       
  636.         4364    180     0      vm_mem.o           
  637.         8280    188     0      vm_page.o          
  638.         2056    20      0      vm_proc.o          
  639.         3060    24      0      vm_pt.o            
  640.         2788    72      0      vm_sched.o         
  641.         528     0       0      vm_subr.o              
  642.         1052    32      0      vm_sw.o            
  643.         1836    44      0      vm_swap.o          
  644.         1536    152     0      vm_swp.o           
  645.         2048    68      0      vm_text.o          
  646.         3768    1492    1024   wd.o       
  647. totals: 145708  30492   1064
  648.  
  649.  
  650.  
  651.  
  652.  
  653. Figure 1(b):
  654.  
  655.     Fully Loaded Kernel Breakdown (by module)
  656. vmunix: text    data    bss     module
  657.         0       4       0      af.o                   
  658.         592     16      0       autoconf.o            
  659.         844     0       0       clock.o               
  660.         2584    168     0       com.o                 
  661.         0       640     0       conf.o                
  662.         4096    676     40      cons.o                
  663.         540     132     0       dead_vnops.o          
  664.         1440    28      0       device_pager.o        
  665.         3180    152     48      fd.o                  
  666.         1264    140     0       fifo_vnops.o          
  667.         2812    12      0       if.o                  
  668.         2600    12      0       if_ether.o            
  669.         1056    24      18      if_ethersubr.o        
  670.         464     0       0       if_loop.o             
  671.         5044    12      12      if_ne.o               
  672.         3184    16      0       if_sl.o               
  673.         3852    12      4       if_we.o               
  674.         2844    4       0       in.o                  
  675.         356     0       0       in_cksum.o            
  676.         1684    0       0       in_pcb.o              
  677.         12      320     0       in_proto.o            
  678.         1496    12      0       init_main.o           
  679.         0       1532    0       init_sysent.o         
  680.         0       468     0       ioconf.o              
  681.         2056    68      0       ip_icmp.o             
  682.         4564    60      48      ip_input.o            
  683.         2616    0       0       ip_output.o           
  684.         1372    4       0       isa.o                 
  685.         1204    16      0       kern_acct.o           
  686.         1280    4       0       kern_clock.o          
  687.         3184    0       0       kern_descrip.o        
  688.         3176    0       0       kern_exec.o           
  689.         1424    0       0       kern_exit.o           
  690.         996     8       4       kern_fork.o           
  691.         1204    0       0       kern_kinfo.o          
  692.         1772    0       0       kern_ktrace.o         
  693.         1028    4       0       kern_lock.o           
  694.         1892    268     0       kern_malloc.o         
  695.         796     0       0       kern_physio.o         
  696.         1180    0       0       kern_proc.o           
  697.         1844    0       0       kern_prot.o           
  698.         1140    0       0       kern_resource.o       
  699.         4172    132     0       kern_sig.o            
  700.         684     0       0       kern_subr.o           
  701.         1988    4       0       kern_synch.o          
  702.         1408    4       0       kern_time.o           
  703.         264     0       0       kern_xxx.o            
  704.         7076    684     0       locore.o              
  705.         4684    192     0       machdep.o             
  706.         552     0       0       mem.o                 
  707.         708     44      4       mfs_vfsops.o          
  708.         656     132     0       mfs_vnops.o           
  709.         1600    0       0       nfs_bio.o             
  710.         1020    0       0       nfs_node.o            
  711.         21700   36      0       nfs_serv.o            
  712.         7748    152     0       nfs_socket.o          
  713.         1040    144     21672   nfs_srvcache.o        
  714.         10284   40      4       nfs_subs.o            
  715.         1956    72      80      nfs_syscalls.o        
  716.         2996    40      1       nfs_vfsops.o          
  717.         21304   424     0       nfs_vnops.o           
  718.         348     12      16      npx.o                 
  719.         0       152     0       param.o               
  720.         6308    16      0       pmap.o                
  721.         2908    4       36      radix.o               
  722.         164     8       0       raw_cb.o              
  723.         1072    36      0       raw_ip.o              
  724.         812     0       0       raw_usrreq.o          
  725.         2304    8       0       route.o               
  726.         4552    116     0       rtsock.o              
  727.         2584    60      0       slcompress.o          
  728.         2296    180     0       spec_vnops.o          
  729.         716     0       0       subr_log.o            
  730.         1764    8       0       subr_prf.o            
  731.         888     0       0       subr_rmap.o           
  732.         340     0       0       subr_xxx.o            
  733.         5456    28      0       swap_pager.o          
  734.         0       40      0       swapvmunix.o          
  735.         3344    0       0       sys_generic.o         
  736.         0       0       0       sys_machdep.o         
  737.         904     56      0       sys_process.o         
  738.         604     20      0       sys_socket.o          
  739.         228     0       0       tcp_debug.o           
  740.         5820    8       0       tcp_input.o           
  741.         1896    16      0       tcp_output.o          
  742.         1504    12      0       tcp_subr.o            
  743.         832     60      0       tcp_timer.o           
  744.         1620    8       0       tcp_usrreq.o          
  745.         2912    0       0       trap.o                
  746.         9488    316     0       tty.o                 
  747.         1864    204     0       tty_compat.o          
  748.         12      204     0       tty_conf.o            
  749.         3452    4       0       tty_pty.o             
  750.         1988    0       0       tty_subr.o            
  751.         504     0       0       tty_tty.o             
  752.         1980    36      0       udp_usrreq.o          
  753.         9644    0       0       ufs_alloc.o           
  754.         2012    0       0       ufs_bmap.o            
  755.         1424    0       0       ufs_disksubr.o        
  756.         3756    0       0       ufs_inode.o           
  757.         1668    12      0       ufs_lockf.o           
  758.         3832    4       0       ufs_lookup.o          
  759.         4572    20      0       ufs_quota.o           
  760.         732     0       0       ufs_subr.o            
  761.         0       620     0       ufs_tables.o          
  762.         3948    64      0       ufs_vfsops.o          
  763.         8264    524     0       ufs_vnops.o           
  764.         620     0       0       uipc_domain.o         
  765.         2672    64      4       uipc_mbuf.o           
  766.         8       176     0       uipc_proto.o          
  767.         6164    0       0       uipc_socket.o         
  768.         3184    24      0       uipc_socket2.o        
  769.         5520    0       0       uipc_syscalls.o       
  770.         3320    32      0       uipc_usrreq.o         
  771.         0       232     0       vers.o                
  772.         3644    0       0       vfs_bio.o             
  773.         1108    4       0       vfs_cache.o           
  774.         0       24      0       vfs_conf.o            
  775.         1776    0       0       vfs_lookup.o          
  776.         3940    44      0       vfs_subr.o            
  777.         7544    0       0       vfs_syscalls.o        
  778.         1684    20      0       vfs_vnops.o           
  779.         3524    0       0       vm_fault.o            
  780.         1964    20      0       vm_glue.o             
  781.         84      0       0       vm_init.o             
  782.         1848    0       0       vm_kern.o             
  783.         944     0       308     vm_machdep.o          
  784.         7624    16      0       vm_map.o              
  785.         384     20      0       vm_meter.o            
  786.         3196    4       0       vm_mmap.o             
  787.         3588    16      0       vm_object.o           
  788.         2500    32      0       vm_page.o             
  789.         824     8       0       vm_pageout.o          
  790.         636     20      0       vm_pager.o            
  791.         1160    0       0       vm_swap.o             
  792.         416     0       0       vm_unix.o             
  793.         304     0       0       vm_user.o             
  794.         2200    28      0       vnode_pager.o         
  795.         6176    1648    524     wd.o                  
  796.         5252    48      9       wt.o                  
  797. totals: 359636 12248 22832
  798.  
  799.  
  800.