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 "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

View file

@ -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
elf.h
View file

@ -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

17
fd.c
View file

@ -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)
{

14
fs.c
View file

@ -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)
{

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 "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));

2
init.c
View file

@ -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 };

View file

@ -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

View file

@ -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)
{

136
lapic.c
View file

@ -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 */
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 */
// [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 */
// [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)

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

44
mp.c
View file

@ -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
}
}

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 */
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
};

View file

@ -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);

View file

@ -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, ...)
{

9
proc.c
View file

@ -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)
{

21
proc.h
View file

@ -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;

View file

@ -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.
*/
// 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.
*/
// 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)
{

2
trap.c
View file

@ -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);

View file

@ -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

View file

@ -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";

13
x86.h
View file

@ -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;