spacing fixes: no tabs, 2-space indents (for rtm)

This commit is contained in:
rsc 2006-09-06 17:04:06 +00:00
parent 45854caa93
commit a650c606fe
33 changed files with 913 additions and 905 deletions

27
asm.h
View File

@ -2,17 +2,18 @@
// macros to create x86 segments from assembler
//
#define SEG_NULLASM \
.word 0, 0; \
.byte 0, 0, 0, 0
#define SEG_ASM(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
#define SEG_NULLASM \
.word 0, 0; \
.byte 0, 0, 0, 0
#define STA_X 0x8 // Executable segment
#define STA_E 0x4 // Expand down (non-executable segments)
#define STA_C 0x4 // Conforming code segment (executable only)
#define STA_W 0x2 // Writeable (non-executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed
#define SEG_ASM(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
#define STA_X 0x8 // Executable segment
#define STA_E 0x4 // Expand down (non-executable segments)
#define STA_C 0x4 // Conforming code segment (executable only)
#define STA_W 0x2 // Writeable (non-executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed

139
bootasm.S
View File

@ -1,36 +1,37 @@
#include "asm.h"
.set PROT_MODE_CSEG,0x8 # code segment selector
.set PROT_MODE_CSEG,0x8 # code segment selector
.set PROT_MODE_DSEG,0x10 # data segment selector
.set CR0_PE_ON,0x1 # protected mode enable flag
.set CR0_PE_ON,0x1 # protected mode enable flag
###################################################################################
# ENTRY POINT
# ENTRY POINT
# This code should be stored in the first sector of the hard disk.
# After the BIOS initializes the hardware on startup or system reset,
# it loads this code at physical address 0x7c00 - 0x7d00 (512 bytes).
# Then the BIOS jumps to the beginning of it, address 0x7c00,
# while running in 16-bit real-mode (8086 compatibility mode).
# The Code Segment register (CS) is initially zero on entry.
#
#
# This code switches into 32-bit protected mode so that all of
# memory can accessed, then calls into C.
###################################################################################
.globl start # Entry point
start: .code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
.globl start # Entry point
start:
.code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax # Segment number zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax # Segment number zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment
# Set up the stack pointer, growing downward from 0x7c00.
movw $start,%sp # Stack Pointer
# Set up the stack pointer, growing downward from 0x7c00.
movw $start,%sp # Stack Pointer
#### Enable A20:
#### For fascinating historical reasons (related to the fact that
#### the earliest 8086-based PCs could only address 1MB of physical memory
@ -38,59 +39,65 @@ start: .code16 # This runs in real mode
#### physical address line 20 is tied to low when the machine boots.
#### Obviously this a bit of a drag for us, especially when trying to
#### address memory above 1MB. This code undoes this.
seta20.1: inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.1 # Yes
movb $0xd1,%al # Command: Write
outb %al,$0x64 # output port
seta20.2: inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.2 # Yes
movb $0xdf,%al # Enable
outb %al,$0x60 # A20
seta20.1:
inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.1 # Yes
movb $0xd1,%al # Command: Write
outb %al,$0x64 # output port
#### Switch from real to protected mode
seta20.2:
inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.2 # Yes
movb $0xdf,%al # Enable
outb %al,$0x60 # A20
#### Switch from real to protected mode
#### The descriptors in our GDT allow all physical memory to be accessed.
#### Furthermore, the descriptors have base addresses of 0, so that the
#### segment translation is a NOP, ie. virtual addresses are identical to
#### their physical addresses. With this setup, immediately after
#### enabling protected mode it will still appear to this code
#### that it is running directly on physical memory with no translation.
#### This initial NOP-translation setup is required by the processor
#### to ensure that the transition to protected mode occurs smoothly.
real_to_prot: cli # Mandatory since we dont set up an IDT
lgdt gdtdesc # load GDT -- mandatory in protected mode
movl %cr0, %eax # turn on protected mode
orl $CR0_PE_ON, %eax #
movl %eax, %cr0 #
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp $PROT_MODE_CSEG, $protcseg
#### enabling protected mode it will still appear to this code
#### that it is running directly on physical memory with no translation.
#### This initial NOP-translation setup is required by the processor
#### to ensure that the transition to protected mode occurs smoothly.
real_to_prot:
cli # Mandatory since we dont set up an IDT
lgdt gdtdesc # load GDT -- mandatory in protected mode
movl %cr0, %eax # turn on protected mode
orl $CR0_PE_ON, %eax #
movl %eax, %cr0 #
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp $PROT_MODE_CSEG, $protcseg
#### we are in 32-bit protected mode (hence the .code32)
.code32
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
call cmain # finish the boot load from C.
# cmain() should not return
spin: jmp spin # ..but in case it does, spin
.p2align 2 # force 4 byte alignment
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
call cmain # finish the boot load from C.
# cmain() should not return
spin:
jmp spin # ..but in case it does, spin
.p2align 2 # force 4 byte alignment
gdt:
SEG_NULLASM # null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
SEG_NULLASM # null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
gdtdesc:
.word 0x17 # sizeof(gdt) - 1
.long gdt # address gdt
.word 0x17 # sizeof(gdt) - 1
.long gdt # address gdt

View File

@ -11,10 +11,10 @@
* 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
* 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
@ -30,8 +30,8 @@
* * cmain() in this file takes over, reads in the kernel and jumps to it.
**********************************************************************/
#define SECTSIZE 512
#define ELFHDR ((struct elfhdr *) 0x10000) // scratch space
#define SECTSIZE 512
#define ELFHDR ((struct elfhdr *) 0x10000) // scratch space
void readsect(void*, uint);
void readseg(uint, uint, uint);
@ -39,30 +39,30 @@ void readseg(uint, uint, uint);
void
cmain(void)
{
struct proghdr *ph, *eph;
struct proghdr *ph, *eph;
// read 1st page off disk
readseg((uint) ELFHDR, SECTSIZE*8, 0);
// read 1st page off disk
readseg((uint) ELFHDR, SECTSIZE*8, 0);
// is this a valid ELF?
if (ELFHDR->magic != ELF_MAGIC)
goto bad;
// is this a valid ELF?
if (ELFHDR->magic != ELF_MAGIC)
goto bad;
// load each program segment (ignores ph flags)
ph = (struct proghdr *) ((uchar *) ELFHDR + ELFHDR->phoff);
eph = ph + ELFHDR->phnum;
for (; ph < eph; ph++)
readseg(ph->va, ph->memsz, ph->offset);
// load each program segment (ignores ph flags)
ph = (struct proghdr *) ((uchar *) ELFHDR + ELFHDR->phoff);
eph = ph + ELFHDR->phnum;
for (; ph < eph; ph++)
readseg(ph->va, ph->memsz, ph->offset);
// call the entry point from the ELF header
// note: does not return!
((void (*)(void)) (ELFHDR->entry & 0xFFFFFF))();
// call the entry point from the ELF header
// note: does not return!
((void (*)(void)) (ELFHDR->entry & 0xFFFFFF))();
bad:
outw(0x8A00, 0x8A00);
outw(0x8A00, 0x8E00);
while(1)
/* do nothing */;
outw(0x8A00, 0x8A00);
outw(0x8A00, 0x8E00);
while(1)
/* do nothing */;
}
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
@ -70,52 +70,52 @@ bad:
void
readseg(uint va, uint count, uint offset)
{
uint end_va;
uint end_va;
va &= 0xFFFFFF;
end_va = va + count;
// round down to sector boundary
va &= ~(SECTSIZE - 1);
va &= 0xFFFFFF;
end_va = va + count;
// round down to sector boundary
va &= ~(SECTSIZE - 1);
// translate from bytes to sectors, and kernel starts at sector 1
offset = (offset / SECTSIZE) + 1;
// translate from bytes to sectors, and kernel starts at sector 1
offset = (offset / SECTSIZE) + 1;
// If this is too slow, we could read lots of sectors at a time.
// We'd write more to memory than asked, but it doesn't matter --
// we load in increasing order.
while (va < end_va) {
readsect((uchar*) va, offset);
va += SECTSIZE;
offset++;
}
// If this is too slow, we could read lots of sectors at a time.
// We'd write more to memory than asked, but it doesn't matter --
// we load in increasing order.
while (va < end_va) {
readsect((uchar*) va, offset);
va += SECTSIZE;
offset++;
}
}
void
waitdisk(void)
{
// wait for disk reaady
while ((inb(0x1F7) & 0xC0) != 0x40)
/* do nothing */;
// wait for disk reaady
while ((inb(0x1F7) & 0xC0) != 0x40)
/* do nothing */;
}
void
readsect(void *dst, uint offset)
{
// wait for disk to be ready
waitdisk();
// wait for disk to be ready
waitdisk();
outb(0x1F2, 1); // count = 1
outb(0x1F3, offset);
outb(0x1F4, offset >> 8);
outb(0x1F5, offset >> 16);
outb(0x1F6, (offset >> 24) | 0xE0);
outb(0x1F7, 0x20); // cmd 0x20 - read sectors
outb(0x1F2, 1); // count = 1
outb(0x1F3, offset);
outb(0x1F4, offset >> 8);
outb(0x1F5, offset >> 16);
outb(0x1F6, (offset >> 24) | 0xE0);
outb(0x1F7, 0x20); // cmd 0x20 - read sectors
// wait for disk to be ready
waitdisk();
// wait for disk to be ready
waitdisk();
// read a sector
insl(0x1F0, dst, SECTSIZE/4);
// read a sector
insl(0x1F0, dst, SECTSIZE/4);
}

