no /* */ comments

This commit is contained in:
rsc 2006-09-06 17:50:20 +00:00
parent 9e9bcaf143
commit f552738889
22 changed files with 347 additions and 371 deletions

View file

@ -1,34 +1,31 @@
#include "types.h" #include "types.h"
#include "elf.h" #include "elf.h"
#include "x86.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.
* 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
* DISK LAYOUT // be stored in the first sector of the disk.
* * 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 2nd sector onward holds the kernel image. // * The kernel image must be in ELF format.
* //
* * The kernel image must be in ELF format. // BOOT UP STEPS
* // * when the CPU boots it loads the BIOS into memory and executes it
* 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)
* * the BIOS intializes devices, sets of the interrupt routines, and // into memory and jumps to it.
* 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...
* * 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()
* * 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.
*
* * cmain() in this file takes over, reads in the kernel and jumps to it.
**********************************************************************/
#define SECTSIZE 512 #define SECTSIZE 512
#define ELFHDR ((struct elfhdr*) 0x10000) // scratch space #define ELFHDR ((struct elfhdr*) 0x10000) // scratch space
@ -62,7 +59,7 @@ bad:
outw(0x8A00, 0x8A00); outw(0x8A00, 0x8A00);
outw(0x8A00, 0x8E00); outw(0x8A00, 0x8E00);
while(1) while(1)
/* do nothing */; ;
} }
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'. // Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
@ -96,7 +93,7 @@ waitdisk(void)
{ {
// wait for disk reaady // wait for disk reaady
while((inb(0x1F7) & 0xC0) != 0x40) while((inb(0x1F7) & 0xC0) != 0x40)
/* do nothing */; ;
} }
void void

View file

