diff options
| -rw-r--r-- | bootmain.c | 57 | ||||
| -rw-r--r-- | console.c | 71 | ||||
| -rw-r--r-- | elf.h | 2 | ||||
| -rw-r--r-- | fd.c | 17 | ||||
| -rw-r--r-- | fs.c | 14 | ||||
| -rw-r--r-- | ide.c | 8 | ||||
| -rw-r--r-- | init.c | 2 | ||||
| -rw-r--r-- | ioapic.h | 68 | ||||
| -rw-r--r-- | kalloc.c | 31 | ||||
| -rw-r--r-- | lapic.c | 140 | ||||
| -rw-r--r-- | mmu.h | 4 | ||||
| -rw-r--r-- | mp.c | 44 | ||||
| -rw-r--r-- | mp.h | 171 | ||||
| -rw-r--r-- | picirq.c | 10 | ||||
| -rw-r--r-- | printf.c | 4 | ||||
| -rw-r--r-- | proc.c | 9 | ||||
| -rw-r--r-- | proc.h | 21 | ||||
| -rw-r--r-- | syscall.c | 24 | ||||
| -rw-r--r-- | trap.c | 2 | ||||
| -rw-r--r-- | traps.h | 6 | ||||
| -rwxr-xr-x | vectors.pl | 6 | ||||
| -rw-r--r-- | x86.h | 13 | 
22 files changed, 350 insertions, 374 deletions
| @@ -1,34 +1,31 @@  #include "types.h"  #include "elf.h"  #include "x86.h" - -/********************************************************************** - * This a dirt simple boot loader, whose sole job is to boot - * an elf kernel image from the first IDE hard disk. - * - * DISK LAYOUT - *  * This program(boot.S and main.c) is the bootloader.  It should - *    be stored in the first sector of the disk. - * - *  * The 2nd sector onward holds the kernel image. - * - *  * The kernel image must be in ELF format. - * - * BOOT UP STEPS - *  * when the CPU boots it loads the BIOS into memory and executes it - * - *  * the BIOS intializes devices, sets of the interrupt routines, and - *    reads the first sector of the boot device(e.g., hard-drive) - *    into memory and jumps to it. - * - *  * Assuming this boot loader is stored in the first sector of the - *    hard-drive, this code takes over... - * - *  * control starts in bootloader.S -- which sets up protected mode, - *    and a stack so C code then run, then calls cmain() - * - *  * cmain() in this file takes over, reads in the kernel and jumps to it. - **********************************************************************/ +// This a dirt simple boot loader, whose sole job is to boot +// an elf kernel image from the first IDE hard disk. +// +// DISK LAYOUT +//  * This program(boot.S and main.c) is the bootloader.  It should +//    be stored in the first sector of the disk. +// +//  * The 2nd sector onward holds the kernel image. +// +//  * The kernel image must be in ELF format. +// +// BOOT UP STEPS +//  * when the CPU boots it loads the BIOS into memory and executes it +// +//  * the BIOS intializes devices, sets of the interrupt routines, and +//    reads the first sector of the boot device(e.g., hard-drive) +//    into memory and jumps to it. +// +//  * Assuming this boot loader is stored in the first sector of the +//    hard-drive, this code takes over... +// +//  * control starts in bootloader.S -- which sets up protected mode, +//    and a stack so C code then run, then calls cmain() +// +//  * cmain() in this file takes over, reads in the kernel and jumps to it.  #define SECTSIZE  512  #define ELFHDR    ((struct elfhdr*) 0x10000) // scratch space @@ -62,7 +59,7 @@ bad:    outw(0x8A00, 0x8A00);    outw(0x8A00, 0x8E00);    while(1) -    /* do nothing */; +    ;  }  // Read 'count' bytes at 'offset' from kernel into virtual address 'va'. @@ -96,7 +93,7 @@ waitdisk(void)  {    // wait for disk reaady    while((inb(0x1F7) & 0xC0) != 0x40) -    /* do nothing */; +    ;  }  void @@ -10,11 +10,9 @@ struct spinlock console_lock;  int panicked = 0;  int use_console_lock = 0; -/* - * copy console output to parallel port, which you can tell - * .bochsrc to copy to the stdout: - * parport1: enabled=1, file="/dev/stdout" - */ +// Copy console output to parallel port, which you can tell +// .bochsrc to copy to the stdout: +//   parport1: enabled=1, file="/dev/stdout"  static void  lpt_putc(int c)  { @@ -97,9 +95,7 @@ printint(int xx, int base, int sgn)      cons_putc(buf[i]);  } -/* - * print to the console. only understands %d, %x, %p, %s. - */ +// Print to the console. only understands %d, %x, %p, %s.  void  cprintf(char *fmt, ...)  { @@ -182,10 +178,10 @@ console_write(int minor, char *buf, int n)  } -/* This is i8042reg.h + kbdreg.h from NetBSD. */ -#define KBSTATP         0x64    /* kbd controller status port(I) */ -#define KBS_DIB         0x01    /* kbd data in buffer */ -#define KBDATAP         0x60    /* kbd data port(I) */ +// This is i8042reg.h + kbdreg.h from NetBSD. +#define KBSTATP         0x64    // kbd controller status port(I) +#define KBS_DIB         0x01    // kbd data in buffer +#define KBDATAP         0x60    // kbd data port(I)  #define NO              0 @@ -241,12 +237,18 @@ static uchar normalmap[256] =    NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',  // 0x40    '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',    '2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,   // 0x50 -  [0x97] KEY_HOME,  [0x9C] '\n' /*KP_Enter*/, -  [0xB5] '/' /*KP_Div*/,  [0xC8] KEY_UP, -  [0xC9] KEY_PGUP,  [0xCB] KEY_LF, -  [0xCD] KEY_RT,    [0xCF] KEY_END, -  [0xD0] KEY_DN,    [0xD1] KEY_PGDN, -  [0xD2] KEY_INS,   [0xD3] KEY_DEL +  [0x97] KEY_HOME, +  [0x9C] '\n',      // KP_Enter +  [0xB5] '/',       // KP_Div +  [0xC8] KEY_UP, +  [0xC9] KEY_PGUP, +  [0xCB] KEY_LF, +  [0xCD] KEY_RT, +  [0xCF] KEY_END, +  [0xD0] KEY_DN, +  [0xD1] KEY_PGDN, +  [0xD2] KEY_INS, +  [0xD3] KEY_DEL  };  static uchar shiftmap[256] = @@ -262,12 +264,18 @@ static uchar shiftmap[256] =    NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',  // 0x40    '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',    '2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,   // 0x50 -  [0x97] KEY_HOME,  [0x9C] '\n' /*KP_Enter*/, -  [0xB5] '/' /*KP_Div*/,  [0xC8] KEY_UP, -  [0xC9] KEY_PGUP,  [0xCB] KEY_LF, -  [0xCD] KEY_RT,    [0xCF] KEY_END, -  [0xD0] KEY_DN,    [0xD1] KEY_PGDN, -  [0xD2] KEY_INS,   [0xD3] KEY_DEL +  [0x97] KEY_HOME, +  [0x9C] '\n',      // KP_Enter +  [0xB5] '/',       // KP_Div +  [0xC8] KEY_UP, +  [0xC9] KEY_PGUP, +  [0xCB] KEY_LF, +  [0xCD] KEY_RT, +  [0xCF] KEY_END, +  [0xD0] KEY_DN, +  [0xD1] KEY_PGDN, +  [0xD2] KEY_INS, +  [0xD3] KEY_DEL  };  #define C(x) (x - '@') @@ -282,11 +290,16 @@ static uchar ctlmap[256] =    NO,      NO,      NO,      C('\\'), C('Z'),  C('X'),  C('C'),  C('V'),    C('B'),  C('N'),  C('M'),  NO,      NO,      C('/'),  NO,      NO,    [0x97] KEY_HOME, -  [0xB5] C('/'),    [0xC8] KEY_UP, -  [0xC9] KEY_PGUP,  [0xCB] KEY_LF, -  [0xCD] KEY_RT,    [0xCF] KEY_END, -  [0xD0] KEY_DN,    [0xD1] KEY_PGDN, -  [0xD2] KEY_INS,   [0xD3] KEY_DEL +  [0xB5] C('/'),    // KP_Div +  [0xC8] KEY_UP, +  [0xC9] KEY_PGUP, +  [0xCB] KEY_LF, +  [0xCD] KEY_RT, +  [0xCF] KEY_END, +  [0xD0] KEY_DN, +  [0xD1] KEY_PGDN, +  [0xD2] KEY_INS, +  [0xD3] KEY_DEL  };  static uchar *charcode[4] = { @@ -2,7 +2,7 @@  // format of an ELF executable file  // -#define ELF_MAGIC 0x464C457FU	/* "\x7FELF" in little endian */ +#define ELF_MAGIC 0x464C457FU	// "\x7FELF" in little endian  struct elfhdr {    uint magic;  // must equal ELF_MAGIC @@ -22,9 +22,7 @@ fd_init(void)    initlock(&fd_table_lock, "fd_table");  } -/* - * allocate a file descriptor number for curproc. - */ +// Allocate a file descriptor number for curproc.  int  fd_ualloc(void)  { @@ -36,9 +34,7 @@ fd_ualloc(void)    return -1;  } -/* - * allocate a file descriptor structure - */ +// Allocate a file descriptor structure  struct fd*  fd_alloc(void)  { @@ -57,9 +53,8 @@ fd_alloc(void)    return 0;  } -/* - * addr is a kernel address, pointing into some process's p->mem. - */ +// Write to file descriptor; +// addr is a kernel address, pointing into some process's p->mem.  int  fd_write(struct fd *fd, char *addr, int n)  { @@ -81,6 +76,7 @@ fd_write(struct fd *fd, char *addr, int n)    }  } +// Read from file descriptor.  int  fd_read(struct fd *fd, char *addr, int n)  { @@ -101,6 +97,7 @@ fd_read(struct fd *fd, char *addr, int n)    }  } +// Close file descriptor.  void  fd_close(struct fd *fd)  { @@ -128,6 +125,7 @@ fd_close(struct fd *fd)    }  } +// Get metadata about file descriptor.  int  fd_stat(struct fd *fd, struct stat *st)  { @@ -140,6 +138,7 @@ fd_stat(struct fd *fd, struct stat *st)      return -1;  } +// Increment file descriptor reference count.  void  fd_incref(struct fd *fd)  { @@ -24,9 +24,7 @@ iinit(void)    initlock(&inode_table_lock, "inode_table");  } -/* - * allocate a disk block - */ +// Allocate a disk block.  static uint  balloc(uint dev)  { @@ -90,11 +88,11 @@ bfree(int dev, uint b)    brelse(bp);  } -/* - * fetch an inode, from the in-core table if it's already - * in use, otherwise read from the disk. - * returns an inode with busy set and incremented reference count. - */ +// Find the inode with number inum on device dev +// and return an in-memory copy.  Loads the inode +// from disk into the in-core table if necessary. +// The returned inode has busy set and has its ref count incremented. +// Caller must iput the return value when done with it.  struct inode*  iget(uint dev, uint inum)  { @@ -1,6 +1,4 @@ -/* - * Simple PIO-based (non-DMA) IDE driver code. - */ +// Simple PIO-based (non-DMA) IDE driver code.  #include "types.h"  #include "param.h" @@ -38,7 +36,7 @@ ide_wait_ready(int check_error)    int r;    while(((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY) -    /* do nothing */; +    ;    if(check_error && (r & (IDE_DF|IDE_ERR)) != 0)      return -1; @@ -75,7 +73,7 @@ ide_probe_disk1(void)    // check for Device 1 to be ready for a while    for(x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++) -    /* do nothing */; +    ;    // switch back to Device 0    outb(0x1F6, 0xE0 | (0<<4)); @@ -4,7 +4,7 @@  #include "fs.h"  #include "fcntl.h" -/* The initial user-level program */ +// init: The initial user-level program  char *sh_args[] = { "sh", 0 }; @@ -1,7 +1,7 @@ -#define IO_APIC_BASE   0xFEC00000   /* default physical locations of an IO APIC */ -#define IOAPIC_WINDOW        0x10   /* window register offset */ +#define IO_APIC_BASE   0xFEC00000   // default physical locations of an IO APIC +#define IOAPIC_WINDOW        0x10   // window register offset -/* constants relating to APIC ID registers */ +// Constants relating to APIC ID registers  #define APIC_ID_MASK            0xff000000  #define APIC_ID_SHIFT           24  #define APIC_ID_CLUSTER         0xf0 @@ -10,12 +10,12 @@  #define APIC_MAX_INTRACLUSTER_ID 3  #define APIC_ID_CLUSTER_SHIFT   4 -/* fields in VER */ +// Fields in VER  #define APIC_VER_VERSION        0x000000ff  #define APIC_VER_MAXLVT         0x00ff0000  #define MAXLVTSHIFT             16 -/* Indexes into IO APIC */ +// Indexes into IO APIC  #define IOAPIC_ID               0x00  #define IOAPIC_VER              0x01  #define IOAPIC_ARB              0x02 @@ -45,46 +45,44 @@  #define IOAPIC_REDTBL22         (IOAPIC_REDTBL+0x2c)  #define IOAPIC_REDTBL23         (IOAPIC_REDTBL+0x2e) -/* - * fields in the IO APIC's redirection table entries - */ -#define IOART_DEST      APIC_ID_MASK    /* broadcast addr: all APICs */ +// Fields in the IO APIC's redirection table entries +#define IOART_DEST      APIC_ID_MASK    // broadcast addr: all APICs -#define IOART_RESV      0x00fe0000      /* reserved */ +#define IOART_RESV      0x00fe0000      // reserved -#define IOART_INTMASK   0x00010000      /* R/W: INTerrupt mask */ -#define IOART_INTMCLR   0x00000000      /*       clear, allow INTs */ -#define IOART_INTMSET   0x00010000      /*       set, inhibit INTs */ +#define IOART_INTMASK   0x00010000      // R/W: INTerrupt mask +#define IOART_INTMCLR   0x00000000      //       clear, allow INTs +#define IOART_INTMSET   0x00010000      //       set, inhibit INTs -#define IOART_TRGRMOD   0x00008000      /* R/W: trigger mode */ -#define IOART_TRGREDG   0x00000000      /*       edge */ -#define IOART_TRGRLVL   0x00008000      /*       level */ +#define IOART_TRGRMOD   0x00008000      // R/W: trigger mode +#define IOART_TRGREDG   0x00000000      //       edge +#define IOART_TRGRLVL   0x00008000      //       level -#define IOART_REM_IRR   0x00004000      /* RO: remote IRR */ +#define IOART_REM_IRR   0x00004000      // RO: remote IRR -#define IOART_INTPOL    0x00002000      /* R/W: INT input pin polarity */ -#define IOART_INTAHI    0x00000000      /*      active high */ -#define IOART_INTALO    0x00002000      /*      active low */ +#define IOART_INTPOL    0x00002000      // R/W: INT input pin polarity +#define IOART_INTAHI    0x00000000      //      active high +#define IOART_INTALO    0x00002000      //      active low -#define IOART_DELIVS    0x00001000      /* RO: delivery status */ +#define IOART_DELIVS    0x00001000      // RO: delivery status -#define IOART_DESTMOD   0x00000800      /* R/W: destination mode */ -#define IOART_DESTPHY   0x00000000      /*      physical */ -#define IOART_DESTLOG   0x00000800      /*      logical */ +#define IOART_DESTMOD   0x00000800      // R/W: destination mode +#define IOART_DESTPHY   0x00000000      //      physical +#define IOART_DESTLOG   0x00000800      //      logical -#define IOART_DELMOD    0x00000700      /* R/W: delivery mode */ -#define IOART_DELFIXED  0x00000000      /*       fixed */ -#define IOART_DELLOPRI  0x00000100      /*       lowest priority */ -#define IOART_DELSMI    0x00000200      /*       System Management INT */ -#define IOART_DELRSV1   0x00000300      /*       reserved */ -#define IOART_DELNMI    0x00000400      /*       NMI signal */ -#define IOART_DELINIT   0x00000500      /*       INIT signal */ -#define IOART_DELRSV2   0x00000600      /*       reserved */ -#define IOART_DELEXINT  0x00000700      /*       External INTerrupt */ +#define IOART_DELMOD    0x00000700      // R/W: delivery mode +#define IOART_DELFIXED  0x00000000      //       fixed +#define IOART_DELLOPRI  0x00000100      //       lowest priority +#define IOART_DELSMI    0x00000200      //       System Management INT +#define IOART_DELRSV1   0x00000300      //       reserved +#define IOART_DELNMI    0x00000400      //       NMI signal +#define IOART_DELINIT   0x00000500      //       INIT signal +#define IOART_DELRSV2   0x00000600      //       reserved +#define IOART_DELEXINT  0x00000700      //       External INTerrupt -#define IOART_INTVEC    0x000000ff      /* R/W: INTerrupt vector field */ +#define IOART_INTVEC    0x000000ff      // R/W: INTerrupt vector field -/* fields in VER */ +// Fields in VER  #define IOART_VER_VERSION       0x000000ff  #define IOART_VER_MAXREDIR      0x00ff0000  #define MAXREDIRSHIFT           16 @@ -1,11 +1,9 @@ -/* - * physical memory allocator, intended to be used to allocate - * memory for user processes. allocates in 4096-byte "pages". - * free list is sorted and combines adjacent pages into - * long runs, to make it easier to allocate big segments. - * one reason the page size is 4k is that the x86 segment size - * granularity is 4k. - */ +// Physical memory allocator, intended to allocate +// memory for user processes. Allocates in 4096-byte "pages". +// Free list is kept sorted and combines adjacent pages into +// long runs, to make it easier to allocate big segments. +// One reason the page size is 4k is that the x86 segment size +// granularity is 4k.  #include "param.h"  #include "types.h" @@ -23,11 +21,10 @@ struct run {  };  struct run *freelist; -/* - * initialize free list of physical pages. this code - * cheats by just considering the one megabyte of pages - * after _end. - */ +// Initialize free list of physical pages. +// This code cheats by just considering one megabyte of +// pages after _end.  Real systems would determine the +// amount of memory available in the system and use it all.  void  kinit(void)  { @@ -95,11 +92,9 @@ kfree(char *cp, int len)    release(&kalloc_lock);  } -/* - * allocate n bytes of physical memory. - * returns a kernel-segment pointer. - * returns 0 if there's no run that's big enough. - */ +// Allocate n bytes of physical memory. +// Returns a kernel-segment pointer. +// Returns 0 if the memory cannot be allocated.  char*  kalloc(int n)  { @@ -7,84 +7,84 @@  #include "mmu.h"  #include "proc.h" -enum {					/* Local APIC registers */ -  LAPIC_ID  = 0x0020,	/* ID */ -  LAPIC_VER = 0x0030,	/* Version */ -  LAPIC_TPR = 0x0080,	/* Task Priority */ -  LAPIC_APR = 0x0090,	/* Arbitration Priority */ -  LAPIC_PPR = 0x00A0,	/* Processor Priority */ -  LAPIC_EOI = 0x00B0,	/* EOI */ -  LAPIC_LDR = 0x00D0,	/* Logical Destination */ -  LAPIC_DFR = 0x00E0,	/* Destination Format */ -  LAPIC_SVR = 0x00F0,	/* Spurious Interrupt Vector */ -  LAPIC_ISR = 0x0100,	/* Interrupt Status (8 registers) */ -  LAPIC_TMR = 0x0180,	/* Trigger Mode (8 registers) */ -  LAPIC_IRR = 0x0200,	/* Interrupt Request (8 registers) */ -  LAPIC_ESR = 0x0280,	/* Error Status */ -  LAPIC_ICRLO = 0x0300,	/* Interrupt Command */ -  LAPIC_ICRHI = 0x0310,	/* Interrupt Command [63:32] */ -  LAPIC_TIMER = 0x0320,	/* Local Vector Table 0 (TIMER) */ -  LAPIC_PCINT = 0x0340,	/* Performance Counter LVT */ -  LAPIC_LINT0 = 0x0350,	/* Local Vector Table 1 (LINT0) */ -  LAPIC_LINT1 = 0x0360,	/* Local Vector Table 2 (LINT1) */ -  LAPIC_ERROR = 0x0370,	/* Local Vector Table 3 (ERROR) */ -  LAPIC_TICR = 0x0380,	/* Timer Initial Count */ -  LAPIC_TCCR = 0x0390,	/* Timer Current Count */ -  LAPIC_TDCR = 0x03E0,	/* Timer Divide Configuration */ +enum {					// Local APIC registers +  LAPIC_ID  = 0x0020,	// ID +  LAPIC_VER = 0x0030,	// Version +  LAPIC_TPR = 0x0080,	// Task Priority +  LAPIC_APR = 0x0090,	// Arbitration Priority +  LAPIC_PPR = 0x00A0,	// Processor Priority +  LAPIC_EOI = 0x00B0,	// EOI +  LAPIC_LDR = 0x00D0,	// Logical Destination +  LAPIC_DFR = 0x00E0,	// Destination Format +  LAPIC_SVR = 0x00F0,	// Spurious Interrupt Vector +  LAPIC_ISR = 0x0100,	// Interrupt Status (8 registers) +  LAPIC_TMR = 0x0180,	// Trigger Mode (8 registers) +  LAPIC_IRR = 0x0200,	// Interrupt Request (8 registers) +  LAPIC_ESR = 0x0280,	// Error Status +  LAPIC_ICRLO = 0x0300,	// Interrupt Command +  LAPIC_ICRHI = 0x0310,	// Interrupt Command [63:32] +  LAPIC_TIMER = 0x0320,	// Local Vector Table 0 (TIMER) +  LAPIC_PCINT = 0x0340,	// Performance Counter LVT +  LAPIC_LINT0 = 0x0350,	// Local Vector Table 1 (LINT0) +  LAPIC_LINT1 = 0x0360,	// Local Vector Table 2 (LINT1) +  LAPIC_ERROR = 0x0370,	// Local Vector Table 3 (ERROR) +  LAPIC_TICR = 0x0380,	// Timer Initial Count +  LAPIC_TCCR = 0x0390,	// Timer Current Count +  LAPIC_TDCR = 0x03E0,	// Timer Divide Configuration  }; -enum {					/* LAPIC_SVR */ -  LAPIC_ENABLE	= 0x00000100,	/* Unit Enable */ -  LAPIC_FOCUS	= 0x00000200,	/* Focus Processor Checking Disable */ +enum {					// LAPIC_SVR +  LAPIC_ENABLE	= 0x00000100,	// Unit Enable +  LAPIC_FOCUS	= 0x00000200,	// Focus Processor Checking Disable  }; -enum {					/* LAPIC_ICRLO */ -					/* [14] IPI Trigger Mode Level (RW) */ -  LAPIC_DEASSERT = 0x00000000,	/* Deassert level-sensitive interrupt */ -  LAPIC_ASSERT	= 0x00004000,	/* Assert level-sensitive interrupt */ - -  /* [17:16] Remote Read Status */ -  LAPIC_INVALID	= 0x00000000,	/* Invalid */ -  LAPIC_WAIT	= 0x00010000,	/* In-Progress */ -  LAPIC_VALID	= 0x00020000,	/* Valid */ - -  /* [19:18] Destination Shorthand */ -  LAPIC_FIELD	= 0x00000000,	/* No shorthand */ -  LAPIC_SELF	= 0x00040000,	/* Self is single destination */ -  LAPIC_ALLINC	= 0x00080000,	/* All including self */ -  LAPIC_ALLEXC	= 0x000C0000,	/* All Excluding self */ +enum {					// LAPIC_ICRLO +					// [14] IPI Trigger Mode Level (RW) +  LAPIC_DEASSERT = 0x00000000,	// Deassert level-sensitive interrupt +  LAPIC_ASSERT	= 0x00004000,	// Assert level-sensitive interrupt + +  // [17:16] Remote Read Status +  LAPIC_INVALID	= 0x00000000,	// Invalid +  LAPIC_WAIT	= 0x00010000,	// In-Progress +  LAPIC_VALID	= 0x00020000,	// Valid + +  // [19:18] Destination Shorthand +  LAPIC_FIELD	= 0x00000000,	// No shorthand +  LAPIC_SELF	= 0x00040000,	// Self is single destination +  LAPIC_ALLINC	= 0x00080000,	// All including self +  LAPIC_ALLEXC	= 0x000C0000,	// All Excluding self  }; -enum {					/* LAPIC_ESR */ -  LAPIC_SENDCS	= 0x00000001,	/* Send CS Error */ -  LAPIC_RCVCS	= 0x00000002,	/* Receive CS Error */ -  LAPIC_SENDACCEPT = 0x00000004,	/* Send Accept Error */ -  LAPIC_RCVACCEPT = 0x00000008,	/* Receive Accept Error */ -  LAPIC_SENDVECTOR = 0x00000020,	/* Send Illegal Vector */ -  LAPIC_RCVVECTOR = 0x00000040,	/* Receive Illegal Vector */ -  LAPIC_REGISTER = 0x00000080,	/* Illegal Register Address */ +enum {					// LAPIC_ESR +  LAPIC_SENDCS	= 0x00000001,	// Send CS Error +  LAPIC_RCVCS	= 0x00000002,	// Receive CS Error +  LAPIC_SENDACCEPT = 0x00000004,	// Send Accept Error +  LAPIC_RCVACCEPT = 0x00000008,	// Receive Accept Error +  LAPIC_SENDVECTOR = 0x00000020,	// Send Illegal Vector +  LAPIC_RCVVECTOR = 0x00000040,	// Receive Illegal Vector +  LAPIC_REGISTER = 0x00000080,	// Illegal Register Address  }; -enum {					/* LAPIC_TIMER */ -					/* [17] Timer Mode (RW) */ -  LAPIC_ONESHOT	= 0x00000000,	/* One-shot */ -  LAPIC_PERIODIC = 0x00020000,	/* Periodic */ +enum {					// LAPIC_TIMER +					// [17] Timer Mode (RW) +  LAPIC_ONESHOT	= 0x00000000,	// One-shot +  LAPIC_PERIODIC = 0x00020000,	// Periodic -  /* [19:18] Timer Base (RW) */ -  LAPIC_CLKIN	= 0x00000000,	/* use CLKIN as input */ -  LAPIC_TMBASE	= 0x00040000,	/* use TMBASE */ -  LAPIC_DIVIDER	= 0x00080000,	/* use output of the divider */ +  // [19:18] Timer Base (RW) +  LAPIC_CLKIN	= 0x00000000,	// use CLKIN as input +  LAPIC_TMBASE	= 0x00040000,	// use TMBASE +  LAPIC_DIVIDER	= 0x00080000,	// use output of the divider  }; -enum {					/* LAPIC_TDCR */ -  LAPIC_X2 = 0x00000000,	/* divide by 2 */ -  LAPIC_X4 = 0x00000001,	/* divide by 4 */ -  LAPIC_X8 = 0x00000002,	/* divide by 8 */ -  LAPIC_X16 = 0x00000003,	/* divide by 16 */ -  LAPIC_X32 = 0x00000008,	/* divide by 32 */ -  LAPIC_X64 = 0x00000009,	/* divide by 64 */ -  LAPIC_X128 = 0x0000000A,	/* divide by 128 */ -  LAPIC_X1 = 0x0000000B,	/* divide by 1 */ +enum {					// LAPIC_TDCR +  LAPIC_X2 = 0x00000000,	// divide by 2 +  LAPIC_X4 = 0x00000001,	// divide by 4 +  LAPIC_X8 = 0x00000002,	// divide by 8 +  LAPIC_X16 = 0x00000003,	// divide by 16 +  LAPIC_X32 = 0x00000008,	// divide by 32 +  LAPIC_X64 = 0x00000009,	// divide by 64 +  LAPIC_X128 = 0x0000000A,	// divide by 128 +  LAPIC_X1 = 0x0000000B,	// divide by 1  };  uint *lapicaddr; @@ -128,7 +128,7 @@ lapic_init(int c)    lapic_write(LAPIC_TPR, 0xFF);  // no interrupts for now    lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));  // enable APIC -  // in virtual wire mode, set up the LINT0 and LINT1 as follows: +  // In virtual wire mode, set up the LINT0 and LINT1 as follows:    lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT);    lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI); @@ -141,9 +141,7 @@ lapic_init(int c)    lapic_write(LAPIC_ESR, 0);    lapic_read(LAPIC_ESR); -  /* -   * Issue an INIT Level De-Assert to synchronise arbitration ID's. -   */ +  // Issue an INIT Level De-Assert to synchronise arbitration ID's.    lapic_write(LAPIC_ICRHI, 0);    lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);    while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS) @@ -1,6 +1,4 @@ -/* - * This file contains definitions for the x86 memory management unit (MMU). - */ +// This file contains definitions for the x86 memory management unit (MMU).  // Eflags register  #define FL_CF           0x00000001      // Carry Flag @@ -55,6 +55,11 @@ mp_scan(uchar *addr, int len)    return 0;  } +// Search for the MP Floating Pointer Structure, which according to the +// spec is in one of the following three locations: +// 1) in the first KB of the EBDA; +// 2) in the last KB of system base memory; +// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.  static struct mp*  mp_search(void)  { @@ -62,13 +67,6 @@ mp_search(void)    uint p;    struct mp *mp; -  /* -   * Search for the MP Floating Pointer Structure, which according to the -   * spec is in one of the following three locations: -   * 1) in the first KB of the EBDA; -   * 2) in the last KB of system base memory; -   * 3) in the BIOS ROM between 0xE0000 and 0xFFFFF. -   */    bda = (uchar*) 0x400;    if((p = (bda[0x0F]<<8)|bda[0x0E])){      if((mp = mp_scan((uchar*) p, 1024))) @@ -82,6 +80,11 @@ mp_search(void)    return mp_scan((uchar*)0xF0000, 0x10000);  } +// Search for an MP configuration table. For now, +// don't accept the default configurations (physaddr == 0). +// Check for correct signature, calculate the checksum and, +// if correct, check the version. +// To do: check extended table checksum.  static int  mp_detect(void)  { @@ -89,13 +92,6 @@ mp_detect(void)    uchar *p, sum;    uint length; -  /* -   * Search for an MP configuration table. For now, -   * don't accept the default configurations (physaddr == 0). -   * Check for correct signature, calculate the checksum and, -   * if correct, check the version. -   * To do: check extended table checksum. -   */    if((mp = mp_search()) == 0 || mp->physaddr == 0)      return 1; @@ -128,13 +124,13 @@ mp_init(void)    uchar byte;    ncpu = 0; -  if((r = mp_detect()) != 0) return; +  if((r = mp_detect()) != 0) +    return; + +  // Run through the table saving information needed for starting +  // application processors and initialising any I/O APICs. The table +  // is guaranteed to be in order such that only one pass is necessary. -  /* -   * Run through the table saving information needed for starting -   * application processors and initialising any I/O APICs. The table -   * is guaranteed to be in order such that only one pass is necessary. -   */    mpctb = (struct mpctb*) mp->physaddr;    lapicaddr = (uint*) mpctb->lapicaddr;    p = ((uchar*)mpctb)+sizeof(struct mpctb); @@ -179,10 +175,10 @@ mp_init(void)    }    if(mp->imcrp) {  // it appears that bochs doesn't support IMCR, and code won't run -    outb(0x22, 0x70);   /* select IMCR */ -    byte = inb(0x23);   /* current contents */ -    byte |= 0x01;       /* mask external INTR */ -    outb(0x23, byte);   /* disconnect 8259s/NMI */ +    outb(0x22, 0x70);   // select IMCR +    byte = inb(0x23);   // current contents +    byte |= 0x01;       // mask external INTR +    outb(0x23, byte);   // disconnect 8259s/NMI    }  } @@ -1,123 +1,118 @@ -/* - * See MultiProcessor Specification Version 1.[14]. - * - */ +// See MultiProcessor Specification Version 1.[14]. -struct mp {             /* floating pointer */ -  uchar signature[4];           /* "_MP_" */ -  void *physaddr;               /* physical address of MP configuration table */ -  uchar length;                 /* 1 */ -  uchar specrev;                /* [14] */ -  uchar checksum;               /* all bytes must add up to 0 */ -  uchar type;                   /* MP system configuration type */ +struct mp {             // floating pointer +  uchar signature[4];           // "_MP_" +  void *physaddr;               // physical address of MP configuration table +  uchar length;                 // 1 +  uchar specrev;                // [14] +  uchar checksum;               // all bytes must add up to 0 +  uchar type;                   // MP system configuration type    uchar imcrp;    uchar reserved[3];  }; -struct mpctb {          /* configuration table header */ -  uchar signature[4];           /* "PCMP" */ -  ushort length;                /* total table length */ -  uchar version;                /* [14] */ -  uchar checksum;               /* all bytes must add up to 0 */ -  uchar product[20];            /* product id */ -  uint *oemtable;              /* OEM table pointer */ -  ushort oemlength;             /* OEM table length */ -  ushort entry;                 /* entry count */ -  uint *lapicaddr;             /* address of local APIC */ -  ushort xlength;               /* extended table length */ -  uchar xchecksum;              /* extended table checksum */ +struct mpctb {          // configuration table header +  uchar signature[4];           // "PCMP" +  ushort length;                // total table length +  uchar version;                // [14] +  uchar checksum;               // all bytes must add up to 0 +  uchar product[20];            // product id +  uint *oemtable;              // OEM table pointer +  ushort oemlength;             // OEM table length +  ushort entry;                 // entry count +  uint *lapicaddr;             // address of local APIC +  ushort xlength;               // extended table length +  uchar xchecksum;              // extended table checksum    uchar reserved;  }; -struct mppe {           /* processor table entry */ -  uchar type;                   /* entry type (0) */ -  uchar apicid;                 /* local APIC id */ -  uchar version;                /* local APIC verison */ -  uchar flags;                  /* CPU flags */ -  uchar signature[4];           /* CPU signature */ -  uint feature;                 /* feature flags from CPUID instruction */ +struct mppe {           // processor table entry +  uchar type;                   // entry type (0) +  uchar apicid;                 // local APIC id +  uchar version;                // local APIC verison +  uchar flags;                  // CPU flags +  uchar signature[4];           // CPU signature +  uint feature;                 // feature flags from CPUID instruction    uchar reserved[8];  }; -struct mpbe {           /* bus table entry */ -  uchar type;                   /* entry type (1) */ -  uchar busno;                  /* bus id */ -  char string[6];               /* bus type string */ +struct mpbe {           // bus table entry +  uchar type;                   // entry type (1) +  uchar busno;                  // bus id +  char string[6];               // bus type string  }; -struct mpioapic {       /* I/O APIC table entry */ -  uchar type;                   /* entry type (2) */ -  uchar apicno;                 /* I/O APIC id */ -  uchar version;                /* I/O APIC version */ -  uchar flags;                  /* I/O APIC flags */ -  uint *addr;                  /* I/O APIC address */ +struct mpioapic {       // I/O APIC table entry +  uchar type;                   // entry type (2) +  uchar apicno;                 // I/O APIC id +  uchar version;                // I/O APIC version +  uchar flags;                  // I/O APIC flags +  uint *addr;                  // I/O APIC address  }; -struct mpie {           /* interrupt table entry */ -  uchar type;                   /* entry type ([34]) */ -  uchar intr;                   /* interrupt type */ -  ushort flags;                 /* interrupt flag */ -  uchar busno;                  /* source bus id */ -  uchar irq;                    /* source bus irq */ -  uchar apicno;                 /* destination APIC id */ -  uchar intin;                  /* destination APIC [L]INTIN# */ +struct mpie {           // interrupt table entry +  uchar type;                   // entry type ([34]) +  uchar intr;                   // interrupt type +  ushort flags;                 // interrupt flag +  uchar busno;                  // source bus id +  uchar irq;                    // source bus irq +  uchar apicno;                 // destination APIC id +  uchar intin;                  // destination APIC [L]INTIN#  }; -enum {                  /* table entry types */ -  MPPROCESSOR   = 0x00,         /* one entry per processor */ -  MPBUS = 0x01,                 /* one entry per bus */ -  MPIOAPIC = 0x02,              /* one entry per I/O APIC */ -  MPIOINTR = 0x03,              /* one entry per bus interrupt source */ -  MPLINTR = 0x04,               /* one entry per system interrupt source */ +enum {                  // table entry types +  MPPROCESSOR   = 0x00,         // one entry per processor +  MPBUS = 0x01,                 // one entry per bus +  MPIOAPIC = 0x02,              // one entry per I/O APIC +  MPIOINTR = 0x03,              // one entry per bus interrupt source +  MPLINTR = 0x04,               // one entry per system interrupt source    MPSASM = 0x80,    MPHIERARCHY   = 0x81,    MPCBASM = 0x82, -                        /* PCMPprocessor and PCMPioapic flags */ -  MPEN = 0x01,                  /* enabled */ -  MPBP = 0x02,                  /* bootstrap processor */ +                        // PCMPprocessor and PCMPioapic flags +  MPEN = 0x01,                  // enabled +  MPBP = 0x02,                  // bootstrap processor -                        /* PCMPiointr and PCMPlintr flags */ -  MPPOMASK = 0x03,              /* polarity conforms to specifications of bus */ -  MPHIGH = 0x01,                /* active high */ -  MPLOW = 0x03,                 /* active low */ -  MPELMASK = 0x0C,              /* trigger mode of APIC input signals */ -  MPEDGE = 0x04,                /* edge-triggered */ -  MPLEVEL = 0x0C,               /* level-triggered */ +                        // PCMPiointr and PCMPlintr flags +  MPPOMASK = 0x03,              // polarity conforms to specifications of bus +  MPHIGH = 0x01,                // active high +  MPLOW = 0x03,                 // active low +  MPELMASK = 0x0C,              // trigger mode of APIC input signals +  MPEDGE = 0x04,                // edge-triggered +  MPLEVEL = 0x0C,               // level-triggered -                        /* PCMPiointr and PCMPlintr interrupt type */ -  MPINT = 0x00,                 /* vectored interrupt from APIC Rdt */ -  MPNMI = 0x01,                 /* non-maskable interrupt */ -  MPSMI = 0x02,                 /* system management interrupt */ -  MPExtINT = 0x03,              /* vectored interrupt from external PIC */ +                        // PCMPiointr and PCMPlintr interrupt type +  MPINT = 0x00,                 // vectored interrupt from APIC Rdt +  MPNMI = 0x01,                 // non-maskable interrupt +  MPSMI = 0x02,                 // system management interrupt +  MPExtINT = 0x03,              // vectored interrupt from external PIC  }; -/* - * Common bits for - *      I/O APIC Redirection Table Entry; - *      Local APIC Local Interrupt Vector Table; - *      Local APIC Inter-Processor Interrupt; - *      Local APIC Timer Vector Table. - */ +// Common bits for +//      I/O APIC Redirection Table Entry; +//      Local APIC Local Interrupt Vector Table; +//      Local APIC Inter-Processor Interrupt; +//      Local APIC Timer Vector Table.  enum { -  APIC_FIXED     = 0x00000000,  /* [10:8] Delivery Mode */ -  APIC_LOWEST    = 0x00000100,  /* Lowest priority */ -  APIC_SMI       = 0x00000200,  /* System Management Interrupt */ -  APIC_RR        = 0x00000300,  /* Remote Read */ +  APIC_FIXED     = 0x00000000,  // [10:8] Delivery Mode +  APIC_LOWEST    = 0x00000100,  // Lowest priority +  APIC_SMI       = 0x00000200,  // System Management Interrupt +  APIC_RR        = 0x00000300,  // Remote Read    APIC_NMI       = 0x00000400, -  APIC_INIT      = 0x00000500,  /* INIT/RESET */ -  APIC_STARTUP   = 0x00000600,  /* Startup IPI */ +  APIC_INIT      = 0x00000500,  // INIT/RESET +  APIC_STARTUP   = 0x00000600,  // Startup IPI    APIC_EXTINT    = 0x00000700, -  APIC_PHYSICAL  = 0x00000000,  /* [11] Destination Mode (RW) */ +  APIC_PHYSICAL  = 0x00000000,  // [11] Destination Mode (RW)    APIC_LOGICAL   = 0x00000800, -  APIC_DELIVS    = 0x00001000,  /* [12] Delivery Status (RO) */ -  APIC_HIGH      = 0x00000000,  /* [13] Interrupt Input Pin Polarity (RW) */ +  APIC_DELIVS    = 0x00001000,  // [12] Delivery Status (RO) +  APIC_HIGH      = 0x00000000,  // [13] Interrupt Input Pin Polarity (RW)    APIC_LOW       = 0x00002000, -  APIC_REMOTEIRR = 0x00004000,  /* [14] Remote IRR (RO) */ -  APIC_EDGE      = 0x00000000,  /* [15] Trigger Mode (RW) */ +  APIC_REMOTEIRR = 0x00004000,  // [14] Remote IRR (RO) +  APIC_EDGE      = 0x00000000,  // [15] Trigger Mode (RW)    APIC_LEVEL     = 0x00008000, -  APIC_IMASK     = 0x00010000,  /* [16] Interrupt Mask */ +  APIC_IMASK     = 0x00010000,  // [16] Interrupt Mask  }; @@ -22,7 +22,7 @@ irq_setmask_8259A(ushort mask)    outb(IO_PIC2+1, (char)(mask >> 8));  } -/* Initialize the 8259A interrupt controllers. */ +// Initialize the 8259A interrupt controllers.  void  pic_init(void)  { @@ -67,11 +67,11 @@ pic_init(void)    //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask    //    p:  0 = no polling, 1 = polling mode    //   rs:  0x = NOP, 10 = read IRR, 11 = read ISR -  outb(IO_PIC1, 0x68);             /* clear specific mask */ -  outb(IO_PIC1, 0x0a);             /* read IRR by default */ +  outb(IO_PIC1, 0x68);             // clear specific mask +  outb(IO_PIC1, 0x0a);             // read IRR by default -  outb(IO_PIC2, 0x68);               /* OCW3 */ -  outb(IO_PIC2, 0x0a);               /* OCW3 */ +  outb(IO_PIC2, 0x68);             // OCW3 +  outb(IO_PIC2, 0x0a);             // OCW3    if(irq_mask_8259A != 0xFFFF)      irq_setmask_8259A(irq_mask_8259A); @@ -33,9 +33,7 @@ printint(int fd, int xx, int base, int sgn)      putc(fd, buf[i]);  } -/* - * printf to the stdout. only understands %d, %x, %p, %s. - */ +// Print to the given fd. Only understands %d, %x, %p, %s.  void  printf(int fd, char *fmt, ...)  { @@ -21,11 +21,10 @@ pinit(void)    initlock(&proc_table_lock, "proc_table");  } -/* - * set up CPU's segment descriptors and task state for a - * given process. If p==0, set up for "idle" state for - * when scheduler() isn't running any process. - */ +// Set up CPU's segment descriptors and task state for a +// given process. +// If p==0, set up for "idle" state for when scheduler() +// is idling, not running any process.  void  setupsegs(struct proc *p)  { @@ -1,20 +1,10 @@ -/* - * p->mem: - *   text - *   original data and bss - *   fixed-size stack - *   expandable heap - */ - -/* - * segments in proc->gdt - */ +// segments in proc->gdt  #define SEG_KCODE 1 // kernel code  #define SEG_KDATA 2 // kernel data+stack  #define SEG_UCODE 3  #define SEG_UDATA 4 -#define SEG_TSS 5   // this process's task state -#define NSEGS 6 +#define SEG_TSS   5   // this process's task state +#define NSEGS     6  struct jmpbuf {    // saved registers for kernel context switches @@ -37,6 +27,11 @@ enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };  struct proc{    char *mem;    // start of process's memory (a kernel address) +    // process memory is laid out contiguously: +    //   text +    //   original data and bss +    //   fixed-size stack +    //   expandable heap    uint sz;      // user memory size    char *kstack; // kernel stack    enum proc_state state; @@ -15,18 +15,14 @@  #include "fd.h"  #include "fcntl.h" -/* - * User code makes a system call with INT T_SYSCALL. - * System call number in %eax. - * Arguments on the stack, from the user call to the C - * library system call function. The saved user %esp points - * to a saved program counter, and then the first argument. - */ - -/* - * fetch 32 bits from a user-supplied pointer. - * returns 0 if addr was OK, -1 if illegal. - */ +// User code makes a system call with INT T_SYSCALL. +// System call number in %eax. +// Arguments on the stack, from the user call to the C +// library system call function. The saved user %esp points +// to a saved program counter, and then the first argument. + +// Fetch 32 bits from a user-supplied pointer. +// Returns 0 if addr was OK, -1 if illegal.  int  fetchint(struct proc *p, uint addr, int *ip)  { @@ -58,8 +54,8 @@ fetcharg(int argno, void *ip)    return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);  } -// check that an entire string is valid in user space. -// returns the length, not including null, or -1. +// Check that an entire string is valid in user space. +// Returns the length, not including null, or -1.  int  checkstring(uint s)  { @@ -8,7 +8,7 @@  #include "syscall.h"  struct gatedesc idt[256]; -extern uint vectors[]; /* vectors.S, array of 256 entry point addresses */ +extern uint vectors[];  // in vectors.S: array of 256 entry point addresses  extern void trapenter(void);  extern void trapenter1(void); @@ -8,13 +8,13 @@  #define T_ILLOP          6          // illegal opcode  #define T_DEVICE         7          // device not available  #define T_DBLFLT         8          // double fault -/* #define T_COPROC      9 */       // reserved (not generated by recent processors) +// #define T_COPROC      9          // reserved (not generated by recent processors)  #define T_TSS           10          // invalid task switch segment  #define T_SEGNP         11          // segment not present  #define T_STACK         12          // stack exception  #define T_GPFLT         13          // genernal protection fault  #define T_PGFLT         14          // page fault -/* #define T_RES        15 */       // reserved +// #define T_RES        15          // reserved  #define T_FPERR         16          // floating point error  #define T_ALIGN         17          // aligment check  #define T_MCHK          18          // machine check @@ -25,7 +25,7 @@  #define T_SYSCALL       48          // system call  #define T_DEFAULT      500          // catchall -#define IRQ_OFFSET      32      // IRQ 0 corresponds to int IRQ_OFFSET +#define IRQ_OFFSET      32          // IRQ 0 corresponds to int IRQ_OFFSET  #define IRQ_KBD          1  #define IRQ_IDE         14 @@ -5,8 +5,8 @@  # since otherwise there's no way for trap() to discover  # the interrupt number. -print "/* generated by vectors.pl */\n"; -print "/* handlers */\n"; +print "# generated by vectors.pl - do not edit\n"; +print "# handlers\n";  print ".text\n";  print ".globl alltraps\n";  for(my $i = 0; $i < 256; $i++){ @@ -19,7 +19,7 @@ for(my $i = 0; $i < 256; $i++){      print "  jmp alltraps\n";  } -print "\n/* vector table */\n"; +print "\n# vector table\n";  print ".data\n";  print ".globl vectors\n";  print "vectors:\n"; @@ -125,28 +125,31 @@ sti(void)  }  struct trapframe { -  /* registers as pushed by pusha */ +  // registers as pushed by pusha    uint edi;    uint esi;    uint ebp; -  uint oesp;      /* Useless */ +  uint oesp;      // useless & ignored    uint ebx;    uint edx;    uint ecx;    uint eax; -  /* rest of trap frame */ + +  // rest of trap frame    ushort es;    ushort padding1;    ushort ds;    ushort padding2;    uint trapno; -  /* below here defined by x86 hardware */ + +  // below here defined by x86 hardware    uint err;    uint eip;    ushort cs;    ushort padding3;    uint eflags; -  /* below here only when crossing rings, such as from user to kernel */ + +  // below here only when crossing rings, such as from user to kernel    uint esp;    ushort ss;    ushort padding4; | 