View File

@ -1,5 +1,5 @@
#include "asm.h"
/*
* Start an Application Processor. This must be placed on a 4KB boundary
* somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
@ -13,67 +13,68 @@
* mp.c causes each non-boot CPU in turn to jump to start.
* mp.c puts the correct %esp in start-4, and the place to jump
* to in start-8.
*
*
*/
.set PROT_MODE_CSEG,0x8 # code segment selector
.set PROT_MODE_CSEG,0x8 # code segment selector
.set PROT_MODE_DSEG,0x10 # data segment selector
.set CR0_PE_ON,0x1 # protected mode enable flag
.set CR0_PE_ON,0x1 # protected mode enable flag
.globl start
start: .code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
start:
.code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax # Segment number zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax # Segment number zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment
# Set up the stack pointer, growing downward from 0x7000-8.
movw $start-8,%sp # Stack Pointer
#### Switch from real to protected mode
# Set up the stack pointer, growing downward from 0x7000-8.
movw $start-8,%sp # Stack Pointer
#### Switch from real to protected mode
#### The descriptors in our GDT allow all physical memory to be accessed.
#### Furthermore, the descriptors have base addresses of 0, so that the
#### segment translation is a NOP, ie. virtual addresses are identical to
#### their physical addresses. With this setup, immediately after
#### enabling protected mode it will still appear to this code
#### that it is running directly on physical memory with no translation.
#### This initial NOP-translation setup is required by the processor
#### to ensure that the transition to protected mode occurs smoothly.
lgdt gdtdesc # load GDT -- mandatory in protected mode
movl %cr0, %eax # turn on protected mode
orl $CR0_PE_ON, %eax #
movl %eax, %cr0 #
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp $PROT_MODE_CSEG, $protcseg
#### enabling protected mode it will still appear to this code
#### that it is running directly on physical memory with no translation.
#### This initial NOP-translation setup is required by the processor
#### to ensure that the transition to protected mode occurs smoothly.
lgdt gdtdesc # load GDT -- mandatory in protected mode
movl %cr0, %eax # turn on protected mode
orl $CR0_PE_ON, %eax #
movl %eax, %cr0 #
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp $PROT_MODE_CSEG, $protcseg
#### we are in 32-bit protected mode (hence the .code32)
.code32
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
movl start-8, %eax
movl start-4, %esp
jmp *%eax
.p2align 2 # force 4 byte alignment
movl start-8, %eax
movl start-4, %esp
jmp *%eax
.p2align 2 # force 4 byte alignment
gdt:
SEG_NULLASM # null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
SEG_NULLASM # null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
gdtdesc:
.word 0x17 # sizeof(gdt) - 1
.long gdt # address gdt
.word 0x17 # sizeof(gdt) - 1
.long gdt # address gdt

8
cat.c
View File

@ -30,10 +30,10 @@ main(int argc, char *argv[])
for(i = 1; i < argc; i++){
fd = open(argv[i], 0);
if(fd < 0){
puts("cat: cannot open ");
puts(argv[i]);
puts("\n");
exit();
puts("cat: cannot open ");
puts(argv[i]);
puts("\n");
exit();
}
rfile(fd);
close(fd);

174
console.c
View File

@ -18,13 +18,13 @@ int use_console_lock = 0;
static void
lpt_putc(int c)
{
int i;
int i;
for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
;
outb(0x378+0, c);
outb(0x378+2, 0x08|0x04|0x01);
outb(0x378+2, 0x08);
for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
;
outb(0x378+0, c);
outb(0x378+2, 0x08|0x04|0x01);
outb(0x378+2, 0x08);
}
static void
@ -183,117 +183,117 @@ 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) */
#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
#define NO 0
#define SHIFT (1<<0)
#define CTL (1<<1)
#define ALT (1<<2)
#define SHIFT (1<<0)
#define CTL (1<<1)
#define ALT (1<<2)
#define CAPSLOCK (1<<3)
#define NUMLOCK (1<<4)
#define SCROLLLOCK (1<<5)
#define CAPSLOCK (1<<3)
#define NUMLOCK (1<<4)
#define SCROLLLOCK (1<<5)
#define E0ESC (1<<6)
#define E0ESC (1<<6)
// Special keycodes
#define KEY_HOME 0xE0
#define KEY_END 0xE1
#define KEY_UP 0xE2
#define KEY_DN 0xE3
#define KEY_LF 0xE4
#define KEY_RT 0xE5
#define KEY_PGUP 0xE6
#define KEY_PGDN 0xE7
#define KEY_INS 0xE8
#define KEY_DEL 0xE9
#define KEY_HOME 0xE0
#define KEY_END 0xE1
#define KEY_UP 0xE2
#define KEY_DN 0xE3
#define KEY_LF 0xE4
#define KEY_RT 0xE5
#define KEY_PGUP 0xE6
#define KEY_PGDN 0xE7
#define KEY_INS 0xE8
#define KEY_DEL 0xE9
static uchar shiftcode[256] =
{
[0x1D] CTL,
[0x2A] SHIFT,
[0x36] SHIFT,
[0x38] ALT,
[0x9D] CTL,
[0xB8] ALT
[0x1D] CTL,
[0x2A] SHIFT,
[0x36] SHIFT,
[0x38] ALT,
[0x9D] CTL,
[0xB8] ALT
};
static uchar togglecode[256] =
{
[0x3A] CAPSLOCK,
[0x45] NUMLOCK,
[0x46] SCROLLLOCK
[0x3A] CAPSLOCK,
[0x45] NUMLOCK,
[0x46] SCROLLLOCK
};
static uchar normalmap[256] =
{
NO, 0x1B, '1', '2', '3', '4', '5', '6', // 0x00
'7', '8', '9', '0', '-', '=', '\b', '\t',
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 0x10
'o', 'p', '[', ']', '\n', NO, 'a', 's',
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 0x20
'\'', '`', NO, '\\', 'z', 'x', 'c', 'v',
'b', 'n', 'm', ',', '.', '/', NO, '*', // 0x30
NO, ' ', NO, NO, NO, NO, NO, NO,
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
NO, 0x1B, '1', '2', '3', '4', '5', '6', // 0x00
'7', '8', '9', '0', '-', '=', '\b', '\t',
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 0x10
'o', 'p', '[', ']', '\n', NO, 'a', 's',
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 0x20
'\'', '`', NO, '\\', 'z', 'x', 'c', 'v',
'b', 'n', 'm', ',', '.', '/', NO, '*', // 0x30
NO, ' ', NO, NO, NO, NO, NO, NO,
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
};
static uchar shiftmap[256] =
{
NO, 033, '!', '@', '#', '$', '%', '^', // 0x00
'&', '*', '(', ')', '_', '+', '\b', '\t',
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', // 0x10
'O', 'P', '{', '}', '\n', NO, 'A', 'S',
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 0x20
'"', '~', NO, '|', 'Z', 'X', 'C', 'V',
'B', 'N', 'M', '<', '>', '?', NO, '*', // 0x30
NO, ' ', NO, NO, NO, NO, NO, NO,
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
NO, 033, '!', '@', '#', '$', '%', '^', // 0x00
'&', '*', '(', ')', '_', '+', '\b', '\t',
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', // 0x10
'O', 'P', '{', '}', '\n', NO, 'A', 'S',
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 0x20
'"', '~', NO, '|', 'Z', 'X', 'C', 'V',
'B', 'N', 'M', '<', '>', '?', NO, '*', // 0x30
NO, ' ', NO, NO, NO, NO, NO, NO,
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
};
#define C(x) (x - '@')
static uchar ctlmap[256] =
{
NO, NO, NO, NO, NO, NO, NO, NO,
NO, NO, NO, NO, NO, NO, NO, NO,
C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'),
C('O'), C('P'), NO, NO, '\r', NO, C('A'), C('S'),
C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), NO,
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
NO, NO, NO, NO, NO, NO, NO, NO,
NO, NO, NO, NO, NO, NO, NO, NO,
C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'),
C('O'), C('P'), NO, NO, '\r', NO, C('A'), C('S'),
C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), NO,
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
};
static uchar *charcode[4] = {
normalmap,
shiftmap,
ctlmap,
ctlmap
normalmap,
shiftmap,
ctlmap,
ctlmap
};
#define KBD_BUF 64