@ -10,11 +10,9 @@ struct spinlock console_lock;
int panicked = 0; int panicked = 0;
int use_console_lock = 0; int use_console_lock = 0;
/* // Copy console output to parallel port, which you can tell
* copy console output to parallel port, which you can tell // .bochsrc to copy to the stdout:
* .bochsrc to copy to the stdout: // parport1: enabled=1, file="/dev/stdout"
* parport1: enabled=1, file="/dev/stdout"
*/
static void static void
lpt_putc(int c) lpt_putc(int c)
{ {
@ -97,9 +95,7 @@ printint(int xx, int base, int sgn)
cons_putc(buf[i]); 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 void
cprintf(char *fmt, ...) cprintf(char *fmt, ...)
{ {
@ -182,10 +178,10 @@ console_write(int minor, char *buf, int n)
} }
/* This is i8042reg.h + kbdreg.h from NetBSD. */ // This is i8042reg.h + kbdreg.h from NetBSD.
#define KBSTATP 0x64 /* kbd controller status port(I) */ #define KBSTATP 0x64 // kbd controller status port(I)
#define KBS_DIB 0x01 /* kbd data in buffer */ #define KBS_DIB 0x01 // kbd data in buffer
#define KBDATAP 0x60 /* kbd data port(I) */ #define KBDATAP 0x60 // kbd data port(I)
#define NO 0 #define NO 0
@ -241,12 +237,18 @@ static uchar normalmap[256] =
NO, NO, NO, NO, NO, NO, NO, '7', // 0x40 NO, NO, NO, NO, NO, NO, NO, '7', // 0x40
'8', '9', '-', '4', '5', '6', '+', '1', '8', '9', '-', '4', '5', '6', '+', '1',
'2', '3', '0', '.', NO, NO, NO, NO, // 0x50 '2', '3', '0', '.', NO, NO, NO, NO, // 0x50
[0x97] KEY_HOME, [0x9C] '\n' /*KP_Enter*/, [0x97] KEY_HOME,
[0xB5] '/' /*KP_Div*/, [0xC8] KEY_UP, [0x9C] '\n', // KP_Enter
[0xC9] KEY_PGUP, [0xCB] KEY_LF, [0xB5] '/', // KP_Div
[0xCD] KEY_RT, [0xCF] KEY_END, [0xC8] KEY_UP,
[0xD0] KEY_DN, [0xD1] KEY_PGDN, [0xC9] KEY_PGUP,
[0xD2] KEY_INS, [0xD3] KEY_DEL [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] = static uchar shiftmap[256] =
@ -262,12 +264,18 @@ static uchar shiftmap[256] =
NO, NO, NO, NO, NO, NO, NO, '7', // 0x40 NO, NO, NO, NO, NO, NO, NO, '7', // 0x40
'8', '9', '-', '4', '5', '6', '+', '1', '8', '9', '-', '4', '5', '6', '+', '1',
'2', '3', '0', '.', NO, NO, NO, NO, // 0x50 '2', '3', '0', '.', NO, NO, NO, NO, // 0x50
[0x97] KEY_HOME, [0x9C] '\n' /*KP_Enter*/, [0x97] KEY_HOME,
[0xB5] '/' /*KP_Div*/, [0xC8] KEY_UP, [0x9C] '\n', // KP_Enter
[0xC9] KEY_PGUP, [0xCB] KEY_LF, [0xB5] '/', // KP_Div
[0xCD] KEY_RT, [0xCF] KEY_END, [0xC8] KEY_UP,
[0xD0] KEY_DN, [0xD1] KEY_PGDN, [0xC9] KEY_PGUP,
[0xD2] KEY_INS, [0xD3] KEY_DEL [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 - '@') #define C(x) (x - '@')
@ -282,11 +290,16 @@ static uchar ctlmap[256] =
NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'), NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'),
C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO, C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO,
[0x97] KEY_HOME, [0x97] KEY_HOME,
[0xB5] C('/'), [0xC8] KEY_UP, [0xB5] C('/'), // KP_Div
[0xC9] KEY_PGUP, [0xCB] KEY_LF, [0xC8] KEY_UP,
[0xCD] KEY_RT, [0xCF] KEY_END, [0xC9] KEY_PGUP,
[0xD0] KEY_DN, [0xD1] KEY_PGDN, [0xCB] KEY_LF,
[0xD2] KEY_INS, [0xD3] KEY_DEL [0xCD] KEY_RT,
[0xCF] KEY_END,
[0xD0] KEY_DN,
[0xD1] KEY_PGDN,
[0xD2] KEY_INS,
[0xD3] KEY_DEL
}; };
static uchar *charcode[4] = { static uchar *charcode[4] = {

2
elf.h
View file

@ -2,7 +2,7 @@
// format of an ELF executable file // format of an ELF executable file
// //
#define ELF_MAGIC 0x464C457FU /* "\x7FELF" in little endian */ #define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian
struct elfhdr { struct elfhdr {
uint magic; // must equal ELF_MAGIC uint magic; // must equal ELF_MAGIC

17
fd.c
View file

@ -22,9 +22,7 @@ fd_init(void)
initlock(&fd_table_lock, "fd_table"); initlock(&fd_table_lock, "fd_table");
} }
/* // Allocate a file descriptor number for curproc.
* allocate a file descriptor number for curproc.
*/
int int
fd_ualloc(void) fd_ualloc(void)
{ {
@ -36,9 +34,7 @@ fd_ualloc(void)
return -1; return -1;
} }
/* // Allocate a file descriptor structure
* allocate a file descriptor structure
*/
struct fd* struct fd*
fd_alloc(void) fd_alloc(void)
{ {
@ -57,9 +53,8 @@ fd_alloc(void)
return 0; return 0;
} }
/* // Write to file descriptor;
* addr is a kernel address, pointing into some process's p->mem. // addr is a kernel address, pointing into some process's p->mem.
*/
int int
fd_write(struct fd *fd, char *addr, int n) 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 int
fd_read(struct fd *fd, char *addr, int n) 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 void
fd_close(struct fd *fd) fd_close(struct fd *fd)
{ {
@ -128,6 +125,7 @@ fd_close(struct fd *fd)
} }
} }
// Get metadata about file descriptor.
int int
fd_stat(struct fd *fd, struct stat *st) fd_stat(struct fd *fd, struct stat *st)
{ {
@ -140,6 +138,7 @@ fd_stat(struct fd *fd, struct stat *st)
return -1; return -1;
} }
// Increment file descriptor reference count.
void void
fd_incref(struct fd *fd) fd_incref(struct fd *fd)
{ {

14
fs.c
View file

@ -24,9 +24,7 @@ iinit(void)
initlock(&inode_table_lock, "inode_table"); initlock(&inode_table_lock, "inode_table");
} }
/* // Allocate a disk block.
* allocate a disk block
*/
static uint static uint
balloc(uint dev) balloc(uint dev)
{ {
@ -90,11 +88,11 @@ bfree(int dev, uint b)
brelse(bp); brelse(bp);
} }
/* // Find the inode with number inum on device dev
* fetch an inode, from the in-core table if it's already // and return an in-memory copy. Loads the inode
* in use, otherwise read from the disk. // from disk into the in-core table if necessary.
* returns an inode with busy set and incremented reference count. // The returned inode has busy set and has its ref count incremented.
*/ // Caller must iput the return value when done with it.
struct inode* struct inode*
iget(uint dev, uint inum) iget(uint dev, uint inum)
{ {

8
ide.c
View file

@ -1,6 +1,4 @@
/* // Simple PIO-based (non-DMA) IDE driver code.
* Simple PIO-based (non-DMA) IDE driver code.
*/
#include "types.h" #include "types.h"
#include "param.h" #include "param.h"
@ -38,7 +36,7 @@ ide_wait_ready(int check_error)
int r; int r;
while(((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY) while(((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
/* do nothing */; ;
if(check_error && (r & (IDE_DF|IDE_ERR)) != 0) if(check_error && (r & (IDE_DF|IDE_ERR)) != 0)
return -1; return -1;
@ -75,7 +73,7 @@ ide_probe_disk1(void)
// check for Device 1 to be ready for a while // check for Device 1 to be ready for a while
for(x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++) for(x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
/* do nothing */; ;
// switch back to Device 0 // switch back to Device 0
outb(0x1F6, 0xE0 | (0<<4)); outb(0x1F6, 0xE0 | (0<<4));

2
init.c
View file

@ -4,7 +4,7 @@
#include "fs.h" #include "fs.h"
#include "fcntl.h" #include "fcntl.h"
/* The initial user-level program */ // init: The initial user-level program
char *sh_args[] = { "sh", 0 }; char *sh_args[] = { "sh", 0 };

View file

@ -1,7 +1,7 @@
#define IO_APIC_BASE 0xFEC00000 /* default physical locations of an IO APIC */ #define IO_APIC_BASE 0xFEC00000 // default physical locations of an IO APIC
#define IOAPIC_WINDOW 0x10 /* window register offset */ #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_MASK 0xff000000
#define APIC_ID_SHIFT 24 #define APIC_ID_SHIFT 24
#define APIC_ID_CLUSTER 0xf0 #define APIC_ID_CLUSTER 0xf0
@ -10,12 +10,12 @@
#define APIC_MAX_INTRACLUSTER_ID 3 #define APIC_MAX_INTRACLUSTER_ID 3
#define APIC_ID_CLUSTER_SHIFT 4 #define APIC_ID_CLUSTER_SHIFT 4
/* fields in VER */ // Fields in VER
#define APIC_VER_VERSION 0x000000ff #define APIC_VER_VERSION 0x000000ff
#define APIC_VER_MAXLVT 0x00ff0000 #define APIC_VER_MAXLVT 0x00ff0000
#define MAXLVTSHIFT 16 #define MAXLVTSHIFT 16
/* Indexes into IO APIC */ // Indexes into IO APIC
#define IOAPIC_ID 0x00 #define IOAPIC_ID 0x00
#define IOAPIC_VER 0x01 #define IOAPIC_VER 0x01
#define IOAPIC_ARB 0x02 #define IOAPIC_ARB 0x02
@ -45,46 +45,44 @@
#define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2c) #define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2c)
#define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2e) #define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2e)
/* // Fields in the IO APIC's redirection table entries
* fields in the IO APIC's redirection table entries #define IOART_DEST APIC_ID_MASK // broadcast addr: all APICs
*/
#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_INTMASK 0x00010000 // R/W: INTerrupt mask
#define IOART_INTMCLR 0x00000000 /* clear, allow INTs */ #define IOART_INTMCLR 0x00000000 // clear, allow INTs
#define IOART_INTMSET 0x00010000 /* set, inhibit INTs */ #define IOART_INTMSET 0x00010000 // set, inhibit INTs
#define IOART_TRGRMOD 0x00008000 /* R/W: trigger mode */ #define IOART_TRGRMOD 0x00008000 // R/W: trigger mode
#define IOART_TRGREDG 0x00000000 /* edge */ #define IOART_TRGREDG 0x00000000 // edge
#define IOART_TRGRLVL 0x00008000 /* level */ #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_INTPOL 0x00002000 // R/W: INT input pin polarity
#define IOART_INTAHI 0x00000000 /* active high */ #define IOART_INTAHI 0x00000000 // active high
#define IOART_INTALO 0x00002000 /* active low */ #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_DESTMOD 0x00000800 // R/W: destination mode
#define IOART_DESTPHY 0x00000000 /* physical */ #define IOART_DESTPHY 0x00000000 // physical
#define IOART_DESTLOG 0x00000800 /* logical */ #define IOART_DESTLOG 0x00000800 // logical
#define IOART_DELMOD 0x00000700 /* R/W: delivery mode */ #define IOART_DELMOD 0x00000700 // R/W: delivery mode
#define IOART_DELFIXED 0x00000000 /* fixed */ #define IOART_DELFIXED 0x00000000 // fixed
#define IOART_DELLOPRI 0x00000100 /* lowest priority */ #define IOART_DELLOPRI 0x00000100 // lowest priority
#define IOART_DELSMI 0x00000200 /* System Management INT */ #define IOART_DELSMI 0x00000200 // System Management INT
#define IOART_DELRSV1 0x00000300 /* reserved */ #define IOART_DELRSV1 0x00000300 // reserved
#define IOART_DELNMI 0x00000400 /* NMI signal */ #define IOART_DELNMI 0x00000400 // NMI signal
#define IOART_DELINIT 0x00000500 /* INIT signal */ #define IOART_DELINIT 0x00000500 // INIT signal
#define IOART_DELRSV2 0x00000600 /* reserved */ #define IOART_DELRSV2 0x00000600 // reserved
#define IOART_DELEXINT 0x00000700 /* External INTerrupt */ #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_VERSION 0x000000ff
#define IOART_VER_MAXREDIR 0x00ff0000 #define IOART_VER_MAXREDIR 0x00ff0000
#define MAXREDIRSHIFT 16 #define MAXREDIRSHIFT 16

View file

@ -1,11 +1,9 @@
/* // Physical memory allocator, intended to allocate
* physical memory allocator, intended to be used to allocate // memory for user processes. Allocates in 4096-byte "pages".
* memory for user processes. allocates in 4096-byte "pages". // Free list is kept sorted and combines adjacent pages into
* free list is sorted and combines adjacent pages into // long runs, to make it easier to allocate big segments.
* long runs, to make it easier to allocate big segments. // One reason the page size is 4k is that the x86 segment size
* one reason the page size is 4k is that the x86 segment size // granularity is 4k.
* granularity is 4k.
*/
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
@ -23,11 +21,10 @@ struct run {
}; };
struct run *freelist; struct run *freelist;
/* // Initialize free list of physical pages.
* initialize free list of physical pages. this code // This code cheats by just considering one megabyte of
* cheats by just considering the one megabyte of pages // pages after _end. Real systems would determine the
* after _end. // amount of memory available in the system and use it all.
*/
void void
kinit(void) kinit(void)
{ {
@ -95,11 +92,9 @@ kfree(char *cp, int len)
release(&kalloc_lock); release(&kalloc_lock);
} }
/* // Allocate n bytes of physical memory.
* allocate n bytes of physical memory. // Returns a kernel-segment pointer.
* returns a kernel-segment pointer. // Returns 0 if the memory cannot be allocated.
* returns 0 if there's no run that's big enough.
*/
char* char*
kalloc(int n) kalloc(int n)
{ {

136
lapic.c
View file

@ -7,84 +7,84 @@
#include "mmu.h" #include "mmu.h"
#include "proc.h" #include "proc.h"
enum { /* Local APIC registers */ enum { // Local APIC registers
LAPIC_ID = 0x0020, /* ID */ LAPIC_ID = 0x0020, // ID
LAPIC_VER = 0x0030, /* Version */ LAPIC_VER = 0x0030, // Version
LAPIC_TPR = 0x0080, /* Task Priority */ LAPIC_TPR = 0x0080, // Task Priority
LAPIC_APR = 0x0090, /* Arbitration Priority */ LAPIC_APR = 0x0090, // Arbitration Priority
LAPIC_PPR = 0x00A0, /* Processor Priority */ LAPIC_PPR = 0x00A0, // Processor Priority
LAPIC_EOI = 0x00B0, /* EOI */ LAPIC_EOI = 0x00B0, // EOI
LAPIC_LDR = 0x00D0, /* Logical Destination */ LAPIC_LDR = 0x00D0, // Logical Destination
LAPIC_DFR = 0x00E0, /* Destination Format */ LAPIC_DFR = 0x00E0, // Destination Format
LAPIC_SVR = 0x00F0, /* Spurious Interrupt Vector */ LAPIC_SVR = 0x00F0, // Spurious Interrupt Vector
LAPIC_ISR = 0x0100, /* Interrupt Status (8 registers) */ LAPIC_ISR = 0x0100, // Interrupt Status (8 registers)
LAPIC_TMR = 0x0180, /* Trigger Mode (8 registers) */ LAPIC_TMR = 0x0180, // Trigger Mode (8 registers)
LAPIC_IRR = 0x0200, /* Interrupt Request (8 registers) */ LAPIC_IRR = 0x0200, // Interrupt Request (8 registers)
LAPIC_ESR = 0x0280, /* Error Status */ LAPIC_ESR = 0x0280, // Error Status
LAPIC_ICRLO = 0x0300, /* Interrupt Command */ LAPIC_ICRLO = 0x0300, // Interrupt Command
LAPIC_ICRHI = 0x0310, /* Interrupt Command [63:32] */ LAPIC_ICRHI = 0x0310, // Interrupt Command [63:32]
LAPIC_TIMER = 0x0320, /* Local Vector Table 0 (TIMER) */ LAPIC_TIMER = 0x0320, // Local Vector Table 0 (TIMER)
LAPIC_PCINT = 0x0340, /* Performance Counter LVT */ LAPIC_PCINT = 0x0340, // Performance Counter LVT
LAPIC_LINT0 = 0x0350, /* Local Vector Table 1 (LINT0) */ LAPIC_LINT0 = 0x0350, // Local Vector Table 1 (LINT0)
LAPIC_LINT1 = 0x0360, /* Local Vector Table 2 (LINT1) */ LAPIC_LINT1 = 0x0360, // Local Vector Table 2 (LINT1)
LAPIC_ERROR = 0x0370, /* Local Vector Table 3 (ERROR) */ LAPIC_ERROR = 0x0370, // Local Vector Table 3 (ERROR)
LAPIC_TICR = 0x0380, /* Timer Initial Count */ LAPIC_TICR = 0x0380, // Timer Initial Count
LAPIC_TCCR = 0x0390, /* Timer Current Count */ LAPIC_TCCR = 0x0390, // Timer Current Count
LAPIC_TDCR = 0x03E0, /* Timer Divide Configuration */ LAPIC_TDCR = 0x03E0, // Timer Divide Configuration
}; };
enum { /* LAPIC_SVR */ enum { // LAPIC_SVR
LAPIC_ENABLE = 0x00000100, /* Unit Enable */ LAPIC_ENABLE = 0x00000100, // Unit Enable
LAPIC_FOCUS = 0x00000200, /* Focus Processor Checking Disable */ LAPIC_FOCUS = 0x00000200, // Focus Processor Checking Disable
}; };
enum { /* LAPIC_ICRLO */ enum { // LAPIC_ICRLO
/* [14] IPI Trigger Mode Level (RW) */ // [14] IPI Trigger Mode Level (RW)
LAPIC_DEASSERT = 0x00000000, /* Deassert level-sensitive interrupt */ LAPIC_DEASSERT = 0x00000000, // Deassert level-sensitive interrupt
LAPIC_ASSERT = 0x00004000, /* Assert level-sensitive interrupt */ LAPIC_ASSERT = 0x00004000, // Assert level-sensitive interrupt
/* [17:16] Remote Read Status */ // [17:16] Remote Read Status
LAPIC_INVALID = 0x00000000, /* Invalid */ LAPIC_INVALID = 0x00000000, // Invalid
LAPIC_WAIT = 0x00010000, /* In-Progress */ LAPIC_WAIT = 0x00010000, // In-Progress
LAPIC_VALID = 0x00020000, /* Valid */ LAPIC_VALID = 0x00020000, // Valid
/* [19:18] Destination Shorthand */ // [19:18] Destination Shorthand
LAPIC_FIELD = 0x00000000, /* No shorthand */ LAPIC_FIELD = 0x00000000, // No shorthand
LAPIC_SELF = 0x00040000, /* Self is single destination */ LAPIC_SELF = 0x00040000, // Self is single destination
LAPIC_ALLINC = 0x00080000, /* All including self */ LAPIC_ALLINC = 0x00080000, // All including self
LAPIC_ALLEXC = 0x000C0000, /* All Excluding self */ LAPIC_ALLEXC = 0x000C0000, // All Excluding self
}; };
enum { /* LAPIC_ESR */ enum { // LAPIC_ESR
LAPIC_SENDCS = 0x00000001, /* Send CS Error */ LAPIC_SENDCS = 0x00000001, // Send CS Error
LAPIC_RCVCS = 0x00000002, /* Receive CS Error */ LAPIC_RCVCS = 0x00000002, // Receive CS Error
LAPIC_SENDACCEPT = 0x00000004, /* Send Accept Error */ LAPIC_SENDACCEPT = 0x00000004, // Send Accept Error
LAPIC_RCVACCEPT = 0x00000008, /* Receive Accept Error */ LAPIC_RCVACCEPT = 0x00000008, // Receive Accept Error
LAPIC_SENDVECTOR = 0x00000020, /* Send Illegal Vector */ LAPIC_SENDVECTOR = 0x00000020, // Send Illegal Vector
LAPIC_RCVVECTOR = 0x00000040, /* Receive Illegal Vector */ LAPIC_RCVVECTOR = 0x00000040, // Receive Illegal Vector
LAPIC_REGISTER = 0x00000080, /* Illegal Register Address */ LAPIC_REGISTER = 0x00000080, // Illegal Register Address
}; };
enum { /* LAPIC_TIMER */ enum { // LAPIC_TIMER
/* [17] Timer Mode (RW) */ // [17] Timer Mode (RW)
LAPIC_ONESHOT = 0x00000000, /* One-shot */ LAPIC_ONESHOT = 0x00000000, // One-shot
LAPIC_PERIODIC = 0x00020000, /* Periodic */ LAPIC_PERIODIC = 0x00020000, // Periodic
/* [19:18] Timer Base (RW) */ // [19:18] Timer Base (RW)
LAPIC_CLKIN = 0x00000000, /* use CLKIN as input */ LAPIC_CLKIN = 0x00000000, // use CLKIN as input
LAPIC_TMBASE = 0x00040000, /* use TMBASE */ LAPIC_TMBASE = 0x00040000, // use TMBASE
LAPIC_DIVIDER = 0x00080000, /* use output of the divider */ LAPIC_DIVIDER = 0x00080000, // use output of the divider
}; };
enum { /* LAPIC_TDCR */ enum { // LAPIC_TDCR
LAPIC_X2 = 0x00000000, /* divide by 2 */ LAPIC_X2 = 0x00000000, // divide by 2
LAPIC_X4 = 0x00000001, /* divide by 4 */ LAPIC_X4 = 0x00000001, // divide by 4
LAPIC_X8 = 0x00000002, /* divide by 8 */ LAPIC_X8 = 0x00000002, // divide by 8
LAPIC_X16 = 0x00000003, /* divide by 16 */ LAPIC_X16 = 0x00000003, // divide by 16
LAPIC_X32 = 0x00000008, /* divide by 32 */ LAPIC_X32 = 0x00000008, // divide by 32
LAPIC_X64 = 0x00000009, /* divide by 64 */ LAPIC_X64 = 0x00000009, // divide by 64
LAPIC_X128 = 0x0000000A, /* divide by 128 */ LAPIC_X128 = 0x0000000A, // divide by 128
LAPIC_X1 = 0x0000000B, /* divide by 1 */ LAPIC_X1 = 0x0000000B, // divide by 1
}; };
uint *lapicaddr; uint *lapicaddr;
@ -128,7 +128,7 @@ lapic_init(int c)
lapic_write(LAPIC_TPR, 0xFF); // no interrupts for now lapic_write(LAPIC_TPR, 0xFF); // no interrupts for now
lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS)); // enable APIC 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_LINT0, APIC_IMASK | APIC_EXTINT);
lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI); lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI);
@ -141,9 +141,7 @@ lapic_init(int c)
lapic_write(LAPIC_ESR, 0); lapic_write(LAPIC_ESR, 0);
lapic_read(LAPIC_ESR); 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_ICRHI, 0);
lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT); lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS) while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)

4
mmu.h
View file

@ -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 // Eflags register
#define FL_CF 0x00000001 // Carry Flag #define FL_CF 0x00000001 // Carry Flag

44
mp.c
View file

@ -55,6 +55,11 @@ mp_scan(uchar *addr, int len)
return 0; 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* static struct mp*
mp_search(void) mp_search(void)
{ {
@ -62,13 +67,6 @@ mp_search(void)
uint p; uint p;
struct mp *mp; 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; bda = (uchar*) 0x400;
if((p = (bda[0x0F]<<8)|bda[0x0E])){ if((p = (bda[0x0F]<<8)|bda[0x0E])){
if((mp = mp_scan((uchar*) p, 1024))) if((mp = mp_scan((uchar*) p, 1024)))
@ -82,6 +80,11 @@ mp_search(void)
return mp_scan((uchar*)0xF0000, 0x10000); 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 static int
mp_detect(void) mp_detect(void)
{ {
@ -89,13 +92,6 @@ mp_detect(void)
uchar *p, sum; uchar *p, sum;
uint length; 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) if((mp = mp_search()) == 0 || mp->physaddr == 0)
return 1; return 1;
@ -128,13 +124,13 @@ mp_init(void)
uchar byte; uchar byte;
ncpu = 0; 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; mpctb = (struct mpctb*) mp->physaddr;
lapicaddr = (uint*) mpctb->lapicaddr; lapicaddr = (uint*) mpctb->lapicaddr;
p = ((uchar*)mpctb)+sizeof(struct mpctb); 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 if(mp->imcrp) { // it appears that bochs doesn't support IMCR, and code won't run
outb(0x22, 0x70); /* select IMCR */ outb(0x22, 0x70); // select IMCR
byte = inb(0x23); /* current contents */ byte = inb(0x23); // current contents
byte |= 0x01; /* mask external INTR */ byte |= 0x01; // mask external INTR
outb(0x23, byte); /* disconnect 8259s/NMI */ outb(0x23, byte); // disconnect 8259s/NMI
} }
} }

171
mp.h
View file

@ -1,123 +1,118 @@
/* // See MultiProcessor Specification Version 1.[14].
* See MultiProcessor Specification Version 1.[14].
*
*/
struct mp { /* floating pointer */ struct mp { // floating pointer
uchar signature[4]; /* "_MP_" */ uchar signature[4]; // "_MP_"
void *physaddr; /* physical address of MP configuration table */ void *physaddr; // physical address of MP configuration table
uchar length; /* 1 */ uchar length; // 1
uchar specrev; /* [14] */ uchar specrev; // [14]
uchar checksum; /* all bytes must add up to 0 */ uchar checksum; // all bytes must add up to 0
uchar type; /* MP system configuration type */ uchar type; // MP system configuration type
uchar imcrp; uchar imcrp;
uchar reserved[3]; uchar reserved[3];
}; };
struct mpctb { /* configuration table header */ struct mpctb { // configuration table header
uchar signature[4]; /* "PCMP" */ uchar signature[4]; // "PCMP"
ushort length; /* total table length */ ushort length; // total table length
uchar version; /* [14] */ uchar version; // [14]
uchar checksum; /* all bytes must add up to 0 */ uchar checksum; // all bytes must add up to 0
uchar product[20]; /* product id */ uchar product[20]; // product id
uint *oemtable; /* OEM table pointer */ uint *oemtable; // OEM table pointer
ushort oemlength; /* OEM table length */ ushort oemlength; // OEM table length
ushort entry; /* entry count */ ushort entry; // entry count
uint *lapicaddr; /* address of local APIC */ uint *lapicaddr; // address of local APIC
ushort xlength; /* extended table length */ ushort xlength; // extended table length
uchar xchecksum; /* extended table checksum */ uchar xchecksum; // extended table checksum
uchar reserved; uchar reserved;
}; };
struct mppe { /* processor table entry */ struct mppe { // processor table entry
uchar type; /* entry type (0) */ uchar type; // entry type (0)
uchar apicid; /* local APIC id */ uchar apicid; // local APIC id
uchar version; /* local APIC verison */ uchar version; // local APIC verison
uchar flags; /* CPU flags */ uchar flags; // CPU flags
uchar signature[4]; /* CPU signature */ uchar signature[4]; // CPU signature
uint feature; /* feature flags from CPUID instruction */ uint feature; // feature flags from CPUID instruction
uchar reserved[8]; uchar reserved[8];
}; };
struct mpbe { /* bus table entry */ struct mpbe { // bus table entry
uchar type; /* entry type (1) */ uchar type; // entry type (1)
uchar busno; /* bus id */ uchar busno; // bus id
char string[6]; /* bus type string */ char string[6]; // bus type string
}; };
struct mpioapic { /* I/O APIC table entry */ struct mpioapic { // I/O APIC table entry
uchar type; /* entry type (2) */ uchar type; // entry type (2)
uchar apicno; /* I/O APIC id */ uchar apicno; // I/O APIC id
uchar version; /* I/O APIC version */ uchar version; // I/O APIC version
uchar flags; /* I/O APIC flags */ uchar flags; // I/O APIC flags
uint *addr; /* I/O APIC address */ uint *addr; // I/O APIC address
}; };
struct mpie { /* interrupt table entry */ struct mpie { // interrupt table entry
uchar type; /* entry type ([34]) */ uchar type; // entry type ([34])
uchar intr; /* interrupt type */ uchar intr; // interrupt type
ushort flags; /* interrupt flag */ ushort flags; // interrupt flag
uchar busno; /* source bus id */ uchar busno; // source bus id
uchar irq; /* source bus irq */ uchar irq; // source bus irq
uchar apicno; /* destination APIC id */ uchar apicno; // destination APIC id
uchar intin; /* destination APIC [L]INTIN# */ uchar intin; // destination APIC [L]INTIN#
}; };
enum { /* table entry types */ enum { // table entry types
MPPROCESSOR = 0x00, /* one entry per processor */ MPPROCESSOR = 0x00, // one entry per processor
MPBUS = 0x01, /* one entry per bus */ MPBUS = 0x01, // one entry per bus
MPIOAPIC = 0x02, /* one entry per I/O APIC */ MPIOAPIC = 0x02, // one entry per I/O APIC
MPIOINTR = 0x03, /* one entry per bus interrupt source */ MPIOINTR = 0x03, // one entry per bus interrupt source
MPLINTR = 0x04, /* one entry per system interrupt source */ MPLINTR = 0x04, // one entry per system interrupt source
MPSASM = 0x80, MPSASM = 0x80,
MPHIERARCHY = 0x81, MPHIERARCHY = 0x81,
MPCBASM = 0x82, MPCBASM = 0x82,
/* PCMPprocessor and PCMPioapic flags */ // PCMPprocessor and PCMPioapic flags
MPEN = 0x01, /* enabled */ MPEN = 0x01, // enabled
MPBP = 0x02, /* bootstrap processor */ MPBP = 0x02, // bootstrap processor
/* PCMPiointr and PCMPlintr flags */ // PCMPiointr and PCMPlintr flags
MPPOMASK = 0x03, /* polarity conforms to specifications of bus */ MPPOMASK = 0x03, // polarity conforms to specifications of bus
MPHIGH = 0x01, /* active high */ MPHIGH = 0x01, // active high
MPLOW = 0x03, /* active low */ MPLOW = 0x03, // active low
MPELMASK = 0x0C, /* trigger mode of APIC input signals */ MPELMASK = 0x0C, // trigger mode of APIC input signals
MPEDGE = 0x04, /* edge-triggered */ MPEDGE = 0x04, // edge-triggered
MPLEVEL = 0x0C, /* level-triggered */ MPLEVEL = 0x0C, // level-triggered
/* PCMPiointr and PCMPlintr interrupt type */ // PCMPiointr and PCMPlintr interrupt type
MPINT = 0x00, /* vectored interrupt from APIC Rdt */ MPINT = 0x00, // vectored interrupt from APIC Rdt
MPNMI = 0x01, /* non-maskable interrupt */ MPNMI = 0x01, // non-maskable interrupt
MPSMI = 0x02, /* system management interrupt */ MPSMI = 0x02, // system management interrupt
MPExtINT = 0x03, /* vectored interrupt from external PIC */ MPExtINT = 0x03, // vectored interrupt from external PIC
}; };
/* // Common bits for
* Common bits for // I/O APIC Redirection Table Entry;
* I/O APIC Redirection Table Entry; // Local APIC Local Interrupt Vector Table;
* Local APIC Local Interrupt Vector Table; // Local APIC Inter-Processor Interrupt;
* Local APIC Inter-Processor Interrupt; // Local APIC Timer Vector Table.
* Local APIC Timer Vector Table.
*/
enum { enum {
APIC_FIXED = 0x00000000, /* [10:8] Delivery Mode */ APIC_FIXED = 0x00000000, // [10:8] Delivery Mode
APIC_LOWEST = 0x00000100, /* Lowest priority */ APIC_LOWEST = 0x00000100, // Lowest priority
APIC_SMI = 0x00000200, /* System Management Interrupt */ APIC_SMI = 0x00000200, // System Management Interrupt
APIC_RR = 0x00000300, /* Remote Read */ APIC_RR = 0x00000300, // Remote Read
APIC_NMI = 0x00000400, APIC_NMI = 0x00000400,
APIC_INIT = 0x00000500, /* INIT/RESET */ APIC_INIT = 0x00000500, // INIT/RESET
APIC_STARTUP = 0x00000600, /* Startup IPI */ APIC_STARTUP = 0x00000600, // Startup IPI
APIC_EXTINT = 0x00000700, APIC_EXTINT = 0x00000700,
APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */ APIC_PHYSICAL = 0x00000000, // [11] Destination Mode (RW)
APIC_LOGICAL = 0x00000800, APIC_LOGICAL = 0x00000800,
APIC_DELIVS = 0x00001000, /* [12] Delivery Status (RO) */ APIC_DELIVS = 0x00001000, // [12] Delivery Status (RO)
APIC_HIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */ APIC_HIGH = 0x00000000, // [13] Interrupt Input Pin Polarity (RW)
APIC_LOW = 0x00002000, APIC_LOW = 0x00002000,
APIC_REMOTEIRR = 0x00004000, /* [14] Remote IRR (RO) */ APIC_REMOTEIRR = 0x00004000, // [14] Remote IRR (RO)
APIC_EDGE = 0x00000000, /* [15] Trigger Mode (RW) */ APIC_EDGE = 0x00000000, // [15] Trigger Mode (RW)
APIC_LEVEL = 0x00008000, APIC_LEVEL = 0x00008000,
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */ APIC_IMASK = 0x00010000, // [16] Interrupt Mask
}; };

View file

@ -22,7 +22,7 @@ irq_setmask_8259A(ushort mask)
outb(IO_PIC2+1, (char)(mask >> 8)); outb(IO_PIC2+1, (char)(mask >> 8));
} }
/* Initialize the 8259A interrupt controllers. */ // Initialize the 8259A interrupt controllers.
void void
pic_init(void) pic_init(void)
{ {
@ -67,11 +67,11 @@ pic_init(void)
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask // ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
// p: 0 = no polling, 1 = polling mode // p: 0 = no polling, 1 = polling mode
// rs: 0x = NOP, 10 = read IRR, 11 = read ISR // rs: 0x = NOP, 10 = read IRR, 11 = read ISR
outb(IO_PIC1, 0x68); /* clear specific mask */ outb(IO_PIC1, 0x68); // clear specific mask
outb(IO_PIC1, 0x0a); /* read IRR by default */ outb(IO_PIC1, 0x0a); // read IRR by default
outb(IO_PIC2, 0x68); /* OCW3 */ outb(IO_PIC2, 0x68); // OCW3
outb(IO_PIC2, 0x0a); /* OCW3 */ outb(IO_PIC2, 0x0a); // OCW3
if(irq_mask_8259A != 0xFFFF) if(irq_mask_8259A != 0xFFFF)
irq_setmask_8259A(irq_mask_8259A); irq_setmask_8259A(irq_mask_8259A);

View file

@ -33,9 +33,7 @@ printint(int fd, int xx, int base, int sgn)
putc(fd, buf[i]); putc(fd, buf[i]);
} }
/* // Print to the given fd. Only understands %d, %x, %p, %s.
* printf to the stdout. only understands %d, %x, %p, %s.
*/
void void
printf(int fd, char *fmt, ...) printf(int fd, char *fmt, ...)
{ {

9
proc.c
View file

@ -21,11 +21,10 @@ pinit(void)
initlock(&proc_table_lock, "proc_table"); initlock(&proc_table_lock, "proc_table");
} }
/* // Set up CPU's segment descriptors and task state for a
* set up CPU's segment descriptors and task state for a // given process.
* given process. If p==0, set up for "idle" state for // If p==0, set up for "idle" state for when scheduler()
* when scheduler() isn't running any process. // is idling, not running any process.
*/
void void
setupsegs(struct proc *p) setupsegs(struct proc *p)
{ {

21
proc.h
View file

@ -1,20 +1,10 @@
/* // segments in proc->gdt
* p->mem:
* text
* original data and bss
* fixed-size stack
* expandable heap
*/
/*
* segments in proc->gdt
*/
#define SEG_KCODE 1 // kernel code #define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack #define SEG_KDATA 2 // kernel data+stack
#define SEG_UCODE 3 #define SEG_UCODE 3
#define SEG_UDATA 4 #define SEG_UDATA 4
#define SEG_TSS 5 // this process's task state #define SEG_TSS 5 // this process's task state
#define NSEGS 6 #define NSEGS 6
struct jmpbuf { struct jmpbuf {
// saved registers for kernel context switches // saved registers for kernel context switches
@ -37,6 +27,11 @@ enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
struct proc{ struct proc{
char *mem; // start of process's memory (a kernel address) 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 uint sz; // user memory size
char *kstack; // kernel stack char *kstack; // kernel stack
enum proc_state state; enum proc_state state;

View file

@ -15,18 +15,14 @@
#include "fd.h" #include "fd.h"
#include "fcntl.h" #include "fcntl.h"
/* // User code makes a system call with INT T_SYSCALL.
* User code makes a system call with INT T_SYSCALL. // System call number in %eax.
* System call number in %eax. // Arguments on the stack, from the user call to the C
* Arguments on the stack, from the user call to the C // library system call function. The saved user %esp points
* library system call function. The saved user %esp points // to a saved program counter, and then the first argument.
* to a saved program counter, and then the first argument.
*/
/* // Fetch 32 bits from a user-supplied pointer.
* fetch 32 bits from a user-supplied pointer. // Returns 0 if addr was OK, -1 if illegal.
* returns 0 if addr was OK, -1 if illegal.
*/
int int
fetchint(struct proc *p, uint addr, int *ip) 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); return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);
} }
// check that an entire string is valid in user space. // Check that an entire string is valid in user space.
// returns the length, not including null, or -1. // Returns the length, not including null, or -1.
int int
checkstring(uint s) checkstring(uint s)
{ {

2
trap.c
View file

@ -8,7 +8,7 @@
#include "syscall.h" #include "syscall.h"
struct gatedesc idt[256]; 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 trapenter(void);
extern void trapenter1(void); extern void trapenter1(void);

View file

@ -8,13 +8,13 @@
#define T_ILLOP 6 // illegal opcode #define T_ILLOP 6 // illegal opcode
#define T_DEVICE 7 // device not available #define T_DEVICE 7 // device not available
#define T_DBLFLT 8 // double fault #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_TSS 10 // invalid task switch segment
#define T_SEGNP 11 // segment not present #define T_SEGNP 11 // segment not present
#define T_STACK 12 // stack exception #define T_STACK 12 // stack exception
#define T_GPFLT 13 // genernal protection fault #define T_GPFLT 13 // genernal protection fault
#define T_PGFLT 14 // page 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_FPERR 16 // floating point error
#define T_ALIGN 17 // aligment check #define T_ALIGN 17 // aligment check
#define T_MCHK 18 // machine check #define T_MCHK 18 // machine check
@ -25,7 +25,7 @@
#define T_SYSCALL 48 // system call #define T_SYSCALL 48 // system call
#define T_DEFAULT 500 // catchall #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_KBD 1
#define IRQ_IDE 14 #define IRQ_IDE 14

View file

@ -5,8 +5,8 @@
# since otherwise there's no way for trap() to discover # since otherwise there's no way for trap() to discover
# the interrupt number. # the interrupt number.
print "/* generated by vectors.pl */\n"; print "# generated by vectors.pl - do not edit\n";
print "/* handlers */\n"; print "# handlers\n";
print ".text\n"; print ".text\n";
print ".globl alltraps\n"; print ".globl alltraps\n";
for(my $i = 0; $i < 256; $i++){ for(my $i = 0; $i < 256; $i++){
@ -19,7 +19,7 @@ for(my $i = 0; $i < 256; $i++){
print " jmp alltraps\n"; print " jmp alltraps\n";
} }
print "\n/* vector table */\n"; print "\n# vector table\n";
print ".data\n"; print ".data\n";
print ".globl vectors\n"; print ".globl vectors\n";
print "vectors:\n"; print "vectors:\n";

13
x86.h
View file

@ -125,28 +125,31 @@ sti(void)
} }
struct trapframe { struct trapframe {
/* registers as pushed by pusha */ // registers as pushed by pusha
uint edi; uint edi;
uint esi; uint esi;
uint ebp; uint ebp;
uint oesp; /* Useless */ uint oesp; // useless & ignored
uint ebx; uint ebx;
uint edx; uint edx;
uint ecx; uint ecx;
uint eax; uint eax;
/* rest of trap frame */
// rest of trap frame
ushort es; ushort es;
ushort padding1; ushort padding1;
ushort ds; ushort ds;
ushort padding2; ushort padding2;
uint trapno; uint trapno;
/* below here defined by x86 hardware */
// below here defined by x86 hardware
uint err; uint err;
uint eip; uint eip;
ushort cs; ushort cs;
ushort padding3; ushort padding3;
uint eflags; 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; uint esp;
ushort ss; ushort ss;
ushort padding4; ushort padding4;