home *** CD-ROM | disk | FTP | other *** search
- _PORTING UNIX TO THE 386: A STRIPPED-DOWN KERNEL_
- by William Frederick Jolitz and Lynne Greer Jolitz
-
-
- [LISTING ONE]
-
- /* locore.s: Copyright (c) 1990,1991 William Jolitz. All rights reserved.
- * Written by William Jolitz 1/90
- * Redistribution and use in source and binary forms are freely permitted
- * provided that the above copyright notice and attribution and date of work
- * and this paragraph are duplicated in all such forms.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- /* [Excerpted from i386/locore.s] */
- #define R(s) s - KERNEL_BASE /* relocate references until mapping enabled */
-
- /* Per-process region virtual address space is located at the top of user
- * space, growing down to the top of the user stack [set in the "high" kernel].
- * At kernel startup time, the only per-process data we need is a kernel stack,
- * so we allocate SPAGES of stack pages for the purpose before calling the
- * kernel initialization code. */
- .data
- .globl _boothowto, _bootdev, _cyloffset
-
- /* Temporary stack */
- .space 128
- tmpstk:
- _boothowto: .long 0 /* bootstrap options */
- _bootdev: .long 0 /* bootstrap device */
- _cyloffset: .long 0 /* cylinder offset of bootstrap partition */
- .text
- .globl start
- start:
- /* arrange for a warm boot from the BIOS at some point in the future */
- movw $0x1234, 0x472
- jmp 1f
- .space 0x500 # skip over BIOS data areas
-
- /* pass parameters on stack (howto, bootdev, cyloffset)
- * note: 0(%esp) is return address of bootstrap that loaded this kernel. */
- 1: movl 4(%esp), %eax
- movl %eax, R(_boothowto)
- movl 8(%esp), %eax
- movl %eax, R(_bootdev)
- movl 12(%esp), %eax
- movl %eax, R(_cyloffset)
-
- /* use temporary stack till mapping enabled to insure it falls within map */
- movl $R(tmpstk), %esp
-
- /* find end of kernel image */
- movl $R(_end), %ecx
- addl $NBPG-1, %ecx
- andl $~(NBPG-1), %ecx
- movl %ecx, %esi
-
- /* clear bss and memory for bootstrap page tables. */
- movl $R(_edata), %edi
- subl %edi, %ecx
- addl $(SPAGES+1+1+1)*NBPG, %ecx
- # stack + page directory + kernel page table + stack page table
- xorl %eax, %eax # pattern
- cld
- rep
- stosb
-
- /* Map Kernel--N.B. don't bother with making kernel text RO, as 386
- * ignores R/W AND U/S bits on kernel access (only valid bit works) !
- * First step - build page tables */
- movl %esi, %ecx # this much memory,
- shrl $PGSHIFT, %ecx # for this many ptes
- movl $PG_V, %eax # having these bits set,
- leal (2+SPAGES)*NBPG(%esi), %ebx # physical address of Sysmap
- movl %ebx, R(_KPTphys) # in the kernel page table,
- call fillpt
-
- /* map proc 0's kernel stack into user page table page */
- movl $SPAGES, %ecx # for this many ptes,
- leal 1*NBPG(%esi), %eax # physical address of stack in proc 0
- orl $PG_V|PG_URKW, %eax # having these bits set,
- leal (1+SPAGES)*NBPG(%esi), %ebx # physical address of stack pt
- addl $(ptei(_PTmap)-1)*4, %ebx
- call fillpt
-
- /* Construct an initial page table directory */
- /* install a pde for temporary double map of bottom of VA */
- leal (SPAGES+2)*NBPG(%esi), %eax # physical address of kernel pt
- orl $PG_V, %eax
- movl %eax, (%esi)
-
- /* kernel pde - same contents */
- leal pdei(KERNEL_BASE)*4(%esi), %ebx # offset of pde for kernel
- movl %eax, (%ebx)
-
- /* install a pde recursively mapping page directory as a page table! */
- movl %esi, %eax # phys address of ptd in proc 0
- orl $PG_V, %eax
- movl %eax, pdei(_PTD)*4(%esi)
-
- /* install a pde to map stack for proc 0 */
- leal (SPAGES+1)*NBPG(%esi), %eax # physical address of pt in proc 0
- orl $PG_V, %eax
- movl %eax, (pdei(_PTD)-1)*4(%esi) # which is where per-process maps!
-
- /* load base of page directory, and enable mapping */
- movl %esi, %eax # phys address of ptd in proc 0
- orl $I386_CR3PAT, %eax
- movl %eax, %cr3 # load ptd addr into mmu
- movl %cr0, %eax # get control word
- orl $0x80000001, %eax # and let s page!
- movl %eax, %cr0 # NOW!
-
- /* now running mapped */
- pushl $begin # jump to high mem!
- ret
-
- /* now running relocated at SYSTEM where the system is linked to run */
- begin:
- /* set up bootstrap stack */
- movl $_PTD-SPAGES*NBPG, %esp # kernel stack virtual address top
- xorl %eax, %eax # mark end of frames with a sentinal
- movl %eax, %ebp
- movl %eax, _PTD # clear lower address space mapping
- leal (SPAGES+3)*NBPG(%esi), %esi # skip past stack + page tables.
- pushl %esi
-
- /* init386(startphys) main(startphys) */
- call _init386 # wire 386 chip for unix operation
- call _main
- popl %eax
-
- /* find process (proc 0) to be run */
- movl _curproc, %eax
- movl P_PCB(%eax), %eax
-
- /* build outer stack frame */
- pushl PCB_SS(%eax) # user ss
- pushl PCB_ESP(%eax) # user esp
- pushl PCB_CS(%eax) # user cs
- pushl PCB_EIP(%eax) # user pc
- movw PCB_DS(%eax), %ds
- movw PCB_ES(%eax), %es
- lret # goto user!
-
- /* fill in pte/pde tables */
- fillpt:
- movl %eax, (%ebx) /* stuff pte */
- addl $NBPG, %eax /* increment physical address */
- addl $4, %ebx /* next pte */
- loop fillpt
- ret
-
-
-
-
- [LISTING TWO]
-
- /* machdep.c: Copyright (c) 1989,1991 William Jolitz. All rights reserved.
- * Written by William Jolitz 7/89
- * Redistribution and use in source and binary forms are freely permitted
- * provided that the above copyright notice and attribution and date of work
- * and this paragraph are duplicated in all such forms.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
- /* [excerpted from i386/i386/machdep.c] * /
- /* Initialize segments & interrupt table */
-
- #define GNULL_SEL 0 /* Null Descriptor */
- #define GCODE_SEL 1 /* Kernel Code Descriptor */
- #define GDATA_SEL 2 /* Kernel Data Descriptor */
- #define GLDT_SEL 3 /* LDT - eventually one per process */
- #define GTGATE_SEL 4 /* Process task switch gate */
- #define GPANIC_SEL 5 /* Task state to consider panic from */
- #define GPROC0_SEL 6 /* Task state process slot zero and up */
- #define NGDT GPROC0_SEL+1
-
- union descriptor gdt[GPROC0_SEL+1];
-
- /* interrupt descriptor table */
- struct gate_descriptor idt[32+16];
-
- /* local descriptor table */
- union descriptor ldt[5];
- #define LSYS5CALLS_SEL 0 /* forced by intel BCS */
- #define LSYS5SIGR_SEL 1
- #define L43BSDCALLS_SEL 2 /* notyet */
- #define LUCODE_SEL 3
- #define LUDATA_SEL 4
-
- /* #define LPOSIXCALLS_SEL 5 /* notyet */
- struct i386tss tss, panic_tss;
-
- /* software prototypes -- in more palitable form */
- struct soft_segment_descriptor gdt_segs[] = {
- /* Null Descriptor */
- { 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0,0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Code Descriptor for kernel */
- { 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMERA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0,0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
- /* Data Descriptor for kernel */
- { 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0,0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
- /* LDT Descriptor */
- { (int) ldt, /* segment base address */
- sizeof(ldt)-1, /* length - all address space */
- SDT_SYSLDT, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0,0,
- 0, /* unused - default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Null Descriptor - Placeholder */
- { 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0,0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Panic Tss Descriptor */
- { (int) &panic_tss, /* segment base address */
- sizeof(tss)-1, /* length - all address space */
- SDT_SYS386TSS, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0,0,
- 0, /* unused - default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Proc 0 Tss Descriptor */
- { 0, /* segment base address */
- sizeof(tss)-1, /* length - all address space */
- SDT_SYS386TSS, /* segment type */
- 0, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0,0,
- 0, /* unused - default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ }};
- struct soft_segment_descriptor ldt_segs[] = {
- /* Null Descriptor - overwritten by call gate */
- { 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0,0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Null Descriptor - overwritten by call gate */
- { 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0,0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Null Descriptor - overwritten by call gate */
- { 0x0, /* segment base address */
- 0x0, /* length - all address space */
- 0, /* segment type */
- 0, /* segment descriptor priority level */
- 0, /* segment descriptor present */
- 0,0,
- 0, /* default 32 vs 16 bit size */
- 0 /* limit granularity (byte/page units)*/ },
- /* Code Descriptor for user */
- { 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMERA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0,0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ },
- /* Data Descriptor for user */
- { 0x0, /* segment base address */
- 0xfffff, /* length - all address space */
- SDT_MEMRWA, /* segment type */
- SEL_UPL, /* segment descriptor priority level */
- 1, /* segment descriptor present */
- 0,0,
- 1, /* default 32 vs 16 bit size */
- 1 /* limit granularity (byte/page units)*/ } };
- /* table descriptors - used to load tables by microp */
- struct region_descriptor r_gdt = {
- sizeof(gdt)-1,(char *)gdt
- };
- struct region_descriptor r_idt = {
- sizeof(idt)-1,(char *)idt
- };
- setidt(idx, func, typ, dpl) char *func; {
- struct gate_descriptor *ip = idt + idx;
- ip->gd_looffset = (int)func;
- ip->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
- ip->gd_stkcpy = 0;
- ip->gd_xx = 0;
- ip->gd_type = typ;
- ip->gd_dpl = dpl;
- ip->gd_p = 1;
- ip->gd_hioffset = ((int)func)>>16 ;
- }
- #define IDTVEC(name) X/**/name
- extern IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
- IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
- IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
- IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0),
- IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4),
- IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8),
- IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12),
- IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(rsvd14), IDTVEC(syscall);
- int lcr0(), lcr3(), rcr0(), rcr2();
- int _udatasel, _ucodesel, _gsel_tss;
- init386() { extern ssdtosd(), lgdt(), lidt(), lldt(), etext;
- int x;
- unsigned biosbasemem, biosextmem;
- struct gate_descriptor *gdp;
- extern int sigcode,szsigcode;
- struct pcb *pb = proc0.p_addr;
- /* initialize console */
- cninit ();
- /* make gdt memory segments */
- gdt_segs[GCODE_SEL].ssd_limit = btoc((int) &etext + NBPG);
- gdt_segs[GPROC0_SEL].ssd_base = pb;
- for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
- /* make ldt memory segments */
- ldt_segs[LUCODE_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
- ldt_segs[LUDATA_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
- /* Note. eventually want private ldts per process */
- for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
- /* exceptions */
- setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL);
- setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL);
- setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL);
- setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL);
- setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_KPL);
- setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL);
- setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL);
- setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL);
- setidt(8, &IDTVEC(dble), SDT_SYS386TGT, SEL_KPL);
- setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL);
- setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL);
- setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL);
- setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL);
- setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL);
- setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL);
- setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL);
- setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL);
- setidt(17, &IDTVEC(rsvd0), SDT_SYS386TGT, SEL_KPL);
- setidt(18, &IDTVEC(rsvd1), SDT_SYS386TGT, SEL_KPL);
- setidt(19, &IDTVEC(rsvd2), SDT_SYS386TGT, SEL_KPL);
- setidt(20, &IDTVEC(rsvd3), SDT_SYS386TGT, SEL_KPL);
- setidt(21, &IDTVEC(rsvd4), SDT_SYS386TGT, SEL_KPL);
- setidt(22, &IDTVEC(rsvd5), SDT_SYS386TGT, SEL_KPL);
- setidt(23, &IDTVEC(rsvd6), SDT_SYS386TGT, SEL_KPL);
- setidt(24, &IDTVEC(rsvd7), SDT_SYS386TGT, SEL_KPL);
- setidt(25, &IDTVEC(rsvd8), SDT_SYS386TGT, SEL_KPL);
- setidt(26, &IDTVEC(rsvd9), SDT_SYS386TGT, SEL_KPL);
- setidt(27, &IDTVEC(rsvd10), SDT_SYS386TGT, SEL_KPL);
- setidt(28, &IDTVEC(rsvd11), SDT_SYS386TGT, SEL_KPL);
- setidt(29, &IDTVEC(rsvd12), SDT_SYS386TGT, SEL_KPL);
- setidt(30, &IDTVEC(rsvd13), SDT_SYS386TGT, SEL_KPL);
- setidt(31, &IDTVEC(rsvd14), SDT_SYS386TGT, SEL_KPL);
- #include "isa.h"
- #if NISA >0
- isa_defaultirq();
- #endif
- /* load descriptor tables into 386 */
- lgdt(gdt, sizeof(gdt)-1);
- lidt(idt, sizeof(idt)-1);
- lldt(GSEL(GLDT_SEL, SEL_KPL));
- /* resolve amount of memory present so we can scale kernel PT */
- maxmem = probemem();
- biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8);
- biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8);
- if (biosbasemem == 0xffff || biosextmem == 0xffff) {
- if (biosbasemem == 0xffff && maxmem > RAM_END)
- maxmem = IOM_BEGIN;
- if (biosextmem == 0xffff && maxmem > RAM_END)
- maxmem = IOM_BEGIN;
- } else if (biosextmem > 0 && biosbasemem == IOM_BEGIN/1024) {
- int totbios = (biosbasemem + 0x60000 + biosextmem);
- if (totbios < maxmem) maxmem = totbios;
- } else maxmem = IOM_BEGIN;
- /* call pmap initialization to make new kernel address space */
- pmap_bootstrap ();
- /* now running on new page tables, configured,and u/iom is accessible */
- /* make a initial tss so microp can get interrupt stack on syscall! */
- pb->pcbtss.tss_esp0 = UPT_MIN_ADDRESS;
- pb->pcbtss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
- _gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
- ltr(_gsel_tss);
- /* make a call gate to reenter kernel with */
- gdp = &ldt[LSYS5CALLS_SEL].gd;
- gdp->gd_looffset = (int) &IDTVEC(syscall);
- gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
- gdp->gd_stkcpy = 0;
- gdp->gd_type = SDT_SYS386CGT;
- gdp->gd_dpl = SEL_UPL;
- gdp->gd_p = 1;
- gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16;
- /* transfer to user mode */
- _ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
- _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
- /* setup per-process */
- bcopy(&sigcode, pb->pcb_sigc, szsigcode);
- pb->pcb_flags = 0;
- pb->pcb_ptd = IdlePTD;
- }
-
-
-
-
- [LISTING THREE]
-
- /* Machine dependent constants for 386. */
-
- /* user map constants */
- #define VM_MIN_ADDRESS ((vm_offset_t)0)
- #define UPT_MIN_ADDRESS ((vm_offset_t)0xFDC00000)
- #define UPT_MAX_ADDRESS ((vm_offset_t)0xFDFF7000)
- #define VM_MAX_ADDRESS UPT_MAX_ADDRESS
-
- /* kernel map constants */
- #define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)0xFDFF7000)
- #define KPT_MIN_ADDRESS ((vm_offset_t)0xFDFF8000)
- #define KPT_MAX_ADDRESS ((vm_offset_t)0xFDFFF000)
- #define KERNEL_BASE 0xFE000000
- #define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)0xFF7FF000)
-
- /* # of kernel PT pages (initial only, can grow dynamically) */
- #define VM_KERNEL_PT_PAGES ((vm_size_t)1)
-
-
-
-
-
- [LISTING FOUR]
-
- /* param.h: Copyright (c) 1989,1990,1991 William Jolitz. All rights reserved.
- * Written by William Jolitz 6/89
- * Redistribution and use in source and binary forms are freely permitted
- * provided that the above copyright notice and attribution and date of work
- * and this paragraph are duplicated in all such forms.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
- /* Machine dependent constants for Intel 386. */
-
- #define MACHINE "i386"
-
- #define NBPG 4096 /* bytes/page */
- #define PGOFSET (NBPG-1) /* byte offset into page */
- #define PGSHIFT 12 /* LOG2(NBPG) */
- #define NPTEPG (NBPG/(sizeof (struct pte)))
- #define NBPDR (1024*NBPG) /* bytes/page dir */
- #define PDROFSET (NBPDR-1) /* byte offset into page dir */
- #define PDRSHIFT 22 /* LOG2(NBPDR) */
- #define KERNBASE 0xFE000000 /* start of kernel virtual */
- #define DEV_BSIZE 512
- #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
- #define CLSIZE 1
- #define CLSIZELOG2 0
- #define SSIZE 1 /* initial stack size/NBPG */
- #define SINCR 1 /* increment of stack/NBPG */
- #define SPAGES 2 /* pages of kernel stack area */
-
- /* clicks to bytes */
- #define ctob(x) ((x)<<PGSHIFT)
-
- /* bytes to clicks */
- #define btoc(x) (((unsigned)(x)+(NBPG-1))>>PGSHIFT)
- #define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \
- ((unsigned)(bytes) >> DEV_BSHIFT)
- #define dbtob(db) /* calculates (db * DEV_BSIZE) */ \
- ((unsigned)(db) << DEV_BSHIFT)
-
- /* Map a ``block device block'' to a file system block. This should be device
- * dependent, and will be if we add an entry to cdevsw/bdevsw for that purpose.
- * For now though just use DEV_BSIZE. */
- #define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
-
- /* Mach derived conversion macros */
- #define i386_round_pdr(x) ((((unsigned)(x)) + NBPDR - 1) & ~(NBPDR-1))
- #define i386_trunc_pdr(x) ((unsigned)(x) & ~(NBPDR-1))
- #define i386_round_page(x) ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1))
- #define i386_trunc_page(x) ((unsigned)(x) & ~(NBPG-1))
- #define i386_btod(x) ((unsigned)(x) >> PDRSHIFT)
- #define i386_dtob(x) ((unsigned)(x) << PDRSHIFT)
- #define i386_btop(x) ((unsigned)(x) >> PGSHIFT)
- #define i386_ptob(x) ((unsigned)(x) << PGSHIFT)
-
-
-
-
-
- [LISTING FIVE]
-
- /* param.h: Copyright (c) 1989,1990,1991 William Jolitz. All rights reserved.
- * Written by William Jolitz 6/89
- * Redistribution and use in source and binary forms are freely permitted
- * provided that the above copyright notice and attribution and date of work
- * and this paragraph are duplicated in all such forms.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
- /* Machine dependent constants for Intel 386. */
-
- #define MACHINE "i386"
- #define NBPG 4096 /* bytes/page */
- #define PGOFSET (NBPG-1) /* byte offset into page */
- #define PGSHIFT 12 /* LOG2(NBPG) */
- #define NPTEPG (NBPG/(sizeof (struct pte)))
- #define NBPDR (1024*NBPG) /* bytes/page dir */
- #define PDROFSET (NBPDR-1) /* byte offset into page dir */
- #define PDRSHIFT 22 /* LOG2(NBPDR) */
- #define KERNBASE 0xFE000000 /* start of kernel virtual */
- #define DEV_BSIZE 512
- #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
- #define CLSIZE 1
- #define CLSIZELOG2 0
- #define SSIZE 1 /* initial stack size/NBPG */
- #define SINCR 1 /* increment of stack/NBPG */
- #define SPAGES 2 /* pages of kernel stack area */
-
- /* clicks to bytes */
- #define ctob(x) ((x)<<PGSHIFT)
-
- /* bytes to clicks */
- #define btoc(x) (((unsigned)(x)+(NBPG-1))>>PGSHIFT)
- #define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \
- ((unsigned)(bytes) >> DEV_BSHIFT)
- #define dbtob(db) /* calculates (db * DEV_BSIZE) */ \
- ((unsigned)(db) << DEV_BSHIFT)
-
- /* Map a ``block device block'' to a file system block. This should be device
- * dependent, and will be if we add an entry to cdevsw/bdevsw for that purpose.
- * For now though just use DEV_BSIZE. */
- #define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
-
- /* Mach derived conversion macros */
- #define i386_round_pdr(x) ((((unsigned)(x)) + NBPDR - 1) & ~(NBPDR-1))
- #define i386_trunc_pdr(x) ((unsigned)(x) & ~(NBPDR-1))
- #define i386_round_page(x) ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1))
- #define i386_trunc_page(x) ((unsigned)(x) & ~(NBPG-1))
- #define i386_btod(x) ((unsigned)(x) >> PDRSHIFT)
- #define i386_dtob(x) ((unsigned)(x) << PDRSHIFT)
- #define i386_btop(x) ((unsigned)(x) >> PGSHIFT)
- #define i386_ptob(x) ((unsigned)(x) << PGSHIFT)
-
-
-
-
-
- Figure 1(a):
-
- Minimal Kernel Breakdown (by module)
- vmunix: text data bss module name
-
- 1152 32 0 clock.o
- 0 500 0 conf.o
- 4548 740 32 cons.o
- 1508 24 0 init_main.o
- 0 1212 0 init_sysent.o
- 1588 28 0 kern_clock.o
- 2044 12 0 kern_descrip.o
- 3296 80 0 kern_exec.o
- 1840 48 0 kern_exit.o
- 1600 36 0 kern_fork.o
- 956 0 0 kern_mman.o
- 312 0 0 kern_proc.o
- 1280 0 0 kern_prot.o
- 1216 0 0 kern_resource.o
- 3564 32 0 kern_sig.o
- 684 16 0 kern_subr.o
- 1808 24 0 kern_synch.o
- 1864 4 0 kern_time.o
- 248 0 0 kern_xxx.o
- 6176 20508 0 locore.o
- 5596 596 0 machdep.o
- 0 148 0 param.o
- 2184 84 8 subr_prf.o
- 1092 72 0 subr_rmap.o
- 244 0 0 subr_xxx.o
- 184 72 0 swapgeneric.o
- 3340 0 0 sys_generic.o
- 4156 68 0 sys_inode.o
- 1096 56 0 sys_process.o
- 784 16 0 sys_socket.o
- 2260 224 0 trap.o
- 9480 516 0 tty.o
- 12 204 0 tty_conf.o
- 3928 4 0 tty_pty.o
- 1924 0 0 tty_subr.o
- 8680 1220 0 ufs_alloc.o
- 3312 116 0 ufs_bio.o
- 1668 0 0 ufs_bmap.o
- 1248 48 0 ufs_disksubr.o
- 416 0 0 ufs_fio.o
- 3968 68 0 ufs_inode.o
- 436 0 0 ufs_machdep.o
- 2048 0 0 ufs_mount.o
- 6020 220 0 ufs_namei.o
- 2288 208 0 ufs_subr.o
- 7100 112 0 ufs_syscalls.o
- 0 620 0 ufs_tables.o
- 0 152 0 vers.o
- 2280 48 0 vm_drum.o
- 2964 52 0 vm_machdep.o
- 4364 180 0 vm_mem.o
- 8280 188 0 vm_page.o
- 2056 20 0 vm_proc.o
- 3060 24 0 vm_pt.o
- 2788 72 0 vm_sched.o
- 528 0 0 vm_subr.o
- 1052 32 0 vm_sw.o
- 1836 44 0 vm_swap.o
- 1536 152 0 vm_swp.o
- 2048 68 0 vm_text.o
- 3768 1492 1024 wd.o
- totals: 145708 30492 1064
-
-
-
-
-
- Figure 1(b):
-
- Fully Loaded Kernel Breakdown (by module)
- vmunix: text data bss module
- 0 4 0 af.o
- 592 16 0 autoconf.o
- 844 0 0 clock.o
- 2584 168 0 com.o
- 0 640 0 conf.o
- 4096 676 40 cons.o
- 540 132 0 dead_vnops.o
- 1440 28 0 device_pager.o
- 3180 152 48 fd.o
- 1264 140 0 fifo_vnops.o
- 2812 12 0 if.o
- 2600 12 0 if_ether.o
- 1056 24 18 if_ethersubr.o
- 464 0 0 if_loop.o
- 5044 12 12 if_ne.o
- 3184 16 0 if_sl.o
- 3852 12 4 if_we.o
- 2844 4 0 in.o
- 356 0 0 in_cksum.o
- 1684 0 0 in_pcb.o
- 12 320 0 in_proto.o
- 1496 12 0 init_main.o
- 0 1532 0 init_sysent.o
- 0 468 0 ioconf.o
- 2056 68 0 ip_icmp.o
- 4564 60 48 ip_input.o
- 2616 0 0 ip_output.o
- 1372 4 0 isa.o
- 1204 16 0 kern_acct.o
- 1280 4 0 kern_clock.o
- 3184 0 0 kern_descrip.o
- 3176 0 0 kern_exec.o
- 1424 0 0 kern_exit.o
- 996 8 4 kern_fork.o
- 1204 0 0 kern_kinfo.o
- 1772 0 0 kern_ktrace.o
- 1028 4 0 kern_lock.o
- 1892 268 0 kern_malloc.o
- 796 0 0 kern_physio.o
- 1180 0 0 kern_proc.o
- 1844 0 0 kern_prot.o
- 1140 0 0 kern_resource.o
- 4172 132 0 kern_sig.o
- 684 0 0 kern_subr.o
- 1988 4 0 kern_synch.o
- 1408 4 0 kern_time.o
- 264 0 0 kern_xxx.o
- 7076 684 0 locore.o
- 4684 192 0 machdep.o
- 552 0 0 mem.o
- 708 44 4 mfs_vfsops.o
- 656 132 0 mfs_vnops.o
- 1600 0 0 nfs_bio.o
- 1020 0 0 nfs_node.o
- 21700 36 0 nfs_serv.o
- 7748 152 0 nfs_socket.o
- 1040 144 21672 nfs_srvcache.o
- 10284 40 4 nfs_subs.o
- 1956 72 80 nfs_syscalls.o
- 2996 40 1 nfs_vfsops.o
- 21304 424 0 nfs_vnops.o
- 348 12 16 npx.o
- 0 152 0 param.o
- 6308 16 0 pmap.o
- 2908 4 36 radix.o
- 164 8 0 raw_cb.o
- 1072 36 0 raw_ip.o
- 812 0 0 raw_usrreq.o
- 2304 8 0 route.o
- 4552 116 0 rtsock.o
- 2584 60 0 slcompress.o
- 2296 180 0 spec_vnops.o
- 716 0 0 subr_log.o
- 1764 8 0 subr_prf.o
- 888 0 0 subr_rmap.o
- 340 0 0 subr_xxx.o
- 5456 28 0 swap_pager.o
- 0 40 0 swapvmunix.o
- 3344 0 0 sys_generic.o
- 0 0 0 sys_machdep.o
- 904 56 0 sys_process.o
- 604 20 0 sys_socket.o
- 228 0 0 tcp_debug.o
- 5820 8 0 tcp_input.o
- 1896 16 0 tcp_output.o
- 1504 12 0 tcp_subr.o
- 832 60 0 tcp_timer.o
- 1620 8 0 tcp_usrreq.o
- 2912 0 0 trap.o
- 9488 316 0 tty.o
- 1864 204 0 tty_compat.o
- 12 204 0 tty_conf.o
- 3452 4 0 tty_pty.o
- 1988 0 0 tty_subr.o
- 504 0 0 tty_tty.o
- 1980 36 0 udp_usrreq.o
- 9644 0 0 ufs_alloc.o
- 2012 0 0 ufs_bmap.o
- 1424 0 0 ufs_disksubr.o
- 3756 0 0 ufs_inode.o
- 1668 12 0 ufs_lockf.o
- 3832 4 0 ufs_lookup.o
- 4572 20 0 ufs_quota.o
- 732 0 0 ufs_subr.o
- 0 620 0 ufs_tables.o
- 3948 64 0 ufs_vfsops.o
- 8264 524 0 ufs_vnops.o
- 620 0 0 uipc_domain.o
- 2672 64 4 uipc_mbuf.o
- 8 176 0 uipc_proto.o
- 6164 0 0 uipc_socket.o
- 3184 24 0 uipc_socket2.o
- 5520 0 0 uipc_syscalls.o
- 3320 32 0 uipc_usrreq.o
- 0 232 0 vers.o
- 3644 0 0 vfs_bio.o
- 1108 4 0 vfs_cache.o
- 0 24 0 vfs_conf.o
- 1776 0 0 vfs_lookup.o
- 3940 44 0 vfs_subr.o
- 7544 0 0 vfs_syscalls.o
- 1684 20 0 vfs_vnops.o
- 3524 0 0 vm_fault.o
- 1964 20 0 vm_glue.o
- 84 0 0 vm_init.o
- 1848 0 0 vm_kern.o
- 944 0 308 vm_machdep.o
- 7624 16 0 vm_map.o
- 384 20 0 vm_meter.o
- 3196 4 0 vm_mmap.o
- 3588 16 0 vm_object.o
- 2500 32 0 vm_page.o
- 824 8 0 vm_pageout.o
- 636 20 0 vm_pager.o
- 1160 0 0 vm_swap.o
- 416 0 0 vm_unix.o
- 304 0 0 vm_user.o
- 2200 28 0 vnode_pager.o
- 6176 1648 524 wd.o
- 5252 48 9 wt.o
- totals: 359636 12248 22832
-
-