46
elf.h
View File

@ -5,32 +5,32 @@
#define ELF_MAGIC 0x464C457FU /* "\x7FELF" in little endian */
struct elfhdr {
uint magic; // must equal ELF_MAGIC
uchar elf[12];
ushort type;
ushort machine;
uint version;
uint entry;
uint phoff;
uint shoff;
uint flags;
ushort ehsize;
ushort phentsize;
ushort phnum;
ushort shentsize;
ushort shnum;
ushort shstrndx;
uint magic; // must equal ELF_MAGIC
uchar elf[12];
ushort type;
ushort machine;
uint version;
uint entry;
uint phoff;
uint shoff;
uint flags;
ushort ehsize;
ushort phentsize;
ushort phnum;
ushort shentsize;
ushort shnum;
ushort shstrndx;
};
struct proghdr {
uint type;
uint offset;
uint va;
uint pa;
uint filesz;
uint memsz;
uint flags;
uint align;
uint type;
uint offset;
uint va;
uint pa;
uint filesz;
uint memsz;
uint flags;
uint align;
};
// Values for Proghdr type

26
fs.c
View File

@ -270,16 +270,16 @@ itrunc(struct inode *ip)
for (i = 0; i < NADDRS; i++) {
if (ip->addrs[i] != 0) {
if (i == INDIRECT) {
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
uint *a = (uint *) inbp->data;
for (j = 0; j < NINDIRECT; j++) {
if (a[j] != 0) {
bfree(ip->dev, a[j]);
a[j] = 0;
}
}
brelse(inbp);
}
for (j = 0; j < NINDIRECT; j++) {
if (a[j] != 0) {
bfree(ip->dev, a[j]);
a[j] = 0;
}
}
brelse(inbp);
}
bfree(ip->dev, ip->addrs[i]);
ip->addrs[i] = 0;
}
@ -411,8 +411,8 @@ writei(struct inode *ip, char *addr, uint off, uint n)
lbn = off / BSIZE;
if (lbn >= MAXFILE) return r;
if (newblock(ip, lbn) < 0) {
cprintf("newblock failed\n");
return r;
cprintf("newblock failed\n");
return r;
}
m = min(BSIZE - off % BSIZE, n-r);
bp = bread(ip->dev, bmap(ip, lbn));
@ -424,8 +424,8 @@ writei(struct inode *ip, char *addr, uint off, uint n)
}
if (r > 0) {
if (off > ip->size) {
if (ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE;
else ip->size = off;
if (ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE;
else ip->size = off;
}
iupdate(ip);
}

9
ide.c
View File

@ -11,8 +11,8 @@
#include "traps.h"
#include "spinlock.h"
#define IDE_BSY 0x80
#define IDE_DRDY 0x40
#define IDE_BSY 0x80
#define IDE_DRDY 0x40
#define IDE_DF 0x20
#define IDE_ERR 0x01
@ -23,6 +23,7 @@ struct ide_request {
uint nsecs;
uint read;
};
struct ide_request request[NREQUEST];
int head, tail;
struct spinlock ide_lock;
@ -154,7 +155,7 @@ int
ide_write(int diskno, uint secno, const void *src, uint nsecs)
{
int r;
if(nsecs > 256)
panic("ide_write");
@ -165,7 +166,7 @@ ide_write(int diskno, uint secno, const void *src, uint nsecs)
outb(0x1F4, (secno >> 8) & 0xFF);
outb(0x1F5, (secno >> 16) & 0xFF);
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
outb(0x1F7, 0x30); // CMD 0x30 means write sector
outb(0x1F7, 0x30); // CMD 0x30 means write sector
for (; nsecs > 0; nsecs--, src += 512) {
if ((r = ide_wait_ready(1)) < 0)

View File

@ -11,8 +11,8 @@ struct ioapic {
};
#define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2)
#define IOAPIC_REDTBL_HI(i) (IOAPIC_REDTBL_LO(i) + 1)
#define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2)
#define IOAPIC_REDTBL_HI(i) (IOAPIC_REDTBL_LO(i) + 1)
static uint
ioapic_read(struct ioapic *io, int reg)
@ -40,7 +40,7 @@ ioapic_init(void)
io = (struct ioapic *) IO_APIC_BASE;
l = ioapic_read(io, IOAPIC_VER);
nintr = ((l & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1;
id = ioapic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT;
id = ioapic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT;
if (id != ioapic_id)
panic ("ioapic_init: id isn't equal to ioapic_id\n");
for (i = 0; i < nintr; i++) {

138
ioapic.h
View File

@ -1,90 +1,90 @@
#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 */
#define APIC_ID_MASK 0xff000000
#define APIC_ID_SHIFT 24
#define APIC_ID_CLUSTER 0xf0
#define APIC_ID_CLUSTER_ID 0x0f
#define APIC_MAX_CLUSTER 0xe
#define APIC_MAX_INTRACLUSTER_ID 3
#define APIC_ID_CLUSTER_SHIFT 4
#define APIC_ID_MASK 0xff000000
#define APIC_ID_SHIFT 24
#define APIC_ID_CLUSTER 0xf0
#define APIC_ID_CLUSTER_ID 0x0f
#define APIC_MAX_CLUSTER 0xe
#define APIC_MAX_INTRACLUSTER_ID 3
#define APIC_ID_CLUSTER_SHIFT 4
/* fields in VER */
#define APIC_VER_VERSION 0x000000ff
#define APIC_VER_MAXLVT 0x00ff0000
#define MAXLVTSHIFT 16
#define APIC_VER_VERSION 0x000000ff
#define APIC_VER_MAXLVT 0x00ff0000
#define MAXLVTSHIFT 16
/* Indexes into IO APIC */
#define IOAPIC_ID 0x00
#define IOAPIC_VER 0x01
#define IOAPIC_ARB 0x02
#define IOAPIC_REDTBL 0x10
#define IOAPIC_REDTBL0 IOAPIC_REDTBL
#define IOAPIC_REDTBL1 (IOAPIC_REDTBL+0x02)
#define IOAPIC_REDTBL2 (IOAPIC_REDTBL+0x04)
#define IOAPIC_REDTBL3 (IOAPIC_REDTBL+0x06)
#define IOAPIC_REDTBL4 (IOAPIC_REDTBL+0x08)
#define IOAPIC_REDTBL5 (IOAPIC_REDTBL+0x0a)
#define IOAPIC_REDTBL6 (IOAPIC_REDTBL+0x0c)
#define IOAPIC_REDTBL7 (IOAPIC_REDTBL+0x0e)
#define IOAPIC_REDTBL8 (IOAPIC_REDTBL+0x10)
#define IOAPIC_REDTBL9 (IOAPIC_REDTBL+0x12)
#define IOAPIC_REDTBL10 (IOAPIC_REDTBL+0x14)
#define IOAPIC_REDTBL11 (IOAPIC_REDTBL+0x16)
#define IOAPIC_REDTBL12 (IOAPIC_REDTBL+0x18)
#define IOAPIC_REDTBL13 (IOAPIC_REDTBL+0x1a)
#define IOAPIC_REDTBL14 (IOAPIC_REDTBL+0x1c)
#define IOAPIC_REDTBL15 (IOAPIC_REDTBL+0x1e)
#define IOAPIC_REDTBL16 (IOAPIC_REDTBL+0x20)
#define IOAPIC_REDTBL17 (IOAPIC_REDTBL+0x22)
#define IOAPIC_REDTBL18 (IOAPIC_REDTBL+0x24)
#define IOAPIC_REDTBL19 (IOAPIC_REDTBL+0x26)
#define IOAPIC_REDTBL20 (IOAPIC_REDTBL+0x28)
#define IOAPIC_REDTBL21 (IOAPIC_REDTBL+0x2a)
#define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2c)
#define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2e)
#define IOAPIC_ID 0x00
#define IOAPIC_VER 0x01
#define IOAPIC_ARB 0x02
#define IOAPIC_REDTBL 0x10
#define IOAPIC_REDTBL0 IOAPIC_REDTBL
#define IOAPIC_REDTBL1 (IOAPIC_REDTBL+0x02)
#define IOAPIC_REDTBL2 (IOAPIC_REDTBL+0x04)
#define IOAPIC_REDTBL3 (IOAPIC_REDTBL+0x06)
#define IOAPIC_REDTBL4 (IOAPIC_REDTBL+0x08)
#define IOAPIC_REDTBL5 (IOAPIC_REDTBL+0x0a)
#define IOAPIC_REDTBL6 (IOAPIC_REDTBL+0x0c)
#define IOAPIC_REDTBL7 (IOAPIC_REDTBL+0x0e)
#define IOAPIC_REDTBL8 (IOAPIC_REDTBL+0x10)
#define IOAPIC_REDTBL9 (IOAPIC_REDTBL+0x12)
#define IOAPIC_REDTBL10 (IOAPIC_REDTBL+0x14)
#define IOAPIC_REDTBL11 (IOAPIC_REDTBL+0x16)
#define IOAPIC_REDTBL12 (IOAPIC_REDTBL+0x18)
#define IOAPIC_REDTBL13 (IOAPIC_REDTBL+0x1a)
#define IOAPIC_REDTBL14 (IOAPIC_REDTBL+0x1c)
#define IOAPIC_REDTBL15 (IOAPIC_REDTBL+0x1e)
#define IOAPIC_REDTBL16 (IOAPIC_REDTBL+0x20)
#define IOAPIC_REDTBL17 (IOAPIC_REDTBL+0x22)
#define IOAPIC_REDTBL18 (IOAPIC_REDTBL+0x24)
#define IOAPIC_REDTBL19 (IOAPIC_REDTBL+0x26)
#define IOAPIC_REDTBL20 (IOAPIC_REDTBL+0x28)
#define IOAPIC_REDTBL21 (IOAPIC_REDTBL+0x2a)
#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 */
#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 */
#define IOART_VER_VERSION 0x000000ff
#define IOART_VER_MAXREDIR 0x00ff0000
#define MAXREDIRSHIFT 16
#define IOART_VER_VERSION 0x000000ff
#define IOART_VER_MAXREDIR 0x00ff0000
#define MAXREDIRSHIFT 16

18
ls.c
View File

@ -59,17 +59,17 @@ main(int argc, char *argv[])
sz = st.st_size;
for(off = 0; off < sz; off += sizeof(struct dirent)) {
if (read(fd, &dirent, sizeof(struct dirent)) != sizeof(struct dirent)) {
printf(1, "ls: read error\n");
break;
printf(1, "ls: read error\n");
break;
}
if (dirent.inum != 0) {
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
if (stat (dirent.name, &st) < 0) {
printf(1, "stat: failed %s\n", dirent.name);
continue;
}
pname(dirent.name);
printf(1, "%d %d %d\n", st.st_type, dirent.inum, st.st_size);
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
if (stat (dirent.name, &st) < 0) {
printf(1, "stat: failed %s\n", dirent.name);
continue;
}
pname(dirent.name);
printf(1, "%d %d %d\n", st.st_type, dirent.inum, st.st_size);
}
}
break;

2
main.c
View File

@ -97,7 +97,7 @@ mpmain(void)
// make sure there's a TSS
setupsegs(0);
cpuid(0, 0, 0, 0, 0); // memory barrier
cpuid(0, 0, 0, 0, 0); // memory barrier
cpus[cpu()].booted = 1;
// Enable interrupts on this processor.

20
mkfs.c
View File

@ -81,8 +81,8 @@ main(int argc, char *argv[])
usedblocks = ninodes / IPB + 3 + bitblocks;
freeblock = usedblocks;
printf ("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,
bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks);
printf("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,
bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks);
assert (nblocks + usedblocks == size);
@ -246,22 +246,22 @@ iappend(uint inum, void *xp, int n)
assert(fbn < MAXFILE);
if (fbn < NDIRECT) {
if(xint(din.addrs[fbn]) == 0) {
din.addrs[fbn] = xint(freeblock++);
usedblocks++;
din.addrs[fbn] = xint(freeblock++);
usedblocks++;
}
x = xint(din.addrs[fbn]);
} else {
if(xint(din.addrs[INDIRECT]) == 0) {
printf("allocate indirect block\n");
din.addrs[INDIRECT] = xint(freeblock++);
usedblocks++;
printf("allocate indirect block\n");
din.addrs[INDIRECT] = xint(freeblock++);
usedblocks++;
}
printf("read indirect block\n");
rsect(xint(din.addrs[INDIRECT]), (char *) indirect);
if (indirect[fbn - NDIRECT] == 0) {
indirect[fbn - NDIRECT] = xint(freeblock++);
usedblocks++;
wsect(xint(din.addrs[INDIRECT]), (char *) indirect);
indirect[fbn - NDIRECT] = xint(freeblock++);
usedblocks++;
wsect(xint(din.addrs[INDIRECT]), (char *) indirect);
}
x = xint(indirect[fbn-NDIRECT]);
}

236
mmu.h
View File

@ -3,133 +3,133 @@
*/
// Eflags register
#define FL_CF 0x00000001 // Carry Flag
#define FL_PF 0x00000004 // Parity Flag
#define FL_AF 0x00000010 // Auxiliary carry Flag
#define FL_ZF 0x00000040 // Zero Flag
#define FL_SF 0x00000080 // Sign Flag
#define FL_TF 0x00000100 // Trap Flag
#define FL_IF 0x00000200 // Interrupt Flag
#define FL_DF 0x00000400 // Direction Flag
#define FL_OF 0x00000800 // Overflow Flag
#define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask
#define FL_IOPL_0 0x00000000 // IOPL == 0
#define FL_IOPL_1 0x00001000 // IOPL == 1
#define FL_IOPL_2 0x00002000 // IOPL == 2
#define FL_IOPL_3 0x00003000 // IOPL == 3
#define FL_NT 0x00004000 // Nested Task
#define FL_RF 0x00010000 // Resume Flag
#define FL_VM 0x00020000 // Virtual 8086 mode
#define FL_AC 0x00040000 // Alignment Check
#define FL_VIF 0x00080000 // Virtual Interrupt Flag
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
#define FL_ID 0x00200000 // ID flag
#define FL_CF 0x00000001 // Carry Flag
#define FL_PF 0x00000004 // Parity Flag
#define FL_AF 0x00000010 // Auxiliary carry Flag
#define FL_ZF 0x00000040 // Zero Flag
#define FL_SF 0x00000080 // Sign Flag
#define FL_TF 0x00000100 // Trap Flag
#define FL_IF 0x00000200 // Interrupt Flag
#define FL_DF 0x00000400 // Direction Flag
#define FL_OF 0x00000800 // Overflow Flag
#define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask
#define FL_IOPL_0 0x00000000 // IOPL == 0
#define FL_IOPL_1 0x00001000 // IOPL == 1
#define FL_IOPL_2 0x00002000 // IOPL == 2
#define FL_IOPL_3 0x00003000 // IOPL == 3
#define FL_NT 0x00004000 // Nested Task
#define FL_RF 0x00010000 // Resume Flag
#define FL_VM 0x00020000 // Virtual 8086 mode
#define FL_AC 0x00040000 // Alignment Check
#define FL_VIF 0x00080000 // Virtual Interrupt Flag
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
#define FL_ID 0x00200000 // ID flag
// Segment Descriptor
struct segdesc {
uint lim_15_0 : 16; // Low bits of segment limit
uint base_15_0 : 16; // Low bits of segment base address
uint base_23_16 : 8; // Middle bits of segment base address
uint type : 4; // Segment type (see STS_ constants)
uint s : 1; // 0 = system, 1 = application
uint dpl : 2; // Descriptor Privilege Level
uint p : 1; // Present
uint lim_19_16 : 4; // High bits of segment limit
uint avl : 1; // Unused (available for software use)
uint rsv1 : 1; // Reserved
uint db : 1; // 0 = 16-bit segment, 1 = 32-bit segment
uint g : 1; // Granularity: limit scaled by 4K when set
uint base_31_24 : 8; // High bits of segment base address
uint lim_15_0 : 16; // Low bits of segment limit
uint base_15_0 : 16; // Low bits of segment base address
uint base_23_16 : 8; // Middle bits of segment base address
uint type : 4; // Segment type (see STS_ constants)
uint s : 1; // 0 = system, 1 = application
uint dpl : 2; // Descriptor Privilege Level
uint p : 1; // Present
uint lim_19_16 : 4; // High bits of segment limit
uint avl : 1; // Unused (available for software use)
uint rsv1 : 1; // Reserved
uint db : 1; // 0 = 16-bit segment, 1 = 32-bit segment
uint g : 1; // Granularity: limit scaled by 4K when set
uint base_31_24 : 8; // High bits of segment base address
};
// Null segment
#define SEG_NULL (struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
#define SEG_NULL (struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
// Normal segment
#define SEG(type, base, lim, dpl) (struct segdesc) \
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \
#define SEG(type, base, lim, dpl) (struct segdesc) \
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \
(uint) (base) >> 24 }
#define SEG16(type, base, lim, dpl) (struct segdesc) \
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \
#define SEG16(type, base, lim, dpl) (struct segdesc) \
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \
(uint) (base) >> 24 }
// Application segment type bits
#define STA_X 0x8 // Executable segment
#define STA_E 0x4 // Expand down (non-executable segments)
#define STA_C 0x4 // Conforming code segment (executable only)
#define STA_W 0x2 // Writeable (non-executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed
#define STA_X 0x8 // Executable segment
#define STA_E 0x4 // Expand down (non-executable segments)
#define STA_C 0x4 // Conforming code segment (executable only)
#define STA_W 0x2 // Writeable (non-executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed
// System segment type bits
#define STS_T16A 0x1 // Available 16-bit TSS
#define STS_LDT 0x2 // Local Descriptor Table
#define STS_T16B 0x3 // Busy 16-bit TSS
#define STS_CG16 0x4 // 16-bit Call Gate
#define STS_TG 0x5 // Task Gate / Coum Transmitions
#define STS_IG16 0x6 // 16-bit Interrupt Gate
#define STS_TG16 0x7 // 16-bit Trap Gate
#define STS_T32A 0x9 // Available 32-bit TSS
#define STS_T32B 0xB // Busy 32-bit TSS
#define STS_CG32 0xC // 32-bit Call Gate
#define STS_IG32 0xE // 32-bit Interrupt Gate
#define STS_TG32 0xF // 32-bit Trap Gate
#define STS_T16A 0x1 // Available 16-bit TSS
#define STS_LDT 0x2 // Local Descriptor Table
#define STS_T16B 0x3 // Busy 16-bit TSS
#define STS_CG16 0x4 // 16-bit Call Gate
#define STS_TG 0x5 // Task Gate / Coum Transmitions
#define STS_IG16 0x6 // 16-bit Interrupt Gate
#define STS_TG16 0x7 // 16-bit Trap Gate
#define STS_T32A 0x9 // Available 32-bit TSS
#define STS_T32B 0xB // Busy 32-bit TSS
#define STS_CG32 0xC // 32-bit Call Gate
#define STS_IG32 0xE // 32-bit Interrupt Gate
#define STS_TG32 0xF // 32-bit Trap Gate
// Task state segment format
struct taskstate {
uint link; // Old ts selector
uint esp0; // Stack pointers and segment selectors
ushort ss0; // after an increase in privilege level
ushort padding1;
uint * esp1;
ushort ss1;
ushort padding2;
uint * esp2;
ushort ss2;
ushort padding3;
void * cr3; // Page directory base
uint * eip; // Saved state from last task switch
uint eflags;
uint eax; // More saved state (registers)
uint ecx;
uint edx;
uint ebx;
uint * esp;
uint * ebp;
uint esi;
uint edi;
ushort es; // Even more saved state (segment selectors)
ushort padding4;
ushort cs;
ushort padding5;
ushort ss;
ushort padding6;
ushort ds;
ushort padding7;
ushort fs;
ushort padding8;
ushort gs;
ushort padding9;
ushort ldt;
ushort padding10;
ushort t; // Trap on task switch
ushort iomb; // I/O map base address
uint link; // Old ts selector
uint esp0; // Stack pointers and segment selectors
ushort ss0; // after an increase in privilege level
ushort padding1;
uint * esp1;
ushort ss1;
ushort padding2;
uint * esp2;
ushort ss2;
ushort padding3;
void * cr3; // Page directory base
uint * eip; // Saved state from last task switch
uint eflags;
uint eax; // More saved state (registers)
uint ecx;
uint edx;
uint ebx;
uint * esp;
uint * ebp;
uint esi;
uint edi;
ushort es; // Even more saved state (segment selectors)
ushort padding4;
ushort cs;
ushort padding5;
ushort ss;
ushort padding6;
ushort ds;
ushort padding7;
ushort fs;
ushort padding8;
ushort gs;
ushort padding9;
ushort ldt;
ushort padding10;
ushort t; // Trap on task switch
ushort iomb; // I/O map base address
};
// Gate descriptors for interrupts and traps
struct gatedesc {
uint off_15_0 : 16; // low 16 bits of offset in segment
uint ss : 16; // segment selector
uint args : 5; // # args, 0 for interrupt/trap gates
uint rsv1 : 3; // reserved(should be zero I guess)
uint type : 4; // type(STS_{TG,IG32,TG32})
uint s : 1; // must be 0 (system)
uint dpl : 2; // descriptor(meaning new) privilege level
uint p : 1; // Present
uint off_31_16 : 16; // high bits of offset in segment
uint off_15_0 : 16; // low 16 bits of offset in segment
uint ss : 16; // segment selector
uint args : 5; // # args, 0 for interrupt/trap gates
uint rsv1 : 3; // reserved(should be zero I guess)
uint type : 4; // type(STS_{TG,IG32,TG32})
uint s : 1; // must be 0 (system)
uint dpl : 2; // descriptor(meaning new) privilege level
uint p : 1; // Present
uint off_31_16 : 16; // high bits of offset in segment
};
// Set up a normal interrupt/trap gate descriptor.
@ -138,18 +138,18 @@ struct gatedesc {
// - sel: Code segment selector for interrupt/trap handler
// - off: Offset in code segment for interrupt/trap handler
// - dpl: Descriptor Privilege Level -
// the privilege level required for software to invoke
// this interrupt/trap gate explicitly using an int instruction.
#define SETGATE(gate, istrap, sel, off, d) \
{ \
(gate).off_15_0 = (uint) (off) & 0xffff; \
(gate).ss = (sel); \
(gate).args = 0; \
(gate).rsv1 = 0; \
(gate).type = (istrap) ? STS_TG32 : STS_IG32; \
(gate).s = 0; \
(gate).dpl = (d); \
(gate).p = 1; \
(gate).off_31_16 = (uint) (off) >> 16; \
// the privilege level required for software to invoke
// this interrupt/trap gate explicitly using an int instruction.
#define SETGATE(gate, istrap, sel, off, d) \
{ \
(gate).off_15_0 = (uint) (off) & 0xffff; \
(gate).ss = (sel); \
(gate).args = 0; \
(gate).rsv1 = 0; \
(gate).type = (istrap) ? STS_TG32 : STS_IG32; \
(gate).s = 0; \
(gate).dpl = (d); \
(gate).p = 1; \
(gate).off_31_16 = (uint) (off) >> 16; \
}

58
mp.c
View File

@ -8,25 +8,25 @@
#include "proc.h"
static char* buses[] = {
"CBUSI ",
"CBUSII",
"EISA ",
"FUTURE",
"INTERN",
"ISA ",
"MBI ",
"MBII ",
"MCA ",
"MPI ",
"MPSA ",
"NUBUS ",
"PCI ",
"PCMCIA",
"TC ",
"VL ",
"VME ",
"XPRESS",
0,
"CBUSI ",
"CBUSII",
"EISA ",
"FUTURE",
"INTERN",
"ISA ",
"MBI ",
"MBII ",
"MCA ",
"MPI ",
"MPSA ",
"NUBUS ",
"PCI ",
"PCMCIA",
"TC ",
"VL ",
"VME ",
"XPRESS",
0,
};
struct cpu cpus[NCPU];
@ -146,7 +146,7 @@ mp_init(void)
proc = (struct mppe *) p;
cpus[ncpu].apicid = proc->apicid;
if (proc->flags & MPBP) {
bcpu = &cpus[ncpu];
bcpu = &cpus[ncpu];
}
ncpu++;
p += sizeof(struct mppe);
@ -154,8 +154,8 @@ mp_init(void)
case MPBUS:
bus = (struct mpbe *) p;
for(i = 0; buses[i]; i++){
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
break;
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
break;
}
p += sizeof(struct mpbe);
continue;
@ -171,18 +171,18 @@ mp_init(void)
default:
cprintf("mpinit: unknown PCMP type 0x%x (e-p 0x%x)\n", *p, e-p);
while(p < e){
cprintf("%uX ", *p);
p++;
cprintf("%uX ", *p);
p++;
}
break;
}
}
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 */
}
}
@ -205,7 +205,7 @@ mp_startthem(void)
int c;
memmove((void *) APBOOTCODE,_binary_bootother_start,
(uint) _binary_bootother_size);
(uint) _binary_bootother_size);
for(c = 0; c < ncpu; c++){
if (c == cpu()) continue;

170
mp.h
View File

@ -3,121 +3,121 @@
*
*/
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,
MPHIERARCHY = 0x81,
MPCBASM = 0x82,
/* PCMPprocessor and PCMPioapic flags */
MPEN = 0x01, /* enabled */
MPBP = 0x02, /* bootstrap processor */
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 */
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.
* 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_NMI = 0x00000400,
APIC_INIT = 0x00000500, /* INIT/RESET */
APIC_STARTUP = 0x00000600, /* Startup IPI */
APIC_EXTINT = 0x00000700,
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_EXTINT = 0x00000700,
APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */
APIC_LOGICAL = 0x00000800,
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_LOW = 0x00002000,
APIC_REMOTEIRR = 0x00004000, /* [14] Remote IRR (RO) */
APIC_EDGE = 0x00000000, /* [15] Trigger Mode (RW) */
APIC_LEVEL = 0x00008000,
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */
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_LEVEL = 0x00008000,
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */
};

View File

@ -4,10 +4,10 @@
#include "defs.h"
// I/O Addresses of the two 8259A programmable interrupt controllers
#define IO_PIC1 0x20 // Master (IRQs 0-7)
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
#define IO_PIC1 0x20 // Master (IRQs 0-7)
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
// Current IRQ mask.
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
@ -49,19 +49,19 @@ pic_init(void)
// n: 1 = special fully nested mode
// b: 1 = buffered mode
// m: 0 = slave PIC, 1 = master PIC
// (ignored when b is 0, as the master/slave role
// can be hardwired).
// (ignored when b is 0, as the master/slave role
// can be hardwired).
// a: 1 = Automatic EOI mode
// p: 0 = MCS-80/85 mode, 1 = intel x86 mode
outb(IO_PIC1+1, 0x3);
// Set up slave (8259A-2)
outb(IO_PIC2, 0x11); // ICW1
outb(IO_PIC2+1, IRQ_OFFSET + 8); // ICW2
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
outb(IO_PIC2, 0x11); // ICW1
outb(IO_PIC2+1, IRQ_OFFSET + 8); // ICW2
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
// NB Automatic EOI mode doesn't tend to work on the slave.
// Linux source code says it's "to be investigated".
outb(IO_PIC2+1, 0x3); // ICW4
outb(IO_PIC2+1, 0x3); // ICW4
// OCW3: 0ef01prs
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask

View File

@ -65,8 +65,8 @@ printf(int fd, char *fmt, ...)
s++;
}
} else if(c == 'c'){
putc(fd, *ap);
ap++;
putc(fd, *ap);
ap++;
} else if(c == '%'){
putc(fd, c);
} else {

View File

@ -1,37 +1,35 @@
.globl setjmp
setjmp:
movl 4(%esp), %eax
movl %ebx, 0(%eax)
movl %ecx, 4(%eax)
movl %edx, 8(%eax)
movl %esi, 12(%eax)
movl %edi, 16(%eax)
movl %esp, 20(%eax)
movl %ebp, 24(%eax)
pushl 0(%esp) /* %eip */
popl 28(%eax)
movl $0, %eax /* return value */
ret
movl 4(%esp), %eax
movl %ebx, 0(%eax)
movl %ecx, 4(%eax)
movl %edx, 8(%eax)
movl %esi, 12(%eax)
movl %edi, 16(%eax)
movl %esp, 20(%eax)
movl %ebp, 24(%eax)
pushl 0(%esp) /* %eip */
popl 28(%eax)
movl $0, %eax /* return value */
ret
.globl longjmp
longjmp:
movl 4(%esp), %eax
movl 0(%eax), %ebx
movl 4(%eax), %ecx
movl 8(%eax), %edx
movl 12(%eax), %esi
movl 16(%eax), %edi
movl 20(%eax), %esp
movl 24(%eax), %ebp
movl 4(%esp), %eax
movl 0(%eax), %ebx
movl 4(%eax), %ecx
movl 8(%eax), %edx
movl 12(%eax), %esi
movl 16(%eax), %edi
movl 20(%eax), %esp
movl 24(%eax), %ebp
addl $4, %esp /* pop %eip into thin air */
pushl 28(%eax) /* push new %eip */
movl $1, %eax /* return value (appears to come from setjmp!) */
ret
addl $4, %esp /* pop %eip into thin air */
pushl 28(%eax) /* push new %eip */
movl $1, %eax /* return value (appears to come from setjmp!) */
ret

124
sh.c
View File

@ -68,28 +68,28 @@ parse(char *s)
while (1) {
switch ((c = gettoken(0, &t))) {
case 'w': // Add an argument
case 'w': // Add an argument
if (cmdlist[nextcmd].argc >= MAXARGS) {
printf(2, "too many arguments\n");
return -1;
printf(2, "too many arguments\n");
return -1;
}
cmdlist[nextcmd].argv[cmdlist[nextcmd].argc++] = t;
break;
case '<': // Input redirection
case '<': // Input redirection
// Grab the filename from the argument list
if (gettoken(0, &t) != 'w') {
printf(2, "syntax error: < not followed by word\n");
return -1;
printf(2, "syntax error: < not followed by word\n");
return -1;
}
addio('<', t);
break;
case '>': // Output redirection
case '>': // Output redirection
// Grab the filename from the argument list
if (gettoken(0, &t) != 'w') {
printf(2, "syntax error: > not followed by word\n");
return -1;
printf(2, "syntax error: > not followed by word\n");
return -1;
}
addio('>', t);
break;
@ -100,13 +100,13 @@ parse(char *s)
nextcmd++;
break;
case 0: // String is complete
case 0: // String is complete
return 0;
default:
printf(2, "syntax error: bad return %d from gettoken", c);
return -1;
}
}
}
@ -136,14 +136,14 @@ runcmd(void)
cmdlist[c].argv[0] = cmdlist[c].argv0buf;
}
cmdlist[c].argv[cmdlist[c].argc] = 0;
// Print the command.
if (debug) {
printf(2, "[%d] SPAWN:", getpid());
for (i = 0; cmdlist[c].argv[i]; i++)
printf(2, " %s", cmdlist[c].argv[i]);
printf(2, " %s", cmdlist[c].argv[i]);
for (i = 0; i < nextio; i++) {
printf(2, "%c %s", iolist[i].token, iolist[i].s);
printf(2, "%c %s", iolist[i].token, iolist[i].s);
}
printf(2, "\n");
}
@ -156,55 +156,55 @@ runcmd(void)
if (cmdlist[c].token == '|')
if (pipe(fdarray) < 0)
printf(2, "cmd %d pipe failed\n", c);
printf(2, "cmd %d pipe failed\n", c);
pid = fork();
if (pid == 0) {
if (cmdlist[c].token == '|') {
if (close(1) < 0)
printf(2, "close 1 failed\n");
if ((tfd = dup(fdarray[1])) < 0)
printf(2, "dup failed\n");
if (close(fdarray[0]) < 0)
printf(2, "close fdarray[0] failed\n");
if (close(fdarray[1]) < 0)
printf(2, "close fdarray[1] failed\n");
if (close(1) < 0)
printf(2, "close 1 failed\n");
if ((tfd = dup(fdarray[1])) < 0)
printf(2, "dup failed\n");
if (close(fdarray[0]) < 0)
printf(2, "close fdarray[0] failed\n");
if (close(fdarray[1]) < 0)
printf(2, "close fdarray[1] failed\n");
}
if (c > 0 && cmdlist[c-1].token == '|') {
if (close(0) < 0)
printf(2, "close 0 failed\n");
if ((tfd = dup(fdarray[0])) < 0)
printf(2, "dup failed\n");
if (close(fdarray[0]) < 0)
printf(2, "close fdarray[0] failed\n");
if (close(fdarray[1]) < 0)
printf(2, "close fdarray[1] failed\n");
if (close(0) < 0)
printf(2, "close 0 failed\n");
if ((tfd = dup(fdarray[0])) < 0)
printf(2, "dup failed\n");
if (close(fdarray[0]) < 0)
printf(2, "close fdarray[0] failed\n");
if (close(fdarray[1]) < 0)
printf(2, "close fdarray[1] failed\n");
}
if (ioredirection() < 0)
exit();
exit();
if ((r = exec(cmdlist[c].argv0buf, (char**) cmdlist[c].argv)) < 0) {
printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r);
exit();
printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r);
exit();
}
} else if (pid > 0) {
int p;
if (debug)
printf(2, "[%d] FORKED child %d\n", getpid(), pid);
printf(2, "[%d] FORKED child %d\n", getpid(), pid);
if (c > 0 && cmdlist[c-1].token == '|') {
close(fdarray[0]);
close(fdarray[1]);
close(fdarray[0]);
close(fdarray[1]);
}
if (cmdlist[c].token != '|') {
if (debug)
printf(2, "[%d] WAIT for children\n", getpid());
do {
p = wait();
if (debug)
printf(2, "[%d] WAIT child %d finished\n", getpid(), p);
} while (p > 0);
if (debug)
printf(2, "[%d] wait finished\n", getpid());
if (debug)
printf(2, "[%d] WAIT for children\n", getpid());
do {
p = wait();
if (debug)
printf(2, "[%d] WAIT child %d finished\n", getpid(), p);
} while (p > 0);
if (debug)
printf(2, "[%d] wait finished\n", getpid());
}
}
}
@ -219,23 +219,23 @@ ioredirection(void)
switch (iolist[i].token) {
case '<':
if (close(0) < 0)
printf(2, "close 0 failed\n");
printf(2, "close 0 failed\n");
if ((fd = open(iolist[i].s, O_RDONLY)) < 0) {
printf(2, "failed to open %s for read: %d", iolist[i].s, fd);
return -1;
printf(2, "failed to open %s for read: %d", iolist[i].s, fd);
return -1;
}
if (debug)
printf(2, "redirect 0 from %s\n", iolist[i].s);
printf(2, "redirect 0 from %s\n", iolist[i].s);
break;
case '>':
if (close(1) < 0)
printf(2, "close 1 failed\n");
printf(2, "close 1 failed\n");
if ((fd = open(iolist[i].s, O_WRONLY|O_CREATE)) < 0) {
printf(2, "failed to open %s for write: %d", iolist[i].s, fd);
exit();
printf(2, "failed to open %s for write: %d", iolist[i].s, fd);
exit();
}
if (debug)
printf(2, "redirect 1 to %s\n", iolist[i].s);
printf(2, "redirect 1 to %s\n", iolist[i].s);
break;
}
}
@ -283,11 +283,11 @@ gettoken(char *s, char **p1)
// Get the next token from string s.
// Set *p1 to the beginning of the token and *p2 just past the token.
// Returns
// 0 for end-of-string;
// < for <;
// > for >;
// | for |;
// w for a word.
// 0 for end-of-string;
// < for <;
// > for >;
// | for |;
// w for a word.
//
// Eventually (once we parse the space where the \0 will go),
// words get nul-terminated.

