wrap long lines
This commit is contained in:
parent
db8fb62e4d
commit
0cfc7290e8
18 changed files with 181 additions and 154 deletions
12
asm.h
12
asm.h
|
@ -11,9 +11,9 @@
|
||||||
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
|
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
|
||||||
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
|
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
|
||||||
|
|
||||||
#define STA_X 0x8 // Executable segment
|
#define STA_X 0x8 // Executable segment
|
||||||
#define STA_E 0x4 // Expand down (non-executable segments)
|
#define STA_E 0x4 // Expand down (non-executable segments)
|
||||||
#define STA_C 0x4 // Conforming code segment (executable only)
|
#define STA_C 0x4 // Conforming code segment (executable only)
|
||||||
#define STA_W 0x2 // Writeable (non-executable segments)
|
#define STA_W 0x2 // Writeable (non-executable segments)
|
||||||
#define STA_R 0x2 // Readable (executable segments)
|
#define STA_R 0x2 // Readable (executable segments)
|
||||||
#define STA_A 0x1 // Accessed
|
#define STA_A 0x1 // Accessed
|
||||||
|
|
3
bio.c
3
bio.c
|
@ -41,7 +41,8 @@ getblk(uint dev, uint sector)
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
for(b = bufhead.next; b != &bufhead; b = b->next)
|
for(b = bufhead.next; b != &bufhead; b = b->next)
|
||||||
if((b->flags & (B_BUSY|B_VALID)) && b->dev == dev && b->sector == sector)
|
if((b->flags & (B_BUSY|B_VALID)) &&
|
||||||
|
b->dev == dev && b->sector == sector)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(b != &bufhead){
|
if(b != &bufhead){
|
||||||
|
|
46
bootasm.S
46
bootasm.S
|
@ -4,7 +4,7 @@
|
||||||
.set PROT_MODE_DSEG,0x10 # data 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.
|
# This code should be stored in the first sector of the hard disk.
|
||||||
# After the BIOS initializes the hardware on startup or system reset,
|
# After the BIOS initializes the hardware on startup or system reset,
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
#
|
#
|
||||||
# This code switches into 32-bit protected mode so that all of
|
# This code switches into 32-bit protected mode so that all of
|
||||||
# memory can accessed, then calls into C.
|
# memory can accessed, then calls into C.
|
||||||
###################################################################################
|
#########################################################################
|
||||||
|
|
||||||
.globl start # Entry point
|
.globl start # Entry point
|
||||||
start:
|
start:
|
||||||
|
@ -32,13 +32,13 @@ start:
|
||||||
# Set up the stack pointer, growing downward from 0x7c00.
|
# Set up the stack pointer, growing downward from 0x7c00.
|
||||||
movw $start,%sp # Stack Pointer
|
movw $start,%sp # Stack Pointer
|
||||||
|
|
||||||
#### Enable A20:
|
# Enable A20:
|
||||||
#### For fascinating historical reasons (related to the fact that
|
# For fascinating historical reasons (related to the fact that
|
||||||
#### the earliest 8086-based PCs could only address 1MB of physical memory
|
# the earliest 8086-based PCs could only address 1MB of physical
|
||||||
#### and subsequent 80286-based PCs wanted to retain maximum compatibility),
|
# memory and subsequent 80286-based PCs wanted to retain maximum
|
||||||
#### physical address line 20 is tied to low when the machine boots.
|
# compatibility), physical address line 20 is tied to low when the
|
||||||
#### Obviously this a bit of a drag for us, especially when trying to
|
# machine boots. Obviously this a bit of a drag for us, especially
|
||||||
#### address memory above 1MB. This code undoes this.
|
# when trying to address memory above 1MB. This code undoes this.
|
||||||
|
|
||||||
seta20.1:
|
seta20.1:
|
||||||
inb $0x64,%al # Get status
|
inb $0x64,%al # Get status
|
||||||
|
@ -54,22 +54,22 @@ seta20.2:
|
||||||
movb $0xdf,%al # Enable
|
movb $0xdf,%al # Enable
|
||||||
outb %al,$0x60 # A20
|
outb %al,$0x60 # A20
|
||||||
|
|
||||||
#### Switch from real to protected mode
|
# Switch from real to protected mode
|
||||||
#### The descriptors in our GDT allow all physical memory to be accessed.
|
# The descriptors in our GDT allow all physical memory to be accessed.
|
||||||
#### Furthermore, the descriptors have base addresses of 0, so that the
|
# Furthermore, the descriptors have base addresses of 0, so that the
|
||||||
#### segment translation is a NOP, ie. virtual addresses are identical to
|
# segment translation is a NOP, ie. virtual addresses are identical to
|
||||||
#### their physical addresses. With this setup, immediately after
|
# their physical addresses. With this setup, immediately after
|
||||||
#### enabling protected mode it will still appear to this code
|
# enabling protected mode it will still appear to this code
|
||||||
#### that it is running directly on physical memory with no translation.
|
# that it is running directly on physical memory with no translation.
|
||||||
#### This initial NOP-translation setup is required by the processor
|
# This initial NOP-translation setup is required by the processor
|
||||||
#### to ensure that the transition to protected mode occurs smoothly.
|
# to ensure that the transition to protected mode occurs smoothly.
|
||||||
|
|
||||||
real_to_prot:
|
real_to_prot:
|
||||||
cli # Mandatory since we dont set up an IDT
|
cli # Mandatory since we dont set up an IDT
|
||||||
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
||||||
movl %cr0, %eax # turn on protected mode
|
movl %cr0, %eax # turn on protected mode
|
||||||
orl $CR0_PE_ON, %eax #
|
orl $CR0_PE_ON, %eax #
|
||||||
movl %eax, %cr0 #
|
movl %eax, %cr0 #
|
||||||
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
|
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
|
||||||
### Has the effect of just jmp to the next instruction, but simultaneous
|
### Has the effect of just jmp to the next instruction, but simultaneous
|
||||||
### loads CS with $PROT_MODE_CSEG.
|
### loads CS with $PROT_MODE_CSEG.
|
||||||
|
|
10
bootmain.c
10
bootmain.c
|
@ -1,6 +1,3 @@
|
||||||
#include "types.h"
|
|
||||||
#include "elf.h"
|
|
||||||
#include "x86.h"
|
|
||||||
// This a dirt simple boot loader, whose sole job is to boot
|
// This a dirt simple boot loader, whose sole job is to boot
|
||||||
// an elf kernel image from the first IDE hard disk.
|
// an elf kernel image from the first IDE hard disk.
|
||||||
//
|
//
|
||||||
|
@ -25,7 +22,12 @@
|
||||||
// * control starts in bootloader.S -- which sets up protected mode,
|
// * control starts in bootloader.S -- which sets up protected mode,
|
||||||
// and a stack so C code then run, then calls cmain()
|
// and a stack so C code then run, then calls cmain()
|
||||||
//
|
//
|
||||||
// * cmain() in this file takes over, reads in the kernel and jumps to it.
|
// * cmain() in this file takes over,
|
||||||
|
// reads in the kernel and jumps to it.
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "elf.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
#define SECTSIZE 512
|
#define SECTSIZE 512
|
||||||
#define ELFHDR ((struct elfhdr*) 0x10000) // scratch space
|
#define ELFHDR ((struct elfhdr*) 0x10000) // scratch space
|
||||||
|
|
80
bootother.S
80
bootother.S
|
@ -1,20 +1,17 @@
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
|
|
||||||
/*
|
# Start an Application Processor. This must be placed on a 4KB boundary
|
||||||
* Start an Application Processor. This must be placed on a 4KB boundary
|
# somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
|
||||||
* somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
|
# due to some shortcuts below it's restricted further to within the 1st
|
||||||
* due to some shortcuts below it's restricted further to within the 1st
|
# 64KB. The AP starts in real-mode, with
|
||||||
* 64KB. The AP starts in real-mode, with
|
# CS selector set to the startup memory address/16;
|
||||||
* CS selector set to the startup memory address/16;
|
# CS base set to startup memory address;
|
||||||
* CS base set to startup memory address;
|
# CS limit set to 64KB;
|
||||||
* CS limit set to 64KB;
|
# CPL and IP set to 0.
|
||||||
* CPL and IP set to 0.
|
#
|
||||||
*
|
# mp.c causes each non-boot CPU in turn to jump to start.
|
||||||
* 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
|
||||||
* mp.c puts the correct %esp in start-4, and the place to jump
|
# to in start-8.
|
||||||
* 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 PROT_MODE_DSEG,0x10 # data segment selector
|
||||||
|
@ -22,39 +19,40 @@
|
||||||
|
|
||||||
.globl start
|
.globl start
|
||||||
start:
|
start:
|
||||||
.code16 # This runs in real mode
|
.code16 # This runs in real mode
|
||||||
cli # Disable interrupts
|
cli # Disable interrupts
|
||||||
cld # String operations increment
|
cld # String operations increment
|
||||||
|
|
||||||
# Set up the important data segment registers (DS, ES, SS).
|
# Set up the important data segment registers (DS, ES, SS).
|
||||||
xorw %ax,%ax # Segment number zero
|
xorw %ax,%ax # Segment number zero
|
||||||
movw %ax,%ds # -> Data Segment
|
movw %ax,%ds # -> Data Segment
|
||||||
movw %ax,%es # -> Extra Segment
|
movw %ax,%es # -> Extra Segment
|
||||||
movw %ax,%ss # -> Stack Segment
|
movw %ax,%ss # -> Stack Segment
|
||||||
|
|
||||||
# Set up the stack pointer, growing downward from 0x7000-8.
|
# Set up the stack pointer, growing downward from 0x7000-8.
|
||||||
movw $start-8,%sp # Stack Pointer
|
movw $start-8,%sp # Stack Pointer
|
||||||
|
|
||||||
#### Switch from real to protected mode
|
# Switch from real to protected mode
|
||||||
#### The descriptors in our GDT allow all physical memory to be accessed.
|
# The descriptors in our GDT allow all physical memory to be accessed.
|
||||||
#### Furthermore, the descriptors have base addresses of 0, so that the
|
# Furthermore, the descriptors have base addresses of 0, so that the
|
||||||
#### segment translation is a NOP, ie. virtual addresses are identical to
|
# segment translation is a NOP, ie. virtual addresses are identical to
|
||||||
#### their physical addresses. With this setup, immediately after
|
# their physical addresses. With this setup, immediately after
|
||||||
#### enabling protected mode it will still appear to this code
|
# enabling protected mode it will still appear to this code
|
||||||
#### that it is running directly on physical memory with no translation.
|
# that it is running directly on physical memory with no translation.
|
||||||
#### This initial NOP-translation setup is required by the processor
|
# This initial NOP-translation setup is required by the processor
|
||||||
#### to ensure that the transition to protected mode occurs smoothly.
|
# to ensure that the transition to protected mode occurs smoothly.
|
||||||
|
|
||||||
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
||||||
movl %cr0, %eax # turn on protected mode
|
movl %cr0, %eax # turn on protected mode
|
||||||
orl $CR0_PE_ON, %eax #
|
orl $CR0_PE_ON, %eax #
|
||||||
movl %eax, %cr0 #
|
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
|
# CPU magic: jump to relocation, flush prefetch queue, and reload %cs
|
||||||
### loads CS with $PROT_MODE_CSEG.
|
# Has the effect of just jmp to the next instruction, but simultaneous
|
||||||
|
# loads CS with $PROT_MODE_CSEG.
|
||||||
ljmp $PROT_MODE_CSEG, $protcseg
|
ljmp $PROT_MODE_CSEG, $protcseg
|
||||||
|
|
||||||
#### we are in 32-bit protected mode (hence the .code32)
|
# We are now in 32-bit protected mode (hence the .code32)
|
||||||
.code32
|
.code32
|
||||||
protcseg:
|
protcseg:
|
||||||
# Set up the protected-mode data segment registers
|
# Set up the protected-mode data segment registers
|
||||||
|
@ -69,7 +67,7 @@ protcseg:
|
||||||
movl start-4, %esp
|
movl start-4, %esp
|
||||||
jmp *%eax
|
jmp *%eax
|
||||||
|
|
||||||
.p2align 2 # force 4 byte alignment
|
.p2align 2 # force 4 byte alignment
|
||||||
gdt:
|
gdt:
|
||||||
SEG_NULLASM # null seg
|
SEG_NULLASM # null seg
|
||||||
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
|
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
|
||||||
|
|
3
fs.c
3
fs.c
|
@ -450,7 +450,8 @@ writei(struct inode *ip, char *addr, uint off, uint n)
|
||||||
// NAMEI_DELETE: return locked parent inode, offset of dirent in *ret_off.
|
// NAMEI_DELETE: return locked parent inode, offset of dirent in *ret_off.
|
||||||
// return 0 if name doesn't exist.
|
// return 0 if name doesn't exist.
|
||||||
struct inode*
|
struct inode*
|
||||||
namei(char *path, int mode, uint *ret_off, char **ret_last, struct inode **ret_ip)
|
namei(char *path, int mode, uint *ret_off,
|
||||||
|
char **ret_last, struct inode **ret_ip)
|
||||||
{
|
{
|
||||||
struct inode *dp;
|
struct inode *dp;
|
||||||
struct proc *p = curproc[cpu()];
|
struct proc *p = curproc[cpu()];
|
||||||
|
|
4
ioapic.h
4
ioapic.h
|
@ -1,5 +1,5 @@
|
||||||
#define IO_APIC_BASE 0xFEC00000 // default physical locations of an IO APIC
|
#define IO_APIC_BASE 0xFEC00000 // Default phys addr of IO APIC
|
||||||
#define IOAPIC_WINDOW 0x10 // window register offset
|
#define IOAPIC_WINDOW 0x10 // Window register offset
|
||||||
|
|
||||||
// Constants relating to APIC ID registers
|
// Constants relating to APIC ID registers
|
||||||
#define APIC_ID_MASK 0xff000000
|
#define APIC_ID_MASK 0xff000000
|
||||||
|
|
26
lapic.c
26
lapic.c
|
@ -106,7 +106,8 @@ void
|
||||||
lapic_timerinit(void)
|
lapic_timerinit(void)
|
||||||
{
|
{
|
||||||
lapic_write(LAPIC_TDCR, LAPIC_X1);
|
lapic_write(LAPIC_TDCR, LAPIC_X1);
|
||||||
lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER));
|
lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC |
|
||||||
|
(IRQ_OFFSET + IRQ_TIMER));
|
||||||
lapic_write(LAPIC_TCCR, 10000000);
|
lapic_write(LAPIC_TCCR, 10000000);
|
||||||
lapic_write(LAPIC_TICR, 10000000);
|
lapic_write(LAPIC_TICR, 10000000);
|
||||||
}
|
}
|
||||||
|
@ -122,17 +123,19 @@ lapic_init(int c)
|
||||||
{
|
{
|
||||||
uint r, lvt;
|
uint r, lvt;
|
||||||
|
|
||||||
lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register
|
lapic_write(LAPIC_DFR, 0xFFFFFFFF); // Set dst format register
|
||||||
r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID
|
r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // Read APIC ID
|
||||||
lapic_write(LAPIC_LDR, (1<<r)<<24); // set logical destination register to r
|
lapic_write(LAPIC_LDR, (1<<r)<<24); // Set logical dst register to r
|
||||||
lapic_write(LAPIC_TPR, 0xFF); // no interrupts for now
|
lapic_write(LAPIC_TPR, 0xFF); // No interrupts for now
|
||||||
lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS)); // enable APIC
|
|
||||||
|
// Enable APIC
|
||||||
|
lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));
|
||||||
|
|
||||||
// In virtual wire mode, set up the LINT0 and LINT1 as follows:
|
// In virtual wire mode, set up the LINT0 and LINT1 as follows:
|
||||||
lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT);
|
lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT);
|
||||||
lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI);
|
lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI);
|
||||||
|
|
||||||
lapic_write(LAPIC_EOI, 0); // acknowledge any outstanding interrupts.
|
lapic_write(LAPIC_EOI, 0); // Ack any outstanding interrupts.
|
||||||
|
|
||||||
lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF;
|
lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF;
|
||||||
if(lvt >= 4)
|
if(lvt >= 4)
|
||||||
|
@ -143,7 +146,8 @@ lapic_init(int c)
|
||||||
|
|
||||||
// Issue an INIT Level De-Assert to synchronise arbitration ID's.
|
// Issue an INIT Level De-Assert to synchronise arbitration ID's.
|
||||||
lapic_write(LAPIC_ICRHI, 0);
|
lapic_write(LAPIC_ICRHI, 0);
|
||||||
lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
|
lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|
|
||||||
|
LAPIC_DEASSERT|APIC_INIT);
|
||||||
while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
|
while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -181,10 +185,12 @@ lapic_startap(uchar apicid, int v)
|
||||||
|
|
||||||
crhi = apicid<<24;
|
crhi = apicid<<24;
|
||||||
lapic_write(LAPIC_ICRHI, crhi);
|
lapic_write(LAPIC_ICRHI, crhi);
|
||||||
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|LAPIC_ASSERT|APIC_INIT);
|
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|
|
||||||
|
LAPIC_ASSERT|APIC_INIT);
|
||||||
|
|
||||||
while(j++ < 10000) {;}
|
while(j++ < 10000) {;}
|
||||||
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
|
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|
|
||||||
|
LAPIC_DEASSERT|APIC_INIT);
|
||||||
|
|
||||||
while(j++ < 1000000) {;}
|
while(j++ < 1000000) {;}
|
||||||
|
|
||||||
|
|
2
ls.c
2
ls.c
|
@ -58,7 +58,7 @@ main(int argc, char *argv[])
|
||||||
case T_DIR:
|
case T_DIR:
|
||||||
sz = st.st_size;
|
sz = st.st_size;
|
||||||
for(off = 0; off < sz; off += sizeof(struct dirent)) {
|
for(off = 0; off < sz; off += sizeof(struct dirent)) {
|
||||||
if(read(fd, &dirent, sizeof(struct dirent)) != sizeof(struct dirent)) {
|
if(read(fd, &dirent, sizeof dirent) != sizeof dirent) {
|
||||||
printf(1, "ls: read error\n");
|
printf(1, "ls: read error\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
41
mmu.h
41
mmu.h
|
@ -1,4 +1,5 @@
|
||||||
// This file contains definitions for the x86 memory management unit (MMU).
|
// This file contains definitions for the
|
||||||
|
// x86 memory management unit (MMU).
|
||||||
|
|
||||||
// Eflags register
|
// Eflags register
|
||||||
#define FL_CF 0x00000001 // Carry Flag
|
#define FL_CF 0x00000001 // Carry Flag
|
||||||
|
@ -41,7 +42,7 @@ struct segdesc {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Null segment
|
// 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
|
// Normal segment
|
||||||
#define SEG(type, base, lim, dpl) (struct segdesc) \
|
#define SEG(type, base, lim, dpl) (struct segdesc) \
|
||||||
|
@ -55,26 +56,26 @@ struct segdesc {
|
||||||
(uint) (base) >> 24 }
|
(uint) (base) >> 24 }
|
||||||
|
|
||||||
// Application segment type bits
|
// Application segment type bits
|
||||||
#define STA_X 0x8 // Executable segment
|
#define STA_X 0x8 // Executable segment
|
||||||
#define STA_E 0x4 // Expand down (non-executable segments)
|
#define STA_E 0x4 // Expand down (non-executable segments)
|
||||||
#define STA_C 0x4 // Conforming code segment (executable only)
|
#define STA_C 0x4 // Conforming code segment (executable only)
|
||||||
#define STA_W 0x2 // Writeable (non-executable segments)
|
#define STA_W 0x2 // Writeable (non-executable segments)
|
||||||
#define STA_R 0x2 // Readable (executable segments)
|
#define STA_R 0x2 // Readable (executable segments)
|
||||||
#define STA_A 0x1 // Accessed
|
#define STA_A 0x1 // Accessed
|
||||||
|
|
||||||
// System segment type bits
|
// System segment type bits
|
||||||
#define STS_T16A 0x1 // Available 16-bit TSS
|
#define STS_T16A 0x1 // Available 16-bit TSS
|
||||||
#define STS_LDT 0x2 // Local Descriptor Table
|
#define STS_LDT 0x2 // Local Descriptor Table
|
||||||
#define STS_T16B 0x3 // Busy 16-bit TSS
|
#define STS_T16B 0x3 // Busy 16-bit TSS
|
||||||
#define STS_CG16 0x4 // 16-bit Call Gate
|
#define STS_CG16 0x4 // 16-bit Call Gate
|
||||||
#define STS_TG 0x5 // Task Gate / Coum Transmitions
|
#define STS_TG 0x5 // Task Gate / Coum Transmitions
|
||||||
#define STS_IG16 0x6 // 16-bit Interrupt Gate
|
#define STS_IG16 0x6 // 16-bit Interrupt Gate
|
||||||
#define STS_TG16 0x7 // 16-bit Trap Gate
|
#define STS_TG16 0x7 // 16-bit Trap Gate
|
||||||
#define STS_T32A 0x9 // Available 32-bit TSS
|
#define STS_T32A 0x9 // Available 32-bit TSS
|
||||||
#define STS_T32B 0xB // Busy 32-bit TSS
|
#define STS_T32B 0xB // Busy 32-bit TSS
|
||||||
#define STS_CG32 0xC // 32-bit Call Gate
|
#define STS_CG32 0xC // 32-bit Call Gate
|
||||||
#define STS_IG32 0xE // 32-bit Interrupt Gate
|
#define STS_IG32 0xE // 32-bit Interrupt Gate
|
||||||
#define STS_TG32 0xF // 32-bit Trap Gate
|
#define STS_TG32 0xF // 32-bit Trap Gate
|
||||||
|
|
||||||
// Task state segment format
|
// Task state segment format
|
||||||
struct taskstate {
|
struct taskstate {
|
||||||
|
|
24
mp.c
24
mp.c
|
@ -174,11 +174,12 @@ mp_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mp->imcrp) { // it appears that bochs doesn't support IMCR, and code won't run
|
if(mp->imcrp) {
|
||||||
outb(0x22, 0x70); // select IMCR
|
// It appears that Bochs doesn't support IMCR, so code won't run.
|
||||||
byte = inb(0x23); // current contents
|
outb(0x22, 0x70); // Select IMCR
|
||||||
byte |= 0x01; // mask external INTR
|
byte = inb(0x23); // Current contents
|
||||||
outb(0x23, byte); // disconnect 8259s/NMI
|
byte |= 0x01; // Mask external INTR
|
||||||
|
outb(0x23, byte); // Disconnect 8259s/NMI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,11 +205,20 @@ mp_startthem(void)
|
||||||
(uint) _binary_bootother_size);
|
(uint) _binary_bootother_size);
|
||||||
|
|
||||||
for(c = 0; c < ncpu; c++){
|
for(c = 0; c < ncpu; c++){
|
||||||
|
// Our current cpu has already started.
|
||||||
if(c == cpu())
|
if(c == cpu())
|
||||||
continue;
|
continue;
|
||||||
*(uint*)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp
|
|
||||||
*(uint*)(APBOOTCODE-8) = (uint)mpmain; // tell it where to jump to
|
// Set target %esp
|
||||||
|
*(uint*)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK;
|
||||||
|
|
||||||
|
// Set target %eip
|
||||||
|
*(uint*)(APBOOTCODE-8) = (uint)mpmain;
|
||||||
|
|
||||||
|
// Go!
|
||||||
lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
|
lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
|
||||||
|
|
||||||
|
// Wait for cpu to get through bootstrap.
|
||||||
while(cpus[c].booted == 0)
|
while(cpus[c].booted == 0)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
10
mp.h
10
mp.h
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
struct mp { // floating pointer
|
struct mp { // floating pointer
|
||||||
uchar signature[4]; // "_MP_"
|
uchar signature[4]; // "_MP_"
|
||||||
void *physaddr; // physical address of MP configuration table
|
void *physaddr; // phys addr of MP config table
|
||||||
uchar length; // 1
|
uchar length; // 1
|
||||||
uchar specrev; // [14]
|
uchar specrev; // [14]
|
||||||
uchar checksum; // all bytes must add up to 0
|
uchar checksum; // all bytes must add up to 0
|
||||||
uchar type; // MP system configuration type
|
uchar type; // MP system config type
|
||||||
uchar imcrp;
|
uchar imcrp;
|
||||||
uchar reserved[3];
|
uchar reserved[3];
|
||||||
};
|
};
|
||||||
|
@ -17,10 +17,10 @@ struct mpctb { // configuration table header
|
||||||
uchar version; // [14]
|
uchar version; // [14]
|
||||||
uchar checksum; // all bytes must add up to 0
|
uchar checksum; // all bytes must add up to 0
|
||||||
uchar product[20]; // product id
|
uchar product[20]; // product id
|
||||||
uint *oemtable; // OEM table pointer
|
uint *oemtable; // OEM table pointer
|
||||||
ushort oemlength; // OEM table length
|
ushort oemlength; // OEM table length
|
||||||
ushort entry; // entry count
|
ushort entry; // entry count
|
||||||
uint *lapicaddr; // address of local APIC
|
uint *lapicaddr; // address of local APIC
|
||||||
ushort xlength; // extended table length
|
ushort xlength; // extended table length
|
||||||
uchar xchecksum; // extended table checksum
|
uchar xchecksum; // extended table checksum
|
||||||
uchar reserved;
|
uchar reserved;
|
||||||
|
@ -76,7 +76,7 @@ enum { // table entry types
|
||||||
MPBP = 0x02, // bootstrap processor
|
MPBP = 0x02, // bootstrap processor
|
||||||
|
|
||||||
// PCMPiointr and PCMPlintr flags
|
// PCMPiointr and PCMPlintr flags
|
||||||
MPPOMASK = 0x03, // polarity conforms to specifications of bus
|
MPPOMASK = 0x03, // polarity conforms to bus specs
|
||||||
MPHIGH = 0x01, // active high
|
MPHIGH = 0x01, // active high
|
||||||
MPLOW = 0x03, // active low
|
MPLOW = 0x03, // active low
|
||||||
MPELMASK = 0x0C, // trigger mode of APIC input signals
|
MPELMASK = 0x0C, // trigger mode of APIC input signals
|
||||||
|
|
4
picirq.c
4
picirq.c
|
@ -41,8 +41,8 @@ pic_init(void)
|
||||||
// ICW2: Vector offset
|
// ICW2: Vector offset
|
||||||
outb(IO_PIC1+1, IRQ_OFFSET);
|
outb(IO_PIC1+1, IRQ_OFFSET);
|
||||||
|
|
||||||
// ICW3: bit mask of IR lines connected to slave PICs (master PIC),
|
// ICW3: (master PIC) bit mask of IR lines connected to slaves
|
||||||
// 3-bit No of IR line at which slave connects to master(slave PIC).
|
// (slave PIC) 3-bit # of slave's connection to master
|
||||||
outb(IO_PIC1+1, 1<<IRQ_SLAVE);
|
outb(IO_PIC1+1, 1<<IRQ_SLAVE);
|
||||||
|
|
||||||
// ICW4: 000nbmap
|
// ICW4: 000nbmap
|
||||||
|
|
|
@ -21,10 +21,13 @@ getcallerpcs(void *v, uint pcs[])
|
||||||
{
|
{
|
||||||
uint *ebp = (uint*)v - 2;
|
uint *ebp = (uint*)v - 2;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 10 && ebp && ebp != (uint*)0xffffffff; ebp = (uint*)*ebp, i++){
|
for(i = 0; i < 10; i++){
|
||||||
pcs[i] = *(ebp + 1);
|
if(ebp == 0 || ebp == (uint*)0xffffffff)
|
||||||
|
break;
|
||||||
|
pcs[i] = ebp[1]; // saved %eip
|
||||||
|
ebp = (uint*)ebp[0]; // saved %ebp
|
||||||
}
|
}
|
||||||
for( ; i < 10; i++)
|
for(; i < 10; i++)
|
||||||
pcs[i] = 0;
|
pcs[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,9 @@ sys_write(void)
|
||||||
uint addr;
|
uint addr;
|
||||||
struct proc *p = curproc[cpu()];
|
struct proc *p = curproc[cpu()];
|
||||||
|
|
||||||
if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0)
|
if(fetcharg(0, &fd) < 0 ||
|
||||||
|
fetcharg(1, &addr) < 0 ||
|
||||||
|
fetcharg(2, &n) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(fd < 0 || fd >= NOFILE)
|
if(fd < 0 || fd >= NOFILE)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -78,7 +80,9 @@ sys_read(void)
|
||||||
uint addr;
|
uint addr;
|
||||||
struct proc *p = curproc[cpu()];
|
struct proc *p = curproc[cpu()];
|
||||||
|
|
||||||
if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0)
|
if(fetcharg(0, &fd) < 0 ||
|
||||||
|
fetcharg(1, &addr) < 0 ||
|
||||||
|
fetcharg(2, &n) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(fd < 0 || fd >= NOFILE)
|
if(fd < 0 || fd >= NOFILE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
4
trap.c
4
trap.c
|
@ -8,7 +8,7 @@
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
|
||||||
struct gatedesc idt[256];
|
struct gatedesc idt[256];
|
||||||
extern uint vectors[]; // in vectors.S: array of 256 entry point addresses
|
extern uint vectors[]; // in vectors.S: array of 256 entry pointers
|
||||||
|
|
||||||
extern void trapenter(void);
|
extern void trapenter(void);
|
||||||
extern void trapenter1(void);
|
extern void trapenter1(void);
|
||||||
|
@ -85,7 +85,7 @@ trap(struct trapframe *tf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(curproc[cpu()]) {
|
if(curproc[cpu()]) {
|
||||||
cprintf("pid %d: unhandled trap %d on cpu %d eip %x---terminate process\n",
|
cprintf("pid %d: unhandled trap %d on cpu %d eip %x -- kill proc\n",
|
||||||
curproc[cpu()]->pid, v, cpu(), tf->eip);
|
curproc[cpu()]->pid, v, cpu(), tf->eip);
|
||||||
proc_exit();
|
proc_exit();
|
||||||
}
|
}
|
||||||
|
|
46
traps.h
46
traps.h
|
@ -1,31 +1,31 @@
|
||||||
// system defined:
|
// system defined:
|
||||||
#define T_DIVIDE 0 // divide error
|
#define T_DIVIDE 0 // divide error
|
||||||
#define T_DEBUG 1 // debug exception
|
#define T_DEBUG 1 // debug exception
|
||||||
#define T_NMI 2 // non-maskable interrupt
|
#define T_NMI 2 // non-maskable interrupt
|
||||||
#define T_BRKPT 3 // breakpoint
|
#define T_BRKPT 3 // breakpoint
|
||||||
#define T_OFLOW 4 // overflow
|
#define T_OFLOW 4 // overflow
|
||||||
#define T_BOUND 5 // bounds check
|
#define T_BOUND 5 // bounds check
|
||||||
#define T_ILLOP 6 // illegal opcode
|
#define T_ILLOP 6 // illegal opcode
|
||||||
#define T_DEVICE 7 // device not available
|
#define T_DEVICE 7 // device not available
|
||||||
#define T_DBLFLT 8 // double fault
|
#define T_DBLFLT 8 // double fault
|
||||||
// #define T_COPROC 9 // reserved (not generated by recent processors)
|
// #define T_COPROC 9 // reserved (not used since 486)
|
||||||
#define T_TSS 10 // invalid task switch segment
|
#define T_TSS 10 // invalid task switch segment
|
||||||
#define T_SEGNP 11 // segment not present
|
#define T_SEGNP 11 // segment not present
|
||||||
#define T_STACK 12 // stack exception
|
#define T_STACK 12 // stack exception
|
||||||
#define T_GPFLT 13 // genernal protection fault
|
#define T_GPFLT 13 // genernal protection fault
|
||||||
#define T_PGFLT 14 // page fault
|
#define T_PGFLT 14 // page fault
|
||||||
// #define T_RES 15 // reserved
|
// #define T_RES 15 // reserved
|
||||||
#define T_FPERR 16 // floating point error
|
#define T_FPERR 16 // floating point error
|
||||||
#define T_ALIGN 17 // aligment check
|
#define T_ALIGN 17 // aligment check
|
||||||
#define T_MCHK 18 // machine check
|
#define T_MCHK 18 // machine check
|
||||||
#define T_SIMDERR 19 // SIMD floating point error
|
#define T_SIMDERR 19 // SIMD floating point error
|
||||||
|
|
||||||
// These are arbitrarily chosen, but with care not to overlap
|
// These are arbitrarily chosen, but with care not to overlap
|
||||||
// processor defined exceptions or interrupt vectors.
|
// processor defined exceptions or interrupt vectors.
|
||||||
#define T_SYSCALL 48 // system call
|
#define T_SYSCALL 48 // system call
|
||||||
#define T_DEFAULT 500 // catchall
|
#define T_DEFAULT 500 // catchall
|
||||||
|
|
||||||
#define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET
|
#define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET
|
||||||
|
|
||||||
#define IRQ_KBD 1
|
#define IRQ_KBD 1
|
||||||
#define IRQ_IDE 14
|
#define IRQ_IDE 14
|
||||||
|
|
3
userfs.c
3
userfs.c
|
@ -124,7 +124,8 @@ writetest1(void)
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
if(((int*)buf)[0] != n) {
|
if(((int*)buf)[0] != n) {
|
||||||
printf(stdout, "read content of block %d is %d\n", n, ((int*)buf)[0]);
|
printf(stdout, "read content of block %d is %d\n",
|
||||||
|
n, ((int*)buf)[0]);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
|
|
Loading…
Reference in a new issue