View File

@ -5,8 +5,8 @@ open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!";
$n = sysread(SIG, $buf, 1000);
if($n > 510){
print STDERR "boot block too large: $n bytes (max 510)\n";
exit 1;
print STDERR "boot block too large: $n bytes (max 510)\n";
exit 1;
}
print STDERR "boot block is $n bytes (max 510)\n";

View File

@ -40,7 +40,7 @@ acquire(struct spinlock * lock)
while(cmpxchg(0, 1, &lock->locked) == 1)
;
cpuid(0, 0, 0, 0, 0); // memory barrier
cpuid(0, 0, 0, 0, 0); // memory barrier
getcallerpcs(&lock, lock->pcs);
lock->cpu = cpu() + 10;
}
@ -54,7 +54,7 @@ release(struct spinlock * lock)
lock->pcs[0] = 0;
lock->cpu = 0xffffffff;
cpuid(0, 0, 0, 0, 0); // memory barrier
cpuid(0, 0, 0, 0, 0); // memory barrier
lock->locked = 0;
if(--cpus[cpu()].nlock == 0)
sti();

View File

@ -32,7 +32,7 @@ memmove(void *dst, const void *src, uint n)
{
const char *s;
char *d;
s = src;
d = dst;
if (s < d && s + n > d) {
@ -50,10 +50,10 @@ memmove(void *dst, const void *src, uint n)
int
strncmp(const char *p, const char *q, uint n)
{
while (n > 0 && *p && *p == *q)
n--, p++, q++;
if (n == 0)
return 0;
else
return (int) ((uchar) *p - (uchar) *q);
while (n > 0 && *p && *p == *q)
n--, p++, q++;
if (n == 0)
return 0;
else
return (int) ((uchar) *p - (uchar) *q);
}

2
trap.c
View File

@ -86,7 +86,7 @@ trap(struct trapframe *tf)
if(curproc[cpu()]) {
cprintf("pid %d: unhandled trap %d on cpu %d eip %x---terminate process\n",
curproc[cpu()]->pid, v, cpu(), tf->eip);
curproc[cpu()]->pid, v, cpu(), tf->eip);
proc_exit();
}
cprintf("unexpected trap %d from cpu %d eip %x\n", v, cpu(), tf->eip);

View File

@ -1,38 +1,38 @@
.text
.text
.globl trap
.globl trapret1
.globl alltraps
alltraps:
/* vectors.S sends all traps here */
pushl %ds # build
pushl %es # trap
pushal # frame
movl $16,%eax # SEG_KDATA << 3
movw %ax,%ds # kernel
movw %ax,%es # segments
pushl %esp # pass pointer to this trapframe
call trap # and call trap()
addl $4, %esp
# return falls through to trapret...
/*
* a forked process RETs here
* expects ESP to point to a Trapframe
*/
/* vectors.S sends all traps here */
pushl %ds # build
pushl %es # trap
pushal # frame
movl $16,%eax # SEG_KDATA << 3
movw %ax,%ds # kernel
movw %ax,%es # segments
pushl %esp # pass pointer to this trapframe
call trap # and call trap()
addl $4, %esp
# return falls through to trapret...
/*
* a forked process RETs here
* expects ESP to point to a Trapframe
*/
.globl trapret
trapret:
popal
popl %es
popl %ds
addl $0x8, %esp /* trapno and errcode */
iret
popal
popl %es
popl %ds
addl $0x8, %esp /* trapno and errcode */
iret
.globl forkret1
forkret1:
movl 4(%esp), %esp
jmp trapret
.globl acpu
movl 4(%esp), %esp
jmp trapret
.globl acpu
acpu:
.long 0
.long 0

48
traps.h
View File

@ -1,33 +1,33 @@
// system defined:
#define T_DIVIDE 0 // divide error
#define T_DEBUG 1 // debug exception
#define T_NMI 2 // non-maskable interrupt
#define T_BRKPT 3 // breakpoint
#define T_OFLOW 4 // overflow
#define T_BOUND 5 // bounds check
#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_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_FPERR 16 // floating point error
#define T_ALIGN 17 // aligment check
#define T_MCHK 18 // machine check
#define T_SIMDERR 19 // SIMD floating point error
#define T_DIVIDE 0 // divide error
#define T_DEBUG 1 // debug exception
#define T_NMI 2 // non-maskable interrupt
#define T_BRKPT 3 // breakpoint
#define T_OFLOW 4 // overflow
#define T_BOUND 5 // bounds check
#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_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_FPERR 16 // floating point error
#define T_ALIGN 17 // aligment check
#define T_MCHK 18 // machine check
#define T_SIMDERR 19 // SIMD floating point error
// These are arbitrarily chosen, but with care not to overlap
// processor defined exceptions or interrupt vectors.
#define T_SYSCALL 48 // system call
#define T_DEFAULT 500 // catchall
#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_KBD 1
#define IRQ_IDE 14
#define IRQ_TIMER 18
#define IRQ_ERROR 19

32
ulib.c
View File

@ -12,20 +12,20 @@ puts(char *s)
char*
strcpy(char *s, char *t)
{
char *os;
os = s;
while((*s++ = *t++) != 0)
;
return os;
char *os;
os = s;
while((*s++ = *t++) != 0)
;
return os;
}
int
strcmp(const char *p, const char *q)
{
while (*p && *p == *q)
p++, q++;
return (int) ((unsigned char) *p - (unsigned char) *q);
while (*p && *p == *q)
p++, q++;
return (int) ((unsigned char) *p - (unsigned char) *q);
}
unsigned int
@ -37,7 +37,7 @@ strlen(char *s)
return n;
}
void *
void*
memset(void *dst, int c, unsigned int n)
{
char *d = (char *) dst;
@ -48,16 +48,16 @@ memset(void *dst, int c, unsigned int n)
return dst;
}
char *
char*
strchr(const char *s, char c)
{
for (; *s; s++)
if (*s == c)
return (char *) s;
return 0;
for (; *s; s++)
if (*s == c)
return (char *) s;
return 0;
}
char *
char*
gets(char *buf, int max)
{
int i = 0, cc;

View File

@ -74,17 +74,17 @@ malloc(uint nbytes)
for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
if (p->s.size >= nunits) {
if (p->s.size == nunits)
prevp->s.ptr = p->s.ptr;
prevp->s.ptr = p->s.ptr;
else {
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void *) (p + 1);
}
if (p == freep)
if ((p = morecore(nunits)) == 0)
return 0;
return 0;
}
}

View File

@ -115,8 +115,8 @@ writetest1(void)
i = read(fd, buf, 512);
if (i == 0) {
if (n == MAXFILE - 1) {
printf(stdout, "read only %d blocks from big", n);
exit();
printf(stdout, "read only %d blocks from big", n);
exit();
}
break;
} else if (i != 512) {

10
usys.S
View File

@ -2,11 +2,11 @@
#include "traps.h"
#define STUB(name) \
.globl name; \
name: \
movl $SYS_ ## name, %eax; \
int $T_SYSCALL; \
ret
.globl name; \
name: \
movl $SYS_ ## name, %eax; \
int $T_SYSCALL; \
ret
STUB(fork)
STUB(exit)

View File

@ -13,10 +13,10 @@ for(my $i = 0; $i < 256; $i++){
print ".globl vector$i\n";
print "vector$i:\n";
if(($i < 8 || $i > 14) && $i != 17){
print "\tpushl \$0\n";
print " pushl \$0\n";
}
print "\tpushl \$$i\n";
print "\tjmp alltraps\n";
print " pushl \$$i\n";
print " jmp alltraps\n";
}
print "\n/* vector table */\n";
@ -24,5 +24,5 @@ print ".data\n";
print ".globl vectors\n";
print "vectors:\n";
for(my $i = 0; $i < 256; $i++){
print "\t.long vector$i\n";
print " .long vector$i\n";
}

142
x86.h
View File

@ -1,39 +1,39 @@
static __inline uchar
inb(int port)
{
uchar data;
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
return data;
uchar data;
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static __inline void
insl(int port, void *addr, int cnt)
{
__asm __volatile("cld\n\trepne\n\tinsl" :
"=D" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"memory", "cc");
__asm __volatile("cld\n\trepne\n\tinsl" :
"=D" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"memory", "cc");
}
static __inline void
outb(int port, uchar data)
{
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
}
static __inline void
outw(int port, ushort data)
{
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
}
static __inline void
outsl(int port, const void *addr, int cnt)
{
__asm __volatile("cld\n\trepne\n\toutsl" :
"=S" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"cc");
__asm __volatile("cld\n\trepne\n\toutsl" :
"=S" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"cc");
}
struct segdesc;
@ -41,13 +41,13 @@ struct segdesc;
static __inline void
lgdt(struct segdesc *p, int size)
{
volatile ushort pd[3];
volatile ushort pd[3];
pd[0] = size-1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
pd[0] = size-1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
asm volatile("lgdt (%0)" : : "g" (pd));
asm volatile("lgdt (%0)" : : "g" (pd));
}
struct gatedesc;
@ -55,99 +55,99 @@ struct gatedesc;
static __inline void
lidt(struct gatedesc *p, int size)
{
volatile ushort pd[3];
volatile ushort pd[3];
pd[0] = size-1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
pd[0] = size-1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
asm volatile("lidt (%0)" : : "g" (pd));
asm volatile("lidt (%0)" : : "g" (pd));
}
static __inline void
ltr(ushort sel)
{
__asm __volatile("ltr %0" : : "r" (sel));
__asm __volatile("ltr %0" : : "r" (sel));
}
static __inline uint
read_eflags(void)
{
uint eflags;
__asm __volatile("pushfl; popl %0" : "=r" (eflags));
return eflags;
uint eflags;
__asm __volatile("pushfl; popl %0" : "=r" (eflags));
return eflags;
}
static __inline void
write_eflags(uint eflags)
{
__asm __volatile("pushl %0; popfl" : : "r" (eflags));
__asm __volatile("pushl %0; popfl" : : "r" (eflags));
}
static __inline void
cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
{
uint eax, ebx, ecx, edx;
asm volatile("cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (info));
if (eaxp)
*eaxp = eax;
if (ebxp)
*ebxp = ebx;
if (ecxp)
*ecxp = ecx;
if (edxp)
*edxp = edx;
uint eax, ebx, ecx, edx;
asm volatile("cpuid" :
"=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) :
"a" (info));
if (eaxp)
*eaxp = eax;
if (ebxp)
*ebxp = ebx;
if (ecxp)
*ecxp = ecx;
if (edxp)
*edxp = edx;
}
static __inline uint
cmpxchg(uint oldval, uint newval, volatile uint* lock_addr)
{
uint result;
__asm__ __volatile__(
"lock; cmpxchgl %2, %0"
:"+m" (*lock_addr), "=a" (result) : "r"(newval), "1"(oldval) : "cc"
);
__asm__ __volatile__("lock; cmpxchgl %2, %0" :
"+m" (*lock_addr), "=a" (result) :
"r"(newval), "1"(oldval) :
"cc");
return result;
}
static __inline void
cli(void)
{
__asm__ volatile("cli");
__asm__ volatile("cli");
}
static __inline void
sti(void)
{
__asm__ volatile("sti");
__asm__ volatile("sti");
}
struct trapframe {
/* registers as pushed by pusha */
uint edi;
uint esi;
uint ebp;
uint oesp; /* Useless */
uint ebx;
uint edx;
uint ecx;
uint eax;
/* rest of trap frame */
ushort es;
ushort padding1;
ushort ds;
ushort padding2;
uint trapno;
/* 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 */
uint esp;
ushort ss;
ushort padding4;
/* registers as pushed by pusha */
uint edi;
uint esi;
uint ebp;
uint oesp; /* Useless */
uint ebx;
uint edx;
uint ecx;
uint eax;
/* rest of trap frame */
ushort es;
ushort padding1;
ushort ds;
ushort padding2;
uint trapno;
/* 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 */
uint esp;
ushort ss;
ushort padding4;
};