standardize various * conventions
This commit is contained in:
parent
03b6376f56
commit
9e9bcaf143
43 changed files with 503 additions and 503 deletions
10
bio.c
10
bio.c
|
@ -32,7 +32,7 @@ binit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct buf *
|
struct buf*
|
||||||
getblk(uint dev, uint sector)
|
getblk(uint dev, uint sector)
|
||||||
{
|
{
|
||||||
struct buf *b;
|
struct buf *b;
|
||||||
|
@ -67,7 +67,7 @@ getblk(uint dev, uint sector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct buf *
|
struct buf*
|
||||||
bread(uint dev, uint sector)
|
bread(uint dev, uint sector)
|
||||||
{
|
{
|
||||||
void *c;
|
void *c;
|
||||||
|
@ -80,7 +80,7 @@ bread(uint dev, uint sector)
|
||||||
|
|
||||||
acquire(&ide_lock);
|
acquire(&ide_lock);
|
||||||
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
|
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
|
||||||
sleep (c, &ide_lock);
|
sleep(c, &ide_lock);
|
||||||
ide_finish(c);
|
ide_finish(c);
|
||||||
b->flags |= B_VALID;
|
b->flags |= B_VALID;
|
||||||
release(&ide_lock);
|
release(&ide_lock);
|
||||||
|
@ -96,7 +96,7 @@ bwrite(struct buf *b, uint sector)
|
||||||
|
|
||||||
acquire(&ide_lock);
|
acquire(&ide_lock);
|
||||||
c = ide_start_rw(b->dev & 0xff, sector, b->data, 1, 0);
|
c = ide_start_rw(b->dev & 0xff, sector, b->data, 1, 0);
|
||||||
sleep (c, &ide_lock);
|
sleep(c, &ide_lock);
|
||||||
ide_finish(c);
|
ide_finish(c);
|
||||||
b->flags |= B_VALID;
|
b->flags |= B_VALID;
|
||||||
release(&ide_lock);
|
release(&ide_lock);
|
||||||
|
@ -107,7 +107,7 @@ brelse(struct buf *b)
|
||||||
{
|
{
|
||||||
if((b->flags & B_BUSY) == 0)
|
if((b->flags & B_BUSY) == 0)
|
||||||
panic("brelse");
|
panic("brelse");
|
||||||
|
|
||||||
acquire(&buf_table_lock);
|
acquire(&buf_table_lock);
|
||||||
|
|
||||||
b->next->prev = b->prev;
|
b->next->prev = b->prev;
|
||||||
|
|
30
bootasm.S
30
bootasm.S
|
@ -1,23 +1,23 @@
|
||||||
#include "asm.h"
|
#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 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,
|
||||||
# it loads this code at physical address 0x7c00 - 0x7d00 (512 bytes).
|
# it loads this code at physical address 0x7c00 - 0x7d00 (512 bytes).
|
||||||
# Then the BIOS jumps to the beginning of it, address 0x7c00,
|
# Then the BIOS jumps to the beginning of it, address 0x7c00,
|
||||||
# while running in 16-bit real-mode (8086 compatibility mode).
|
# while running in 16-bit real-mode (8086 compatibility mode).
|
||||||
# The Code Segment register (CS) is initially zero on entry.
|
# The Code Segment register (CS) is initially zero on entry.
|
||||||
#
|
#
|
||||||
# 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:
|
||||||
.code16 # This runs in real mode
|
.code16 # This runs in real mode
|
||||||
cli # Disable interrupts
|
cli # Disable interrupts
|
||||||
|
@ -31,7 +31,7 @@ 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 memory
|
||||||
|
@ -39,7 +39,7 @@ start:
|
||||||
#### physical address line 20 is tied to low when the machine boots.
|
#### 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
|
#### Obviously this a bit of a drag for us, especially when trying to
|
||||||
#### address memory above 1MB. This code undoes this.
|
#### address memory above 1MB. This code undoes this.
|
||||||
|
|
||||||
seta20.1:
|
seta20.1:
|
||||||
inb $0x64,%al # Get status
|
inb $0x64,%al # Get status
|
||||||
testb $0x2,%al # Busy?
|
testb $0x2,%al # Busy?
|
||||||
|
@ -54,7 +54,7 @@ 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
|
||||||
|
@ -63,21 +63,21 @@ seta20.2:
|
||||||
#### 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.
|
||||||
ljmp $PROT_MODE_CSEG, $protcseg
|
ljmp $PROT_MODE_CSEG, $protcseg
|
||||||
|
|
||||||
#### we are in 32-bit protected mode (hence the .code32)
|
#### we are 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
|
||||||
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
||||||
movw %ax, %ds # -> DS: Data Segment
|
movw %ax, %ds # -> DS: Data Segment
|
||||||
|
@ -97,7 +97,7 @@ 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
|
||||||
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
||||||
|
|
||||||
gdtdesc:
|
gdtdesc:
|
||||||
.word 0x17 # sizeof(gdt) - 1
|
.word 0x17 # sizeof(gdt) - 1
|
||||||
.long gdt # address gdt
|
.long gdt # address gdt
|
||||||
|
|
24
bootmain.c
24
bootmain.c
|
@ -9,16 +9,16 @@
|
||||||
* DISK LAYOUT
|
* DISK LAYOUT
|
||||||
* * This program(boot.S and main.c) is the bootloader. It should
|
* * This program(boot.S and main.c) is the bootloader. It should
|
||||||
* be stored in the first sector of the disk.
|
* be stored in the first sector of the disk.
|
||||||
*
|
*
|
||||||
* * The 2nd sector onward holds the kernel image.
|
* * The 2nd sector onward holds the kernel image.
|
||||||
*
|
*
|
||||||
* * The kernel image must be in ELF format.
|
* * The kernel image must be in ELF format.
|
||||||
*
|
*
|
||||||
* BOOT UP STEPS
|
* BOOT UP STEPS
|
||||||
* * when the CPU boots it loads the BIOS into memory and executes it
|
* * when the CPU boots it loads the BIOS into memory and executes it
|
||||||
*
|
*
|
||||||
* * the BIOS intializes devices, sets of the interrupt routines, and
|
* * the BIOS intializes devices, sets of the interrupt routines, and
|
||||||
* reads the first sector of the boot device(e.g., hard-drive)
|
* reads the first sector of the boot device(e.g., hard-drive)
|
||||||
* into memory and jumps to it.
|
* into memory and jumps to it.
|
||||||
*
|
*
|
||||||
* * Assuming this boot loader is stored in the first sector of the
|
* * Assuming this boot loader is stored in the first sector of the
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#define SECTSIZE 512
|
#define SECTSIZE 512
|
||||||
#define ELFHDR ((struct elfhdr *) 0x10000) // scratch space
|
#define ELFHDR ((struct elfhdr*) 0x10000) // scratch space
|
||||||
|
|
||||||
void readsect(void*, uint);
|
void readsect(void*, uint);
|
||||||
void readseg(uint, uint, uint);
|
void readseg(uint, uint, uint);
|
||||||
|
@ -45,18 +45,18 @@ cmain(void)
|
||||||
readseg((uint) ELFHDR, SECTSIZE*8, 0);
|
readseg((uint) ELFHDR, SECTSIZE*8, 0);
|
||||||
|
|
||||||
// is this a valid ELF?
|
// is this a valid ELF?
|
||||||
if (ELFHDR->magic != ELF_MAGIC)
|
if(ELFHDR->magic != ELF_MAGIC)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
// load each program segment (ignores ph flags)
|
// load each program segment (ignores ph flags)
|
||||||
ph = (struct proghdr *) ((uchar *) ELFHDR + ELFHDR->phoff);
|
ph = (struct proghdr*) ((uchar*) ELFHDR + ELFHDR->phoff);
|
||||||
eph = ph + ELFHDR->phnum;
|
eph = ph + ELFHDR->phnum;
|
||||||
for (; ph < eph; ph++)
|
for(; ph < eph; ph++)
|
||||||
readseg(ph->va, ph->memsz, ph->offset);
|
readseg(ph->va, ph->memsz, ph->offset);
|
||||||
|
|
||||||
// call the entry point from the ELF header
|
// call the entry point from the ELF header
|
||||||
// note: does not return!
|
// note: does not return!
|
||||||
((void (*)(void)) (ELFHDR->entry & 0xFFFFFF))();
|
((void(*)(void)) (ELFHDR->entry & 0xFFFFFF))();
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
outw(0x8A00, 0x8A00);
|
outw(0x8A00, 0x8A00);
|
||||||
|
@ -74,7 +74,7 @@ readseg(uint va, uint count, uint offset)
|
||||||
|
|
||||||
va &= 0xFFFFFF;
|
va &= 0xFFFFFF;
|
||||||
end_va = va + count;
|
end_va = va + count;
|
||||||
|
|
||||||
// round down to sector boundary
|
// round down to sector boundary
|
||||||
va &= ~(SECTSIZE - 1);
|
va &= ~(SECTSIZE - 1);
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ readseg(uint va, uint count, uint offset)
|
||||||
// If this is too slow, we could read lots of sectors at a time.
|
// 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'd write more to memory than asked, but it doesn't matter --
|
||||||
// we load in increasing order.
|
// we load in increasing order.
|
||||||
while (va < end_va) {
|
while(va < end_va) {
|
||||||
readsect((uchar*) va, offset);
|
readsect((uchar*) va, offset);
|
||||||
va += SECTSIZE;
|
va += SECTSIZE;
|
||||||
offset++;
|
offset++;
|
||||||
|
@ -95,7 +95,7 @@ void
|
||||||
waitdisk(void)
|
waitdisk(void)
|
||||||
{
|
{
|
||||||
// wait for disk reaady
|
// wait for disk reaady
|
||||||
while ((inb(0x1F7) & 0xC0) != 0x40)
|
while((inb(0x1F7) & 0xC0) != 0x40)
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
bootother.S
22
bootother.S
|
@ -1,5 +1,5 @@
|
||||||
#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,
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
* 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
|
||||||
|
@ -34,8 +34,8 @@ start:
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -44,11 +44,11 @@ start:
|
||||||
#### 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
|
### 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.
|
||||||
|
@ -56,7 +56,7 @@ start:
|
||||||
|
|
||||||
#### we are in 32-bit protected mode (hence the .code32)
|
#### we are 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
|
||||||
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
||||||
movw %ax, %ds # -> DS: Data Segment
|
movw %ax, %ds # -> DS: Data Segment
|
||||||
|
@ -67,14 +67,14 @@ protcseg:
|
||||||
|
|
||||||
movl start-8, %eax
|
movl start-8, %eax
|
||||||
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
|
||||||
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
||||||
|
|
||||||
gdtdesc:
|
gdtdesc:
|
||||||
.word 0x17 # sizeof(gdt) - 1
|
.word 0x17 # sizeof(gdt) - 1
|
||||||
.long gdt # address gdt
|
.long gdt # address gdt
|
||||||
|
|
2
cat.c
2
cat.c
|
@ -24,7 +24,7 @@ main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int fd, i;
|
int fd, i;
|
||||||
|
|
||||||
if (argc <= 1) {
|
if(argc <= 1) {
|
||||||
rfile(0);
|
rfile(0);
|
||||||
} else {
|
} else {
|
||||||
for(i = 1; i < argc; i++){
|
for(i = 1; i < argc; i++){
|
||||||
|
|
48
console.c
48
console.c
|
@ -20,7 +20,7 @@ lpt_putc(int c)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
|
for(i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
|
||||||
;
|
;
|
||||||
outb(0x378+0, c);
|
outb(0x378+0, c);
|
||||||
outb(0x378+2, 0x08|0x04|0x01);
|
outb(0x378+2, 0x08|0x04|0x01);
|
||||||
|
@ -31,7 +31,7 @@ static void
|
||||||
cons_putc(int c)
|
cons_putc(int c)
|
||||||
{
|
{
|
||||||
int crtport = 0x3d4; // io port of CGA
|
int crtport = 0x3d4; // io port of CGA
|
||||||
ushort *crt = (ushort *) 0xB8000; // base of CGA memory
|
ushort *crt = (ushort*) 0xB8000; // base of CGA memory
|
||||||
int ind;
|
int ind;
|
||||||
|
|
||||||
if(panicked){
|
if(panicked){
|
||||||
|
@ -79,7 +79,7 @@ printint(int xx, int base, int sgn)
|
||||||
char digits[] = "0123456789ABCDEF";
|
char digits[] = "0123456789ABCDEF";
|
||||||
int i = 0, neg = 0;
|
int i = 0, neg = 0;
|
||||||
uint x;
|
uint x;
|
||||||
|
|
||||||
if(sgn && xx < 0){
|
if(sgn && xx < 0){
|
||||||
neg = 1;
|
neg = 1;
|
||||||
x = 0 - xx;
|
x = 0 - xx;
|
||||||
|
@ -104,7 +104,7 @@ void
|
||||||
cprintf(char *fmt, ...)
|
cprintf(char *fmt, ...)
|
||||||
{
|
{
|
||||||
int i, state = 0, c, locking = 0;
|
int i, state = 0, c, locking = 0;
|
||||||
uint *ap = (uint *)(void*)&fmt + 1;
|
uint *ap = (uint*)(void*)&fmt + 1;
|
||||||
|
|
||||||
if(use_console_lock){
|
if(use_console_lock){
|
||||||
locking = 1;
|
locking = 1;
|
||||||
|
@ -166,13 +166,13 @@ panic(char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
console_write (int minor, char *buf, int n)
|
console_write(int minor, char *buf, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
acquire(&console_lock);
|
acquire(&console_lock);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for(i = 0; i < n; i++) {
|
||||||
cons_putc(buf[i] & 0xff);
|
cons_putc(buf[i] & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ console_write (int minor, char *buf, int n)
|
||||||
#define KEY_INS 0xE8
|
#define KEY_INS 0xE8
|
||||||
#define KEY_DEL 0xE9
|
#define KEY_DEL 0xE9
|
||||||
|
|
||||||
static uchar shiftcode[256] =
|
static uchar shiftcode[256] =
|
||||||
{
|
{
|
||||||
[0x1D] CTL,
|
[0x1D] CTL,
|
||||||
[0x2A] SHIFT,
|
[0x2A] SHIFT,
|
||||||
|
@ -221,7 +221,7 @@ static uchar shiftcode[256] =
|
||||||
[0xB8] ALT
|
[0xB8] ALT
|
||||||
};
|
};
|
||||||
|
|
||||||
static uchar togglecode[256] =
|
static uchar togglecode[256] =
|
||||||
{
|
{
|
||||||
[0x3A] CAPSLOCK,
|
[0x3A] CAPSLOCK,
|
||||||
[0x45] NUMLOCK,
|
[0x45] NUMLOCK,
|
||||||
|
@ -249,7 +249,7 @@ static uchar normalmap[256] =
|
||||||
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
||||||
};
|
};
|
||||||
|
|
||||||
static uchar shiftmap[256] =
|
static uchar shiftmap[256] =
|
||||||
{
|
{
|
||||||
NO, 033, '!', '@', '#', '$', '%', '^', // 0x00
|
NO, 033, '!', '@', '#', '$', '%', '^', // 0x00
|
||||||
'&', '*', '(', ')', '_', '+', '\b', '\t',
|
'&', '*', '(', ')', '_', '+', '\b', '\t',
|
||||||
|
@ -272,13 +272,13 @@ static uchar shiftmap[256] =
|
||||||
|
|
||||||
#define C(x) (x - '@')
|
#define C(x) (x - '@')
|
||||||
|
|
||||||
static uchar ctlmap[256] =
|
static uchar ctlmap[256] =
|
||||||
{
|
{
|
||||||
NO, NO, NO, NO, NO, NO, NO, NO,
|
NO, NO, NO, NO, NO, NO, NO, NO,
|
||||||
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('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('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,
|
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'),
|
NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'),
|
||||||
C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO,
|
C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO,
|
||||||
[0x97] KEY_HOME,
|
[0x97] KEY_HOME,
|
||||||
|
@ -311,41 +311,41 @@ kbd_intr()
|
||||||
acquire(&kbd_lock);
|
acquire(&kbd_lock);
|
||||||
|
|
||||||
st = inb(KBSTATP);
|
st = inb(KBSTATP);
|
||||||
if ((st & KBS_DIB) == 0){
|
if((st & KBS_DIB) == 0){
|
||||||
release(&kbd_lock);
|
release(&kbd_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data = inb(KBDATAP);
|
data = inb(KBDATAP);
|
||||||
|
|
||||||
if (data == 0xE0) {
|
if(data == 0xE0) {
|
||||||
shift |= E0ESC;
|
shift |= E0ESC;
|
||||||
release(&kbd_lock);
|
release(&kbd_lock);
|
||||||
return;
|
return;
|
||||||
} else if (data & 0x80) {
|
} else if(data & 0x80) {
|
||||||
// Key released
|
// Key released
|
||||||
data = (shift & E0ESC ? data : data & 0x7F);
|
data = (shift & E0ESC ? data : data & 0x7F);
|
||||||
shift &= ~(shiftcode[data] | E0ESC);
|
shift &= ~(shiftcode[data] | E0ESC);
|
||||||
release(&kbd_lock);
|
release(&kbd_lock);
|
||||||
return;
|
return;
|
||||||
} else if (shift & E0ESC) {
|
} else if(shift & E0ESC) {
|
||||||
// Last character was an E0 escape; or with 0x80
|
// Last character was an E0 escape; or with 0x80
|
||||||
data |= 0x80;
|
data |= 0x80;
|
||||||
shift &= ~E0ESC;
|
shift &= ~E0ESC;
|
||||||
}
|
}
|
||||||
|
|
||||||
shift |= shiftcode[data];
|
shift |= shiftcode[data];
|
||||||
shift ^= togglecode[data];
|
shift ^= togglecode[data];
|
||||||
|
|
||||||
c = charcode[shift & (CTL | SHIFT)][data];
|
c = charcode[shift & (CTL | SHIFT)][data];
|
||||||
if (shift & CAPSLOCK) {
|
if(shift & CAPSLOCK) {
|
||||||
if ('a' <= c && c <= 'z')
|
if('a' <= c && c <= 'z')
|
||||||
c += 'A' - 'a';
|
c += 'A' - 'a';
|
||||||
else if ('A' <= c && c <= 'Z')
|
else if('A' <= c && c <= 'Z')
|
||||||
c += 'a' - 'A';
|
c += 'a' - 'A';
|
||||||
}
|
}
|
||||||
|
|
||||||
// xxx hack
|
// xxx hack
|
||||||
if (c == 0x0) {
|
if(c == 0x0) {
|
||||||
release(&kbd_lock);
|
release(&kbd_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -397,7 +397,7 @@ console_init()
|
||||||
devsw[CONSOLE].d_write = console_write;
|
devsw[CONSOLE].d_write = console_write;
|
||||||
devsw[CONSOLE].d_read = console_read;
|
devsw[CONSOLE].d_read = console_read;
|
||||||
|
|
||||||
ioapic_enable (IRQ_KBD, 0);
|
ioapic_enable(IRQ_KBD, 0);
|
||||||
|
|
||||||
use_console_lock = 1;
|
use_console_lock = 1;
|
||||||
}
|
}
|
||||||
|
|
8
defs.h
8
defs.h
|
@ -1,5 +1,5 @@
|
||||||
// kalloc.c
|
// kalloc.c
|
||||||
char *kalloc(int);
|
char* kalloc(int);
|
||||||
void kfree(char*, int);
|
void kfree(char*, int);
|
||||||
void kinit(void);
|
void kinit(void);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ struct proc* copyproc(struct proc*);
|
||||||
struct spinlock;
|
struct spinlock;
|
||||||
uint growproc(int);
|
uint growproc(int);
|
||||||
void sleep(void*, struct spinlock*);
|
void sleep(void*, struct spinlock*);
|
||||||
void wakeup(void *);
|
void wakeup(void*);
|
||||||
void scheduler(void);
|
void scheduler(void);
|
||||||
void proc_exit(void);
|
void proc_exit(void);
|
||||||
int proc_kill(int);
|
int proc_kill(int);
|
||||||
|
@ -35,9 +35,9 @@ void tvinit(void);
|
||||||
void idtinit(void);
|
void idtinit(void);
|
||||||
|
|
||||||
// string.c
|
// string.c
|
||||||
void * memset(void*, int, uint);
|
void* memset(void*, int, uint);
|
||||||
int memcmp(const void*, const void*, uint);
|
int memcmp(const void*, const void*, uint);
|
||||||
void *memmove(void*, const void*, uint);
|
void* memmove(void*, const void*, uint);
|
||||||
int strncmp(const char*, const char*, uint);
|
int strncmp(const char*, const char*, uint);
|
||||||
|
|
||||||
// syscall.c
|
// syscall.c
|
||||||
|
|
6
dev.h
6
dev.h
|
@ -1,7 +1,7 @@
|
||||||
struct devsw {
|
struct devsw {
|
||||||
int (*d_open)(char *, int);
|
int (*d_open)(char*, int);
|
||||||
int (*d_read)(int, char *, int);
|
int (*d_read)(int, char*, int);
|
||||||
int (*d_write)(int, char *, int);
|
int (*d_write)(int, char*, int);
|
||||||
int (*d_close)(int);
|
int (*d_close)(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
8
fd.c
8
fd.c
|
@ -39,7 +39,7 @@ fd_ualloc(void)
|
||||||
/*
|
/*
|
||||||
* allocate a file descriptor structure
|
* allocate a file descriptor structure
|
||||||
*/
|
*/
|
||||||
struct fd *
|
struct fd*
|
||||||
fd_alloc(void)
|
fd_alloc(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -67,10 +67,10 @@ fd_write(struct fd *fd, char *addr, int n)
|
||||||
return -1;
|
return -1;
|
||||||
if(fd->type == FD_PIPE){
|
if(fd->type == FD_PIPE){
|
||||||
return pipe_write(fd->pipe, addr, n);
|
return pipe_write(fd->pipe, addr, n);
|
||||||
} else if (fd->type == FD_FILE) {
|
} else if(fd->type == FD_FILE) {
|
||||||
ilock(fd->ip);
|
ilock(fd->ip);
|
||||||
int r = writei (fd->ip, addr, fd->off, n);
|
int r = writei(fd->ip, addr, fd->off, n);
|
||||||
if (r > 0) {
|
if(r > 0) {
|
||||||
fd->off += r;
|
fd->off += r;
|
||||||
}
|
}
|
||||||
iunlock(fd->ip);
|
iunlock(fd->ip);
|
||||||
|
|
172
fs.c
172
fs.c
|
@ -27,8 +27,8 @@ iinit(void)
|
||||||
/*
|
/*
|
||||||
* allocate a disk block
|
* allocate a disk block
|
||||||
*/
|
*/
|
||||||
static uint
|
static uint
|
||||||
balloc(uint dev)
|
balloc(uint dev)
|
||||||
{
|
{
|
||||||
int b;
|
int b;
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
@ -39,31 +39,31 @@ balloc(uint dev)
|
||||||
uchar m;
|
uchar m;
|
||||||
|
|
||||||
bp = bread(dev, 1);
|
bp = bread(dev, 1);
|
||||||
sb = (struct superblock *) bp->data;
|
sb = (struct superblock*) bp->data;
|
||||||
size = sb->size;
|
size = sb->size;
|
||||||
ninodes = sb->ninodes;
|
ninodes = sb->ninodes;
|
||||||
|
|
||||||
for (b = 0; b < size; b++) {
|
for(b = 0; b < size; b++) {
|
||||||
if (b % BPB == 0) {
|
if(b % BPB == 0) {
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
bp = bread(dev, BBLOCK(b, ninodes));
|
bp = bread(dev, BBLOCK(b, ninodes));
|
||||||
}
|
}
|
||||||
bi = b % BPB;
|
bi = b % BPB;
|
||||||
m = 0x1 << (bi % 8);
|
m = 0x1 << (bi % 8);
|
||||||
if ((bp->data[bi/8] & m) == 0) { // is block free?
|
if((bp->data[bi/8] & m) == 0) { // is block free?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (b >= size)
|
if(b >= size)
|
||||||
panic("balloc: out of blocks");
|
panic("balloc: out of blocks");
|
||||||
|
|
||||||
bp->data[bi/8] |= 0x1 << (bi % 8);
|
bp->data[bi/8] |= 0x1 << (bi % 8);
|
||||||
bwrite (bp, BBLOCK(b, ninodes)); // mark it allocated on disk
|
bwrite(bp, BBLOCK(b, ninodes)); // mark it allocated on disk
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bfree(int dev, uint b)
|
bfree(int dev, uint b)
|
||||||
{
|
{
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
@ -73,7 +73,7 @@ bfree(int dev, uint b)
|
||||||
uchar m;
|
uchar m;
|
||||||
|
|
||||||
bp = bread(dev, 1);
|
bp = bread(dev, 1);
|
||||||
sb = (struct superblock *) bp->data;
|
sb = (struct superblock*) bp->data;
|
||||||
ninodes = sb->ninodes;
|
ninodes = sb->ninodes;
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
|
|
||||||
|
@ -86,16 +86,16 @@ bfree(int dev, uint b)
|
||||||
bi = b % BPB;
|
bi = b % BPB;
|
||||||
m = ~(0x1 << (bi %8));
|
m = ~(0x1 << (bi %8));
|
||||||
bp->data[bi/8] &= m;
|
bp->data[bi/8] &= m;
|
||||||
bwrite (bp, BBLOCK(b, ninodes)); // mark it free on disk
|
bwrite(bp, BBLOCK(b, ninodes)); // mark it free on disk
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fetch an inode, from the in-core table if it's already
|
* fetch an inode, from the in-core table if it's already
|
||||||
* in use, otherwise read from the disk.
|
* in use, otherwise read from the disk.
|
||||||
* returns an inode with busy set and incremented reference count.
|
* returns an inode with busy set and incremented reference count.
|
||||||
*/
|
*/
|
||||||
struct inode *
|
struct inode*
|
||||||
iget(uint dev, uint inum)
|
iget(uint dev, uint inum)
|
||||||
{
|
{
|
||||||
struct inode *ip, *nip;
|
struct inode *ip, *nip;
|
||||||
|
@ -132,7 +132,7 @@ iget(uint dev, uint inum)
|
||||||
release(&inode_table_lock);
|
release(&inode_table_lock);
|
||||||
|
|
||||||
bp = bread(dev, IBLOCK(inum));
|
bp = bread(dev, IBLOCK(inum));
|
||||||
dip = &((struct dinode *)(bp->data))[inum % IPB];
|
dip = &((struct dinode*)(bp->data))[inum % IPB];
|
||||||
nip->type = dip->type;
|
nip->type = dip->type;
|
||||||
nip->major = dip->major;
|
nip->major = dip->major;
|
||||||
nip->minor = dip->minor;
|
nip->minor = dip->minor;
|
||||||
|
@ -144,25 +144,25 @@ iget(uint dev, uint inum)
|
||||||
return nip;
|
return nip;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iupdate (struct inode *ip)
|
iupdate(struct inode *ip)
|
||||||
{
|
{
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
struct dinode *dip;
|
struct dinode *dip;
|
||||||
|
|
||||||
bp = bread(ip->dev, IBLOCK(ip->inum));
|
bp = bread(ip->dev, IBLOCK(ip->inum));
|
||||||
dip = &((struct dinode *)(bp->data))[ip->inum % IPB];
|
dip = &((struct dinode*)(bp->data))[ip->inum % IPB];
|
||||||
dip->type = ip->type;
|
dip->type = ip->type;
|
||||||
dip->major = ip->major;
|
dip->major = ip->major;
|
||||||
dip->minor = ip->minor;
|
dip->minor = ip->minor;
|
||||||
dip->nlink = ip->nlink;
|
dip->nlink = ip->nlink;
|
||||||
dip->size = ip->size;
|
dip->size = ip->size;
|
||||||
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
|
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
|
||||||
bwrite (bp, IBLOCK(ip->inum)); // mark it allocated on the disk
|
bwrite(bp, IBLOCK(ip->inum)); // mark it allocated on the disk
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct inode *
|
struct inode*
|
||||||
ialloc(uint dev, short type)
|
ialloc(uint dev, short type)
|
||||||
{
|
{
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
|
@ -173,27 +173,27 @@ ialloc(uint dev, short type)
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
|
||||||
bp = bread(dev, 1);
|
bp = bread(dev, 1);
|
||||||
sb = (struct superblock *) bp->data;
|
sb = (struct superblock*) bp->data;
|
||||||
ninodes = sb->ninodes;
|
ninodes = sb->ninodes;
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
|
|
||||||
for (inum = 1; inum < ninodes; inum++) { // loop over inode blocks
|
for(inum = 1; inum < ninodes; inum++) { // loop over inode blocks
|
||||||
bp = bread(dev, IBLOCK(inum));
|
bp = bread(dev, IBLOCK(inum));
|
||||||
dip = &((struct dinode *)(bp->data))[inum % IPB];
|
dip = &((struct dinode*)(bp->data))[inum % IPB];
|
||||||
if (dip->type == 0) { // a free inode
|
if(dip->type == 0) { // a free inode
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inum >= ninodes)
|
if(inum >= ninodes)
|
||||||
panic ("ialloc: no inodes left");
|
panic("ialloc: no inodes left");
|
||||||
|
|
||||||
memset(dip, 0, sizeof(*dip));
|
memset(dip, 0, sizeof(*dip));
|
||||||
dip->type = type;
|
dip->type = type;
|
||||||
bwrite (bp, IBLOCK(inum)); // mark it allocated on the disk
|
bwrite(bp, IBLOCK(inum)); // mark it allocated on the disk
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
ip = iget (dev, inum);
|
ip = iget(dev, inum);
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,42 +244,42 @@ bmap(struct inode *ip, uint bn)
|
||||||
|
|
||||||
if(bn >= MAXFILE)
|
if(bn >= MAXFILE)
|
||||||
panic("bmap 1");
|
panic("bmap 1");
|
||||||
if (bn < NDIRECT) {
|
if(bn < NDIRECT) {
|
||||||
x = ip->addrs[bn];
|
x = ip->addrs[bn];
|
||||||
if (x == 0)
|
if(x == 0)
|
||||||
panic("bmap 2");
|
panic("bmap 2");
|
||||||
} else {
|
} else {
|
||||||
if(ip->addrs[INDIRECT] == 0)
|
if(ip->addrs[INDIRECT] == 0)
|
||||||
panic("bmap 3");
|
panic("bmap 3");
|
||||||
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
||||||
a = (uint *) inbp->data;
|
a = (uint*) inbp->data;
|
||||||
x = a[bn - NDIRECT];
|
x = a[bn - NDIRECT];
|
||||||
brelse(inbp);
|
brelse(inbp);
|
||||||
if (x == 0)
|
if(x == 0)
|
||||||
panic("bmap 4");
|
panic("bmap 4");
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
itrunc(struct inode *ip)
|
itrunc(struct inode *ip)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
struct buf *inbp;
|
struct buf *inbp;
|
||||||
|
|
||||||
for (i = 0; i < NADDRS; i++) {
|
for(i = 0; i < NADDRS; i++) {
|
||||||
if (ip->addrs[i] != 0) {
|
if(ip->addrs[i] != 0) {
|
||||||
if (i == INDIRECT) {
|
if(i == INDIRECT) {
|
||||||
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
||||||
uint *a = (uint *) inbp->data;
|
uint *a = (uint*) inbp->data;
|
||||||
for (j = 0; j < NINDIRECT; j++) {
|
for(j = 0; j < NINDIRECT; j++) {
|
||||||
if (a[j] != 0) {
|
if(a[j] != 0) {
|
||||||
bfree(ip->dev, a[j]);
|
bfree(ip->dev, a[j]);
|
||||||
a[j] = 0;
|
a[j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
brelse(inbp);
|
brelse(inbp);
|
||||||
}
|
}
|
||||||
bfree(ip->dev, ip->addrs[i]);
|
bfree(ip->dev, ip->addrs[i]);
|
||||||
ip->addrs[i] = 0;
|
ip->addrs[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@ iput(struct inode *ip)
|
||||||
if(ip->count < 1 || ip->busy != 1)
|
if(ip->count < 1 || ip->busy != 1)
|
||||||
panic("iput");
|
panic("iput");
|
||||||
|
|
||||||
if ((ip->count == 1) && (ip->nlink == 0)) {
|
if((ip->count == 1) && (ip->nlink == 0)) {
|
||||||
itrunc(ip);
|
itrunc(ip);
|
||||||
ifree(ip);
|
ifree(ip);
|
||||||
}
|
}
|
||||||
|
@ -343,10 +343,10 @@ readi(struct inode *ip, char *dst, uint off, uint n)
|
||||||
uint target = n, n1;
|
uint target = n, n1;
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
|
||||||
if (ip->type == T_DEV) {
|
if(ip->type == T_DEV) {
|
||||||
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_read)
|
if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_read)
|
||||||
return -1;
|
return -1;
|
||||||
return devsw[ip->major].d_read (ip->minor, dst, n);
|
return devsw[ip->major].d_read(ip->minor, dst, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(n > 0 && off < ip->size){
|
while(n > 0 && off < ip->size){
|
||||||
|
@ -370,23 +370,23 @@ newblock(struct inode *ip, uint lbn)
|
||||||
uint *inaddrs;
|
uint *inaddrs;
|
||||||
uint b;
|
uint b;
|
||||||
|
|
||||||
if (lbn < NDIRECT) {
|
if(lbn < NDIRECT) {
|
||||||
if (ip->addrs[lbn] == 0) {
|
if(ip->addrs[lbn] == 0) {
|
||||||
b = balloc(ip->dev);
|
b = balloc(ip->dev);
|
||||||
if (b <= 0) return -1;
|
if(b <= 0) return -1;
|
||||||
ip->addrs[lbn] = b;
|
ip->addrs[lbn] = b;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ip->addrs[INDIRECT] == 0) {
|
if(ip->addrs[INDIRECT] == 0) {
|
||||||
b = balloc(ip->dev);
|
b = balloc(ip->dev);
|
||||||
if (b <= 0) return -1;
|
if(b <= 0) return -1;
|
||||||
ip->addrs[INDIRECT] = b;
|
ip->addrs[INDIRECT] = b;
|
||||||
}
|
}
|
||||||
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
||||||
inaddrs = (uint *) inbp->data;
|
inaddrs = (uint*) inbp->data;
|
||||||
if (inaddrs[lbn - NDIRECT] == 0) {
|
if(inaddrs[lbn - NDIRECT] == 0) {
|
||||||
b = balloc(ip->dev);
|
b = balloc(ip->dev);
|
||||||
if (b <= 0) return -1;
|
if(b <= 0) return -1;
|
||||||
inaddrs[lbn - NDIRECT] = b;
|
inaddrs[lbn - NDIRECT] = b;
|
||||||
bwrite(inbp, ip->addrs[INDIRECT]);
|
bwrite(inbp, ip->addrs[INDIRECT]);
|
||||||
}
|
}
|
||||||
|
@ -398,40 +398,40 @@ newblock(struct inode *ip, uint lbn)
|
||||||
int
|
int
|
||||||
writei(struct inode *ip, char *addr, uint off, uint n)
|
writei(struct inode *ip, char *addr, uint off, uint n)
|
||||||
{
|
{
|
||||||
if (ip->type == T_DEV) {
|
if(ip->type == T_DEV) {
|
||||||
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write)
|
if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write)
|
||||||
return -1;
|
return -1;
|
||||||
return devsw[ip->major].d_write (ip->minor, addr, n);
|
return devsw[ip->major].d_write(ip->minor, addr, n);
|
||||||
} else if (ip->type == T_FILE || ip->type == T_DIR) {
|
} else if(ip->type == T_FILE || ip->type == T_DIR) {
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int m;
|
int m;
|
||||||
int lbn;
|
int lbn;
|
||||||
while (r < n) {
|
while(r < n) {
|
||||||
lbn = off / BSIZE;
|
lbn = off / BSIZE;
|
||||||
if (lbn >= MAXFILE) return r;
|
if(lbn >= MAXFILE) return r;
|
||||||
if (newblock(ip, lbn) < 0) {
|
if(newblock(ip, lbn) < 0) {
|
||||||
cprintf("newblock failed\n");
|
cprintf("newblock failed\n");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
m = min(BSIZE - off % BSIZE, n-r);
|
m = min(BSIZE - off % BSIZE, n-r);
|
||||||
bp = bread(ip->dev, bmap(ip, lbn));
|
bp = bread(ip->dev, bmap(ip, lbn));
|
||||||
memmove (bp->data + off % BSIZE, addr, m);
|
memmove(bp->data + off % BSIZE, addr, m);
|
||||||
bwrite (bp, bmap(ip, lbn));
|
bwrite(bp, bmap(ip, lbn));
|
||||||
brelse (bp);
|
brelse(bp);
|
||||||
r += m;
|
r += m;
|
||||||
off += m;
|
off += m;
|
||||||
}
|
}
|
||||||
if (r > 0) {
|
if(r > 0) {
|
||||||
if (off > ip->size) {
|
if(off > ip->size) {
|
||||||
if (ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE;
|
if(ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE;
|
||||||
else ip->size = off;
|
else ip->size = off;
|
||||||
}
|
}
|
||||||
iupdate(ip);
|
iupdate(ip);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
panic ("writei: unknown type");
|
panic("writei: unknown type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ writei(struct inode *ip, char *addr, uint off, uint n)
|
||||||
// *ret_ip and *ret_last may be zero even if return value is zero.
|
// *ret_ip and *ret_last may be zero even if return value is zero.
|
||||||
// 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;
|
||||||
|
@ -464,7 +464,7 @@ namei(char *path, int mode, uint *ret_off, char **ret_last, struct inode **ret_i
|
||||||
if(ret_ip)
|
if(ret_ip)
|
||||||
*ret_ip = 0;
|
*ret_ip = 0;
|
||||||
|
|
||||||
if (*cp == '/') dp = iget(rootdev, 1);
|
if(*cp == '/') dp = iget(rootdev, 1);
|
||||||
else {
|
else {
|
||||||
dp = p->cwd;
|
dp = p->cwd;
|
||||||
iincref(dp);
|
iincref(dp);
|
||||||
|
@ -493,10 +493,10 @@ namei(char *path, int mode, uint *ret_off, char **ret_last, struct inode **ret_i
|
||||||
|
|
||||||
for(off = 0; off < dp->size; off += BSIZE){
|
for(off = 0; off < dp->size; off += BSIZE){
|
||||||
bp = bread(dp->dev, bmap(dp, off / BSIZE));
|
bp = bread(dp->dev, bmap(dp, off / BSIZE));
|
||||||
for(ep = (struct dirent *) bp->data;
|
for(ep = (struct dirent*) bp->data;
|
||||||
ep < (struct dirent *) (bp->data + BSIZE);
|
ep < (struct dirent*) (bp->data + BSIZE);
|
||||||
ep++){
|
ep++){
|
||||||
if(ep->inum == 0)
|
if(ep->inum == 0)
|
||||||
continue;
|
continue;
|
||||||
for(i = 0; i < DIRSIZ && cp[i] != '/' && cp[i]; i++)
|
for(i = 0; i < DIRSIZ && cp[i] != '/' && cp[i]; i++)
|
||||||
if(cp[i] != ep->name[i])
|
if(cp[i] != ep->name[i])
|
||||||
|
@ -553,7 +553,7 @@ wdir(struct inode *dp, char *name, uint ino)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(off = 0; off < dp->size; off += sizeof(de)){
|
for(off = 0; off < dp->size; off += sizeof(de)){
|
||||||
if(readi(dp, (char *) &de, off, sizeof(de)) != sizeof(de))
|
if(readi(dp, (char*) &de, off, sizeof(de)) != sizeof(de))
|
||||||
panic("wdir read");
|
panic("wdir read");
|
||||||
if(de.inum == 0)
|
if(de.inum == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -565,17 +565,17 @@ wdir(struct inode *dp, char *name, uint ino)
|
||||||
for( ; i < DIRSIZ; i++)
|
for( ; i < DIRSIZ; i++)
|
||||||
de.name[i] = '\0';
|
de.name[i] = '\0';
|
||||||
|
|
||||||
if(writei(dp, (char *) &de, off, sizeof(de)) != sizeof(de))
|
if(writei(dp, (char*) &de, off, sizeof(de)) != sizeof(de))
|
||||||
panic("wdir write");
|
panic("wdir write");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct inode *
|
struct inode*
|
||||||
mknod(char *cp, short type, short major, short minor)
|
mknod(char *cp, short type, short major, short minor)
|
||||||
{
|
{
|
||||||
struct inode *ip, *dp;
|
struct inode *ip, *dp;
|
||||||
char *last;
|
char *last;
|
||||||
|
|
||||||
if ((dp = namei(cp, NAMEI_CREATE, 0, &last, 0)) == 0)
|
if((dp = namei(cp, NAMEI_CREATE, 0, &last, 0)) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ip = mknod1(dp, last, type, major, minor);
|
ip = mknod1(dp, last, type, major, minor);
|
||||||
|
@ -585,21 +585,21 @@ mknod(char *cp, short type, short major, short minor)
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct inode *
|
struct inode*
|
||||||
mknod1(struct inode *dp, char *name, short type, short major, short minor)
|
mknod1(struct inode *dp, char *name, short type, short major, short minor)
|
||||||
{
|
{
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
|
|
||||||
ip = ialloc(dp->dev, type);
|
ip = ialloc(dp->dev, type);
|
||||||
if (ip == 0)
|
if(ip == 0)
|
||||||
return 0;
|
return 0;
|
||||||
ip->major = major;
|
ip->major = major;
|
||||||
ip->minor = minor;
|
ip->minor = minor;
|
||||||
ip->size = 0;
|
ip->size = 0;
|
||||||
ip->nlink = 1;
|
ip->nlink = 1;
|
||||||
|
|
||||||
iupdate (ip); // write new inode to disk
|
iupdate(ip); // write new inode to disk
|
||||||
|
|
||||||
wdir(dp, name, ip->inum);
|
wdir(dp, name, ip->inum);
|
||||||
|
|
||||||
return ip;
|
return ip;
|
||||||
|
@ -611,7 +611,7 @@ unlink(char *cp)
|
||||||
struct inode *ip, *dp;
|
struct inode *ip, *dp;
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
uint off, inum, dev;
|
uint off, inum, dev;
|
||||||
|
|
||||||
dp = namei(cp, NAMEI_DELETE, &off, 0, 0);
|
dp = namei(cp, NAMEI_DELETE, &off, 0, 0);
|
||||||
if(dp == 0)
|
if(dp == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -626,7 +626,7 @@ unlink(char *cp)
|
||||||
memset(&de, 0, sizeof(de));
|
memset(&de, 0, sizeof(de));
|
||||||
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
||||||
panic("unlink dir write");
|
panic("unlink dir write");
|
||||||
|
|
||||||
iupdate(dp);
|
iupdate(dp);
|
||||||
iput(dp);
|
iput(dp);
|
||||||
|
|
||||||
|
@ -649,7 +649,7 @@ link(char *name1, char *name2)
|
||||||
struct inode *ip, *dp;
|
struct inode *ip, *dp;
|
||||||
char *last;
|
char *last;
|
||||||
|
|
||||||
if ((ip = namei(name1, NAMEI_LOOKUP, 0, 0, 0)) == 0)
|
if((ip = namei(name1, NAMEI_LOOKUP, 0, 0, 0)) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(ip->type == T_DIR){
|
if(ip->type == T_DIR){
|
||||||
iput(ip);
|
iput(ip);
|
||||||
|
@ -658,7 +658,7 @@ link(char *name1, char *name2)
|
||||||
|
|
||||||
iunlock(ip);
|
iunlock(ip);
|
||||||
|
|
||||||
if ((dp = namei(name2, NAMEI_CREATE, 0, &last, 0)) == 0) {
|
if((dp = namei(name2, NAMEI_CREATE, 0, &last, 0)) == 0) {
|
||||||
idecref(ip);
|
idecref(ip);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -667,10 +667,10 @@ link(char *name1, char *name2)
|
||||||
iput(dp);
|
iput(dp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ilock(ip);
|
ilock(ip);
|
||||||
ip->nlink += 1;
|
ip->nlink += 1;
|
||||||
iupdate (ip);
|
iupdate(ip);
|
||||||
|
|
||||||
wdir(dp, last, ip->inum);
|
wdir(dp, last, ip->inum);
|
||||||
iput(dp);
|
iput(dp);
|
||||||
|
|
|
@ -151,7 +151,7 @@ createdelete()
|
||||||
|
|
||||||
if(pid)
|
if(pid)
|
||||||
exit();
|
exit();
|
||||||
else
|
else
|
||||||
exit();
|
exit();
|
||||||
|
|
||||||
for(i = 0; i < n; i++){
|
for(i = 0; i < n; i++){
|
||||||
|
@ -198,7 +198,7 @@ void
|
||||||
unlinkread()
|
unlinkread()
|
||||||
{
|
{
|
||||||
int fd, fd1;
|
int fd, fd1;
|
||||||
|
|
||||||
fd = open("unlinkread", O_CREATE | O_RDWR);
|
fd = open("unlinkread", O_CREATE | O_RDWR);
|
||||||
if(fd < 0){
|
if(fd < 0){
|
||||||
puts("create unlinkread failed\n");
|
puts("create unlinkread failed\n");
|
||||||
|
@ -278,7 +278,7 @@ linktest()
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if(link("lf2", "lf2") >= 0){
|
if(link("lf2", "lf2") >= 0){
|
||||||
puts("link lf2 lf2 succeeded! oops\n");
|
puts("link lf2 lf2 succeeded! oops\n");
|
||||||
exit();
|
exit();
|
||||||
|
@ -591,7 +591,7 @@ bigfile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
fd = open("bigfile", 0);
|
fd = open("bigfile", 0);
|
||||||
if(fd < 0){
|
if(fd < 0){
|
||||||
puts("cannot open bigfile\n");
|
puts("cannot open bigfile\n");
|
||||||
|
|
32
ide.c
32
ide.c
|
@ -37,10 +37,10 @@ ide_wait_ready(int check_error)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
|
while(((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
|
|
||||||
if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
|
if(check_error && (r & (IDE_DF|IDE_ERR)) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -74,13 +74,13 @@ ide_probe_disk1(void)
|
||||||
outb(0x1F6, 0xE0 | (1<<4));
|
outb(0x1F6, 0xE0 | (1<<4));
|
||||||
|
|
||||||
// check for Device 1 to be ready for a while
|
// check for Device 1 to be ready for a while
|
||||||
for (x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
|
for(x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
|
|
||||||
// switch back to Device 0
|
// switch back to Device 0
|
||||||
outb(0x1F6, 0xE0 | (0<<4));
|
outb(0x1F6, 0xE0 | (0<<4));
|
||||||
|
|
||||||
return (x < 1000);
|
return x < 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -88,7 +88,7 @@ ide_start_request (void)
|
||||||
{
|
{
|
||||||
struct ide_request *r;
|
struct ide_request *r;
|
||||||
|
|
||||||
if (head != tail) {
|
if(head != tail) {
|
||||||
r = &request[tail];
|
r = &request[tail];
|
||||||
ide_wait_ready(0);
|
ide_wait_ready(0);
|
||||||
outb(0x3f6, 0); // generate interrupt
|
outb(0x3f6, 0); // generate interrupt
|
||||||
|
@ -97,7 +97,7 @@ ide_start_request (void)
|
||||||
outb(0x1F4, (r->secno >> 8) & 0xFF);
|
outb(0x1F4, (r->secno >> 8) & 0xFF);
|
||||||
outb(0x1F5, (r->secno >> 16) & 0xFF);
|
outb(0x1F5, (r->secno >> 16) & 0xFF);
|
||||||
outb(0x1F6, 0xE0 | ((r->diskno&1)<<4) | ((r->secno>>24)&0x0F));
|
outb(0x1F6, 0xE0 | ((r->diskno&1)<<4) | ((r->secno>>24)&0x0F));
|
||||||
if (r->read) outb(0x1F7, 0x20); // read
|
if(r->read) outb(0x1F7, 0x20); // read
|
||||||
else {
|
else {
|
||||||
outb(0x1F7, 0x30); // write
|
outb(0x1F7, 0x30); // write
|
||||||
outsl(0x1F0, r->addr, 512/4);
|
outsl(0x1F0, r->addr, 512/4);
|
||||||
|
@ -105,7 +105,7 @@ ide_start_request (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void*
|
||||||
ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
|
ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
|
||||||
{
|
{
|
||||||
struct ide_request *r;
|
struct ide_request *r;
|
||||||
|
@ -113,8 +113,8 @@ ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
|
||||||
if(diskno && !disk_1_present)
|
if(diskno && !disk_1_present)
|
||||||
panic("ide disk 1 not present");
|
panic("ide disk 1 not present");
|
||||||
|
|
||||||
while ((head + 1) % NREQUEST == tail)
|
while((head + 1) % NREQUEST == tail)
|
||||||
sleep (&disk_channel, &ide_lock);
|
sleep(&disk_channel, &ide_lock);
|
||||||
|
|
||||||
r = &request[head];
|
r = &request[head];
|
||||||
r->secno = secno;
|
r->secno = secno;
|
||||||
|
@ -134,17 +134,17 @@ int
|
||||||
ide_finish(void *c)
|
ide_finish(void *c)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct ide_request *req = (struct ide_request *) c;
|
struct ide_request *req = (struct ide_request*) c;
|
||||||
|
|
||||||
if (req->read) {
|
if(req->read) {
|
||||||
if ((r = ide_wait_ready(1)) >= 0)
|
if((r = ide_wait_ready(1)) >= 0)
|
||||||
insl(0x1F0, req->addr, 512/4);
|
insl(0x1F0, req->addr, 512/4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((head + 1) % NREQUEST == tail) {
|
if((head + 1) % NREQUEST == tail) {
|
||||||
wakeup(&disk_channel);
|
wakeup(&disk_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
tail = (tail + 1) % NREQUEST;
|
tail = (tail + 1) % NREQUEST;
|
||||||
ide_start_request();
|
ide_start_request();
|
||||||
|
|
||||||
|
@ -168,8 +168,8 @@ ide_write(int diskno, uint secno, const void *src, uint nsecs)
|
||||||
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
|
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) {
|
for(; nsecs > 0; nsecs--, src += 512) {
|
||||||
if ((r = ide_wait_ready(1)) < 0)
|
if((r = ide_wait_ready(1)) < 0)
|
||||||
return r;
|
return r;
|
||||||
outsl(0x1F0, src, 512/4);
|
outsl(0x1F0, src, 512/4);
|
||||||
}
|
}
|
||||||
|
|
2
init.c
2
init.c
|
@ -12,7 +12,7 @@ int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
if(open("console", O_RDWR) < 0){
|
if(open("console", O_RDWR) < 0){
|
||||||
mknod("console", T_DEV, 1, 1);
|
mknod("console", T_DEV, 1, 1);
|
||||||
open("console", O_RDWR);
|
open("console", O_RDWR);
|
||||||
|
|
14
ioapic.c
14
ioapic.c
|
@ -18,7 +18,7 @@ static uint
|
||||||
ioapic_read(struct ioapic *io, int reg)
|
ioapic_read(struct ioapic *io, int reg)
|
||||||
{
|
{
|
||||||
io->ioregsel = reg;
|
io->ioregsel = reg;
|
||||||
return (io->iowin);
|
return io->iowin;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -37,13 +37,13 @@ ioapic_init(void)
|
||||||
uchar id;
|
uchar id;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
io = (struct ioapic *) IO_APIC_BASE;
|
io = (struct ioapic*) IO_APIC_BASE;
|
||||||
l = ioapic_read(io, IOAPIC_VER);
|
l = ioapic_read(io, IOAPIC_VER);
|
||||||
nintr = ((l & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1;
|
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)
|
if(id != ioapic_id)
|
||||||
panic ("ioapic_init: id isn't equal to ioapic_id\n");
|
panic("ioapic_init: id isn't equal to ioapic_id\n");
|
||||||
for (i = 0; i < nintr; i++) {
|
for(i = 0; i < nintr; i++) {
|
||||||
// active-hi and edge-triggered for ISA interrupts
|
// active-hi and edge-triggered for ISA interrupts
|
||||||
// Assume that pin 0 on the first I/O APIC is an ExtINT pin.
|
// Assume that pin 0 on the first I/O APIC is an ExtINT pin.
|
||||||
// Assume that pins 1-15 are ISA interrupts
|
// Assume that pins 1-15 are ISA interrupts
|
||||||
|
@ -68,12 +68,12 @@ ioapic_enable (int irq, int cpunum)
|
||||||
uint l, h;
|
uint l, h;
|
||||||
struct ioapic *io;
|
struct ioapic *io;
|
||||||
|
|
||||||
io = (struct ioapic *) IO_APIC_BASE;
|
io = (struct ioapic*) IO_APIC_BASE;
|
||||||
l = ioapic_read(io, IOAPIC_REDTBL_LO(irq));
|
l = ioapic_read(io, IOAPIC_REDTBL_LO(irq));
|
||||||
l = l & ~IOART_INTMASK; // allow INTs
|
l = l & ~IOART_INTMASK; // allow INTs
|
||||||
ioapic_write(io, IOAPIC_REDTBL_LO(irq), l);
|
ioapic_write(io, IOAPIC_REDTBL_LO(irq), l);
|
||||||
h = ioapic_read(io, IOAPIC_REDTBL_HI(irq));
|
h = ioapic_read(io, IOAPIC_REDTBL_HI(irq));
|
||||||
h &= ~IOART_DEST;
|
h &= ~IOART_DEST;
|
||||||
h |= (cpunum << APIC_ID_SHIFT);
|
h |= (cpunum << APIC_ID_SHIFT);
|
||||||
ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);
|
ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);
|
||||||
}
|
}
|
||||||
|
|
16
kalloc.c
16
kalloc.c
|
@ -34,10 +34,10 @@ kinit(void)
|
||||||
extern int end;
|
extern int end;
|
||||||
uint mem;
|
uint mem;
|
||||||
char *start;
|
char *start;
|
||||||
|
|
||||||
initlock(&kalloc_lock, "kalloc");
|
initlock(&kalloc_lock, "kalloc");
|
||||||
start = (char *) &end;
|
start = (char*) &end;
|
||||||
start = (char *) (((uint)start + PAGE) & ~(PAGE-1));
|
start = (char*) (((uint)start + PAGE) & ~(PAGE-1));
|
||||||
mem = 256; // assume 256 pages of RAM
|
mem = 256; // assume 256 pages of RAM
|
||||||
cprintf("mem = %d\n", mem * PAGE);
|
cprintf("mem = %d\n", mem * PAGE);
|
||||||
kfree(start, mem * PAGE);
|
kfree(start, mem * PAGE);
|
||||||
|
@ -47,8 +47,8 @@ void
|
||||||
kfree(char *cp, int len)
|
kfree(char *cp, int len)
|
||||||
{
|
{
|
||||||
struct run **rr;
|
struct run **rr;
|
||||||
struct run *p = (struct run *) cp;
|
struct run *p = (struct run*) cp;
|
||||||
struct run *pend = (struct run *) (cp + len);
|
struct run *pend = (struct run*) (cp + len);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(len % PAGE)
|
if(len % PAGE)
|
||||||
|
@ -62,7 +62,7 @@ kfree(char *cp, int len)
|
||||||
|
|
||||||
rr = &freelist;
|
rr = &freelist;
|
||||||
while(*rr){
|
while(*rr){
|
||||||
struct run *rend = (struct run *) ((char *)(*rr) + (*rr)->len);
|
struct run *rend = (struct run*) ((char*)(*rr) + (*rr)->len);
|
||||||
if(p >= *rr && p < rend)
|
if(p >= *rr && p < rend)
|
||||||
panic("freeing free page");
|
panic("freeing free page");
|
||||||
if(pend == *rr){
|
if(pend == *rr){
|
||||||
|
@ -116,10 +116,10 @@ kalloc(int n)
|
||||||
if(r->len == n){
|
if(r->len == n){
|
||||||
*rr = r->next;
|
*rr = r->next;
|
||||||
release(&kalloc_lock);
|
release(&kalloc_lock);
|
||||||
return (char *) r;
|
return (char*) r;
|
||||||
}
|
}
|
||||||
if(r->len > n){
|
if(r->len > n){
|
||||||
char *p = (char *)r + (r->len - n);
|
char *p = (char*)r + (r->len - n);
|
||||||
r->len -= n;
|
r->len -= n;
|
||||||
release(&kalloc_lock);
|
release(&kalloc_lock);
|
||||||
return p;
|
return p;
|
||||||
|
|
14
lapic.c
14
lapic.c
|
@ -114,7 +114,7 @@ lapic_timerinit(void)
|
||||||
void
|
void
|
||||||
lapic_timerintr(void)
|
lapic_timerintr(void)
|
||||||
{
|
{
|
||||||
lapic_write (LAPIC_EOI, 0);
|
lapic_write(LAPIC_EOI, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -151,13 +151,13 @@ lapic_init(int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lapic_enableintr(void)
|
lapic_enableintr(void)
|
||||||
{
|
{
|
||||||
lapic_write(LAPIC_TPR, 0);
|
lapic_write(LAPIC_TPR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lapic_disableintr(void)
|
lapic_disableintr(void)
|
||||||
{
|
{
|
||||||
lapic_write(LAPIC_TPR, 0xFF);
|
lapic_write(LAPIC_TPR, 0xFF);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ lapic_disableintr(void)
|
||||||
void
|
void
|
||||||
lapic_eoi(void)
|
lapic_eoi(void)
|
||||||
{
|
{
|
||||||
lapic_write (LAPIC_EOI, 0);
|
lapic_write(LAPIC_EOI, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -185,15 +185,15 @@ lapic_startap(uchar apicid, int v)
|
||||||
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) {;}
|
||||||
|
|
||||||
// in p9 code, this was i < 2, which is what the spec says on page B-3
|
// in p9 code, this was i < 2, which is what the spec says on page B-3
|
||||||
for(i = 0; i < 1; i++){
|
for(i = 0; i < 1; i++){
|
||||||
lapic_write(LAPIC_ICRHI, crhi);
|
lapic_write(LAPIC_ICRHI, crhi);
|
||||||
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/4096));
|
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/4096));
|
||||||
while (j++ < 100000) {;}
|
while(j++ < 100000) {;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
ls.c
18
ls.c
|
@ -12,10 +12,10 @@ pname(char *n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; (i < DIRSIZ) && (n[i] != '\0') ; i++) {
|
for(i = 0; (i < DIRSIZ) && (n[i] != '\0') ; i++) {
|
||||||
printf(1, "%c", n[i]);
|
printf(1, "%c", n[i]);
|
||||||
}
|
}
|
||||||
for (; i < DIRSIZ; i++)
|
for(; i < DIRSIZ; i++)
|
||||||
printf(1, " ");
|
printf(1, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,12 +31,12 @@ main(int argc, char *argv[])
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 2) {
|
if(argc == 2) {
|
||||||
fd = open(argv[1], 0);
|
fd = open(argv[1], 0);
|
||||||
if(fd < 0){
|
if(fd < 0){
|
||||||
printf(2, "ls: cannot open %s\n", argv[1]);
|
printf(2, "ls: cannot open %s\n", argv[1]);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fd = open(".", 0);
|
fd = open(".", 0);
|
||||||
if(fd < 0){
|
if(fd < 0){
|
||||||
|
@ -45,12 +45,12 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fd, &st) < 0) {
|
if(fstat(fd, &st) < 0) {
|
||||||
printf(2, "ls: cannot stat dir\n");
|
printf(2, "ls: cannot stat dir\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (st.st_type) {
|
switch(st.st_type) {
|
||||||
case T_FILE:
|
case T_FILE:
|
||||||
pname(argv[1]);
|
pname(argv[1]);
|
||||||
printf(1, "%d %d %d\n", st.st_type, st.st_ino, st.st_size);
|
printf(1, "%d %d %d\n", st.st_type, st.st_ino, st.st_size);
|
||||||
|
@ -58,13 +58,13 @@ 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(struct dirent)) != sizeof(struct dirent)) {
|
||||||
printf(1, "ls: read error\n");
|
printf(1, "ls: read error\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dirent.inum != 0) {
|
if(dirent.inum != 0) {
|
||||||
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
|
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
|
||||||
if (stat (dirent.name, &st) < 0) {
|
if(stat (dirent.name, &st) < 0) {
|
||||||
printf(1, "stat: failed %s\n", dirent.name);
|
printf(1, "stat: failed %s\n", dirent.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
14
main.c
14
main.c
|
@ -66,7 +66,7 @@ main0(void)
|
||||||
|
|
||||||
// initialize I/O devices, let them enable interrupts
|
// initialize I/O devices, let them enable interrupts
|
||||||
console_init();
|
console_init();
|
||||||
ide_init();
|
ide_init();
|
||||||
|
|
||||||
// start other CPUs
|
// start other CPUs
|
||||||
mp_startthem();
|
mp_startthem();
|
||||||
|
@ -136,7 +136,7 @@ process0()
|
||||||
p0->tf->esp = p0->sz;
|
p0->tf->esp = p0->sz;
|
||||||
|
|
||||||
p1 = copyproc(p0);
|
p1 = copyproc(p0);
|
||||||
|
|
||||||
load_icode(p1, _binary_init_start, (uint) _binary_init_size);
|
load_icode(p1, _binary_init_start, (uint) _binary_init_size);
|
||||||
p1->state = RUNNABLE;
|
p1->state = RUNNABLE;
|
||||||
|
|
||||||
|
@ -152,19 +152,19 @@ load_icode(struct proc *p, uchar *binary, uint size)
|
||||||
struct proghdr *ph;
|
struct proghdr *ph;
|
||||||
|
|
||||||
elf = (struct elfhdr*) binary;
|
elf = (struct elfhdr*) binary;
|
||||||
if (elf->magic != ELF_MAGIC)
|
if(elf->magic != ELF_MAGIC)
|
||||||
panic("load_icode: not an ELF binary");
|
panic("load_icode: not an ELF binary");
|
||||||
|
|
||||||
p->tf->eip = elf->entry;
|
p->tf->eip = elf->entry;
|
||||||
|
|
||||||
// Map and load segments as directed.
|
// Map and load segments as directed.
|
||||||
ph = (struct proghdr*) (binary + elf->phoff);
|
ph = (struct proghdr*) (binary + elf->phoff);
|
||||||
for (i = 0; i < elf->phnum; i++, ph++) {
|
for(i = 0; i < elf->phnum; i++, ph++) {
|
||||||
if (ph->type != ELF_PROG_LOAD)
|
if(ph->type != ELF_PROG_LOAD)
|
||||||
continue;
|
continue;
|
||||||
if (ph->va + ph->memsz < ph->va)
|
if(ph->va + ph->memsz < ph->va)
|
||||||
panic("load_icode: overflow in elf header segment");
|
panic("load_icode: overflow in elf header segment");
|
||||||
if (ph->va + ph->memsz >= p->sz)
|
if(ph->va + ph->memsz >= p->sz)
|
||||||
panic("load_icode: icode wants to be above UTOP");
|
panic("load_icode: icode wants to be above UTOP");
|
||||||
|
|
||||||
// Load/clear the segment
|
// Load/clear the segment
|
||||||
|
|
2
mkdir.c
2
mkdir.c
|
@ -12,7 +12,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 1; i < argc; i++){
|
for(i = 1; i < argc; i++){
|
||||||
if (mkdir(argv[i]) < 0) {
|
if(mkdir(argv[i]) < 0) {
|
||||||
printf(2, "mkdir: %s failed to create\n", argv[i]);
|
printf(2, "mkdir: %s failed to create\n", argv[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
36
mkfs.c
36
mkfs.c
|
@ -21,8 +21,8 @@ uint bitblocks;
|
||||||
uint freeinode = 1;
|
uint freeinode = 1;
|
||||||
|
|
||||||
void balloc(int);
|
void balloc(int);
|
||||||
void wsect(uint, void *);
|
void wsect(uint, void*);
|
||||||
void winode(uint, struct dinode *);
|
void winode(uint, struct dinode*);
|
||||||
void rinode(uint inum, struct dinode *ip);
|
void rinode(uint inum, struct dinode *ip);
|
||||||
void rsect(uint sec, void *buf);
|
void rsect(uint sec, void *buf);
|
||||||
uint ialloc(ushort type);
|
uint ialloc(ushort type);
|
||||||
|
@ -33,7 +33,7 @@ ushort
|
||||||
xshort(ushort x)
|
xshort(ushort x)
|
||||||
{
|
{
|
||||||
ushort y;
|
ushort y;
|
||||||
uchar *a = (uchar *) &y;
|
uchar *a = (uchar*) &y;
|
||||||
a[0] = x;
|
a[0] = x;
|
||||||
a[1] = x >> 8;
|
a[1] = x >> 8;
|
||||||
return y;
|
return y;
|
||||||
|
@ -43,7 +43,7 @@ uint
|
||||||
xint(uint x)
|
xint(uint x)
|
||||||
{
|
{
|
||||||
uint y;
|
uint y;
|
||||||
uchar *a = (uchar *) &y;
|
uchar *a = (uchar*) &y;
|
||||||
a[0] = x;
|
a[0] = x;
|
||||||
a[1] = x >> 8;
|
a[1] = x >> 8;
|
||||||
a[2] = x >> 16;
|
a[2] = x >> 16;
|
||||||
|
@ -77,14 +77,14 @@ main(int argc, char *argv[])
|
||||||
sb.nblocks = xint(nblocks); // so whole disk is size sectors
|
sb.nblocks = xint(nblocks); // so whole disk is size sectors
|
||||||
sb.ninodes = xint(ninodes);
|
sb.ninodes = xint(ninodes);
|
||||||
|
|
||||||
bitblocks = size/(512*8) + 1;
|
bitblocks = size/(512*8) + 1;
|
||||||
usedblocks = ninodes / IPB + 3 + bitblocks;
|
usedblocks = ninodes / IPB + 3 + bitblocks;
|
||||||
freeblock = usedblocks;
|
freeblock = usedblocks;
|
||||||
|
|
||||||
printf("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,
|
printf("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,
|
||||||
bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks);
|
bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks);
|
||||||
|
|
||||||
assert (nblocks + usedblocks == size);
|
assert(nblocks + usedblocks == size);
|
||||||
|
|
||||||
for(i = 0; i < nblocks + usedblocks; i++)
|
for(i = 0; i < nblocks + usedblocks; i++)
|
||||||
wsect(i, zeroes);
|
wsect(i, zeroes);
|
||||||
|
@ -118,7 +118,7 @@ main(int argc, char *argv[])
|
||||||
de.inum = xshort(inum);
|
de.inum = xshort(inum);
|
||||||
strncpy(de.name, argv[i], DIRSIZ);
|
strncpy(de.name, argv[i], DIRSIZ);
|
||||||
iappend(rootino, &de, sizeof(de));
|
iappend(rootino, &de, sizeof(de));
|
||||||
|
|
||||||
while((cc = read(fd, buf, sizeof(buf))) > 0)
|
while((cc = read(fd, buf, sizeof(buf))) > 0)
|
||||||
iappend(inum, buf, cc);
|
iappend(inum, buf, cc);
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
// fix size of root inode dir
|
// fix size of root inode dir
|
||||||
rinode(rootino, &din);
|
rinode(rootino, &din);
|
||||||
off = xint(din.size);
|
off = xint(din.size);
|
||||||
off = ((off/BSIZE) + 1) * BSIZE;
|
off = ((off/BSIZE) + 1) * BSIZE;
|
||||||
din.size = xint(off);
|
din.size = xint(off);
|
||||||
winode(rootino, &din);
|
winode(rootino, &din);
|
||||||
|
@ -165,7 +165,7 @@ winode(uint inum, struct dinode *ip)
|
||||||
|
|
||||||
bn = i2b(inum);
|
bn = i2b(inum);
|
||||||
rsect(bn, buf);
|
rsect(bn, buf);
|
||||||
dip = ((struct dinode *) buf) + (inum % IPB);
|
dip = ((struct dinode*) buf) + (inum % IPB);
|
||||||
*dip = *ip;
|
*dip = *ip;
|
||||||
wsect(bn, buf);
|
wsect(bn, buf);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ rinode(uint inum, struct dinode *ip)
|
||||||
|
|
||||||
bn = i2b(inum);
|
bn = i2b(inum);
|
||||||
rsect(bn, buf);
|
rsect(bn, buf);
|
||||||
dip = ((struct dinode *) buf) + (inum % IPB);
|
dip = ((struct dinode*) buf) + (inum % IPB);
|
||||||
*ip = *dip;
|
*ip = *dip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,9 +217,9 @@ balloc(int used)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("balloc: first %d blocks have been allocated\n", used);
|
printf("balloc: first %d blocks have been allocated\n", used);
|
||||||
assert (used < 512);
|
assert(used < 512);
|
||||||
bzero(buf, 512);
|
bzero(buf, 512);
|
||||||
for (i = 0; i < used; i++) {
|
for(i = 0; i < used; i++) {
|
||||||
buf[i/8] = buf[i/8] | (0x1 << (i%8));
|
buf[i/8] = buf[i/8] | (0x1 << (i%8));
|
||||||
}
|
}
|
||||||
printf("balloc: write bitmap block at sector %d\n", ninodes/IPB + 3);
|
printf("balloc: write bitmap block at sector %d\n", ninodes/IPB + 3);
|
||||||
|
@ -231,7 +231,7 @@ balloc(int used)
|
||||||
void
|
void
|
||||||
iappend(uint inum, void *xp, int n)
|
iappend(uint inum, void *xp, int n)
|
||||||
{
|
{
|
||||||
char *p = (char *) xp;
|
char *p = (char*) xp;
|
||||||
uint fbn, off, n1;
|
uint fbn, off, n1;
|
||||||
struct dinode din;
|
struct dinode din;
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
@ -244,7 +244,7 @@ iappend(uint inum, void *xp, int n)
|
||||||
while(n > 0){
|
while(n > 0){
|
||||||
fbn = off / 512;
|
fbn = off / 512;
|
||||||
assert(fbn < MAXFILE);
|
assert(fbn < MAXFILE);
|
||||||
if (fbn < NDIRECT) {
|
if(fbn < NDIRECT) {
|
||||||
if(xint(din.addrs[fbn]) == 0) {
|
if(xint(din.addrs[fbn]) == 0) {
|
||||||
din.addrs[fbn] = xint(freeblock++);
|
din.addrs[fbn] = xint(freeblock++);
|
||||||
usedblocks++;
|
usedblocks++;
|
||||||
|
@ -257,11 +257,11 @@ iappend(uint inum, void *xp, int n)
|
||||||
usedblocks++;
|
usedblocks++;
|
||||||
}
|
}
|
||||||
printf("read indirect block\n");
|
printf("read indirect block\n");
|
||||||
rsect(xint(din.addrs[INDIRECT]), (char *) indirect);
|
rsect(xint(din.addrs[INDIRECT]), (char*) indirect);
|
||||||
if (indirect[fbn - NDIRECT] == 0) {
|
if(indirect[fbn - NDIRECT] == 0) {
|
||||||
indirect[fbn - NDIRECT] = xint(freeblock++);
|
indirect[fbn - NDIRECT] = xint(freeblock++);
|
||||||
usedblocks++;
|
usedblocks++;
|
||||||
wsect(xint(din.addrs[INDIRECT]), (char *) indirect);
|
wsect(xint(din.addrs[INDIRECT]), (char*) indirect);
|
||||||
}
|
}
|
||||||
x = xint(indirect[fbn-NDIRECT]);
|
x = xint(indirect[fbn-NDIRECT]);
|
||||||
}
|
}
|
||||||
|
|
12
mmu.h
12
mmu.h
|
@ -84,21 +84,21 @@ struct taskstate {
|
||||||
uint esp0; // Stack pointers and segment selectors
|
uint esp0; // Stack pointers and segment selectors
|
||||||
ushort ss0; // after an increase in privilege level
|
ushort ss0; // after an increase in privilege level
|
||||||
ushort padding1;
|
ushort padding1;
|
||||||
uint * esp1;
|
uint *esp1;
|
||||||
ushort ss1;
|
ushort ss1;
|
||||||
ushort padding2;
|
ushort padding2;
|
||||||
uint * esp2;
|
uint *esp2;
|
||||||
ushort ss2;
|
ushort ss2;
|
||||||
ushort padding3;
|
ushort padding3;
|
||||||
void * cr3; // Page directory base
|
void *cr3; // Page directory base
|
||||||
uint * eip; // Saved state from last task switch
|
uint *eip; // Saved state from last task switch
|
||||||
uint eflags;
|
uint eflags;
|
||||||
uint eax; // More saved state (registers)
|
uint eax; // More saved state (registers)
|
||||||
uint ecx;
|
uint ecx;
|
||||||
uint edx;
|
uint edx;
|
||||||
uint ebx;
|
uint ebx;
|
||||||
uint * esp;
|
uint *esp;
|
||||||
uint * ebp;
|
uint *ebp;
|
||||||
uint esi;
|
uint esi;
|
||||||
uint edi;
|
uint edi;
|
||||||
ushort es; // Even more saved state (segment selectors)
|
ushort es; // Even more saved state (segment selectors)
|
||||||
|
|
38
mp.c
38
mp.c
|
@ -7,7 +7,7 @@
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
|
|
||||||
static char* buses[] = {
|
static char *buses[] = {
|
||||||
"CBUSI ",
|
"CBUSI ",
|
||||||
"CBUSII",
|
"CBUSII",
|
||||||
"EISA ",
|
"EISA ",
|
||||||
|
@ -34,7 +34,7 @@ int ncpu;
|
||||||
uchar ioapic_id;
|
uchar ioapic_id;
|
||||||
|
|
||||||
static struct cpu *bcpu;
|
static struct cpu *bcpu;
|
||||||
static struct mp* mp; // The MP floating point structure
|
static struct mp *mp; // The MP floating point structure
|
||||||
|
|
||||||
static struct mp*
|
static struct mp*
|
||||||
mp_scan(uchar *addr, int len)
|
mp_scan(uchar *addr, int len)
|
||||||
|
@ -50,7 +50,7 @@ mp_scan(uchar *addr, int len)
|
||||||
for(i = 0; i < sizeof(struct mp); i++)
|
for(i = 0; i < sizeof(struct mp); i++)
|
||||||
sum += p[i];
|
sum += p[i];
|
||||||
if(sum == 0)
|
if(sum == 0)
|
||||||
return (struct mp *)p;
|
return (struct mp*)p;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ mp_search(void)
|
||||||
return mp_scan((uchar*)0xF0000, 0x10000);
|
return mp_scan((uchar*)0xF0000, 0x10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mp_detect(void)
|
mp_detect(void)
|
||||||
{
|
{
|
||||||
struct mpctb *pcmp;
|
struct mpctb *pcmp;
|
||||||
|
@ -99,7 +99,7 @@ mp_detect(void)
|
||||||
if((mp = mp_search()) == 0 || mp->physaddr == 0)
|
if((mp = mp_search()) == 0 || mp->physaddr == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
pcmp = (struct mpctb *) mp->physaddr;
|
pcmp = (struct mpctb*) mp->physaddr;
|
||||||
if(memcmp(pcmp, "PCMP", 4))
|
if(memcmp(pcmp, "PCMP", 4))
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ mp_detect(void)
|
||||||
|
|
||||||
void
|
void
|
||||||
mp_init(void)
|
mp_init(void)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
uchar *p, *e;
|
uchar *p, *e;
|
||||||
struct mpctb *mpctb;
|
struct mpctb *mpctb;
|
||||||
|
@ -128,31 +128,31 @@ mp_init(void)
|
||||||
uchar byte;
|
uchar byte;
|
||||||
|
|
||||||
ncpu = 0;
|
ncpu = 0;
|
||||||
if ((r = mp_detect()) != 0) return;
|
if((r = mp_detect()) != 0) return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run through the table saving information needed for starting
|
* Run through the table saving information needed for starting
|
||||||
* application processors and initialising any I/O APICs. The table
|
* application processors and initialising any I/O APICs. The table
|
||||||
* is guaranteed to be in order such that only one pass is necessary.
|
* is guaranteed to be in order such that only one pass is necessary.
|
||||||
*/
|
*/
|
||||||
mpctb = (struct mpctb *) mp->physaddr;
|
mpctb = (struct mpctb*) mp->physaddr;
|
||||||
lapicaddr = (uint *) mpctb->lapicaddr;
|
lapicaddr = (uint*) mpctb->lapicaddr;
|
||||||
p = ((uchar*)mpctb)+sizeof(struct mpctb);
|
p = ((uchar*)mpctb)+sizeof(struct mpctb);
|
||||||
e = ((uchar*)mpctb)+mpctb->length;
|
e = ((uchar*)mpctb)+mpctb->length;
|
||||||
|
|
||||||
while(p < e) {
|
while(p < e) {
|
||||||
switch(*p){
|
switch(*p){
|
||||||
case MPPROCESSOR:
|
case MPPROCESSOR:
|
||||||
proc = (struct mppe *) p;
|
proc = (struct mppe*) p;
|
||||||
cpus[ncpu].apicid = proc->apicid;
|
cpus[ncpu].apicid = proc->apicid;
|
||||||
if (proc->flags & MPBP) {
|
if(proc->flags & MPBP) {
|
||||||
bcpu = &cpus[ncpu];
|
bcpu = &cpus[ncpu];
|
||||||
}
|
}
|
||||||
ncpu++;
|
ncpu++;
|
||||||
p += sizeof(struct mppe);
|
p += sizeof(struct mppe);
|
||||||
continue;
|
continue;
|
||||||
case MPBUS:
|
case MPBUS:
|
||||||
bus = (struct mpbe *) p;
|
bus = (struct mpbe*) p;
|
||||||
for(i = 0; buses[i]; i++){
|
for(i = 0; buses[i]; i++){
|
||||||
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
|
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -160,12 +160,12 @@ mp_init(void)
|
||||||
p += sizeof(struct mpbe);
|
p += sizeof(struct mpbe);
|
||||||
continue;
|
continue;
|
||||||
case MPIOAPIC:
|
case MPIOAPIC:
|
||||||
ioapic = (struct mpioapic *) p;
|
ioapic = (struct mpioapic*) p;
|
||||||
ioapic_id = ioapic->apicno;
|
ioapic_id = ioapic->apicno;
|
||||||
p += sizeof(struct mpioapic);
|
p += sizeof(struct mpioapic);
|
||||||
continue;
|
continue;
|
||||||
case MPIOINTR:
|
case MPIOINTR:
|
||||||
intr = (struct mpie *) p;
|
intr = (struct mpie*) p;
|
||||||
p += sizeof(struct mpie);
|
p += sizeof(struct mpie);
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
|
@ -178,7 +178,7 @@ mp_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp->imcrp) { // it appears that bochs doesn't support IMCR, and code won't run
|
if(mp->imcrp) { // it appears that bochs doesn't support IMCR, and code won't run
|
||||||
outb(0x22, 0x70); /* select IMCR */
|
outb(0x22, 0x70); /* select IMCR */
|
||||||
byte = inb(0x23); /* current contents */
|
byte = inb(0x23); /* current contents */
|
||||||
byte |= 0x01; /* mask external INTR */
|
byte |= 0x01; /* mask external INTR */
|
||||||
|
@ -204,13 +204,13 @@ mp_startthem(void)
|
||||||
extern int main();
|
extern int main();
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
memmove((void *) APBOOTCODE,_binary_bootother_start,
|
memmove((void*) APBOOTCODE,_binary_bootother_start,
|
||||||
(uint) _binary_bootother_size);
|
(uint) _binary_bootother_size);
|
||||||
|
|
||||||
for(c = 0; c < ncpu; c++){
|
for(c = 0; c < ncpu; c++){
|
||||||
if (c == cpu()) continue;
|
if(c == cpu()) continue;
|
||||||
*(uint *)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp
|
*(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
|
*(uint*)(APBOOTCODE-8) = (uint)mpmain; // tell it where to jump to
|
||||||
lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
|
lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
|
||||||
while(cpus[c].booted == 0)
|
while(cpus[c].booted == 0)
|
||||||
;
|
;
|
||||||
|
|
8
mp.h
8
mp.h
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
struct mp { /* floating pointer */
|
struct mp { /* floating pointer */
|
||||||
uchar signature[4]; /* "_MP_" */
|
uchar signature[4]; /* "_MP_" */
|
||||||
void* physaddr; /* physical address of MP configuration table */
|
void *physaddr; /* physical address of MP configuration table */
|
||||||
uchar length; /* 1 */
|
uchar length; /* 1 */
|
||||||
uchar specrev; /* [14] */
|
uchar specrev; /* [14] */
|
||||||
uchar checksum; /* all bytes must add up to 0 */
|
uchar checksum; /* all bytes must add up to 0 */
|
||||||
|
@ -20,10 +20,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;
|
||||||
|
@ -50,7 +50,7 @@ struct mpioapic { /* I/O APIC table entry */
|
||||||
uchar apicno; /* I/O APIC id */
|
uchar apicno; /* I/O APIC id */
|
||||||
uchar version; /* I/O APIC version */
|
uchar version; /* I/O APIC version */
|
||||||
uchar flags; /* I/O APIC flags */
|
uchar flags; /* I/O APIC flags */
|
||||||
uint * addr; /* I/O APIC address */
|
uint *addr; /* I/O APIC address */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mpie { /* interrupt table entry */
|
struct mpie { /* interrupt table entry */
|
||||||
|
|
2
picirq.c
2
picirq.c
|
@ -73,6 +73,6 @@ pic_init(void)
|
||||||
outb(IO_PIC2, 0x68); /* OCW3 */
|
outb(IO_PIC2, 0x68); /* OCW3 */
|
||||||
outb(IO_PIC2, 0x0a); /* OCW3 */
|
outb(IO_PIC2, 0x0a); /* OCW3 */
|
||||||
|
|
||||||
if (irq_mask_8259A != 0xFFFF)
|
if(irq_mask_8259A != 0xFFFF)
|
||||||
irq_setmask_8259A(irq_mask_8259A);
|
irq_setmask_8259A(irq_mask_8259A);
|
||||||
}
|
}
|
||||||
|
|
8
pipe.c
8
pipe.c
|
@ -28,7 +28,7 @@ pipe_alloc(struct fd **fd1, struct fd **fd2)
|
||||||
goto oops;
|
goto oops;
|
||||||
if((*fd2 = fd_alloc()) == 0)
|
if((*fd2 = fd_alloc()) == 0)
|
||||||
goto oops;
|
goto oops;
|
||||||
if((p = (struct pipe *) kalloc(PAGE)) == 0)
|
if((p = (struct pipe*) kalloc(PAGE)) == 0)
|
||||||
goto oops;
|
goto oops;
|
||||||
p->readopen = 1;
|
p->readopen = 1;
|
||||||
p->writeopen = 1;
|
p->writeopen = 1;
|
||||||
|
@ -46,7 +46,7 @@ pipe_alloc(struct fd **fd1, struct fd **fd2)
|
||||||
return 0;
|
return 0;
|
||||||
oops:
|
oops:
|
||||||
if(p)
|
if(p)
|
||||||
kfree((char *) p, PAGE);
|
kfree((char*) p, PAGE);
|
||||||
if(*fd1){
|
if(*fd1){
|
||||||
(*fd1)->type = FD_NONE;
|
(*fd1)->type = FD_NONE;
|
||||||
fd_close(*fd1);
|
fd_close(*fd1);
|
||||||
|
@ -70,11 +70,11 @@ pipe_close(struct pipe *p, int writeable)
|
||||||
p->readopen = 0;
|
p->readopen = 0;
|
||||||
wakeup(&p->writep);
|
wakeup(&p->writep);
|
||||||
}
|
}
|
||||||
|
|
||||||
release(&p->lock);
|
release(&p->lock);
|
||||||
|
|
||||||
if(p->readopen == 0 && p->writeopen == 0)
|
if(p->readopen == 0 && p->writeopen == 0)
|
||||||
kfree((char *) p, PAGE);
|
kfree((char*) p, PAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
6
printf.c
6
printf.c
|
@ -5,7 +5,7 @@
|
||||||
static void
|
static void
|
||||||
putc(int fd, char c)
|
putc(int fd, char c)
|
||||||
{
|
{
|
||||||
write (fd, &c, 1);
|
write(fd, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -15,7 +15,7 @@ printint(int fd, int xx, int base, int sgn)
|
||||||
char digits[] = "0123456789ABCDEF";
|
char digits[] = "0123456789ABCDEF";
|
||||||
int i = 0, neg = 0;
|
int i = 0, neg = 0;
|
||||||
uint x;
|
uint x;
|
||||||
|
|
||||||
if(sgn && xx < 0){
|
if(sgn && xx < 0){
|
||||||
neg = 1;
|
neg = 1;
|
||||||
x = 0 - xx;
|
x = 0 - xx;
|
||||||
|
@ -40,7 +40,7 @@ void
|
||||||
printf(int fd, char *fmt, ...)
|
printf(int fd, char *fmt, ...)
|
||||||
{
|
{
|
||||||
int i, state = 0, c;
|
int i, state = 0, c;
|
||||||
uint *ap = (uint *)(void*)&fmt + 1;
|
uint *ap = (uint*)(void*)&fmt + 1;
|
||||||
|
|
||||||
for(i = 0; fmt[i]; i++){
|
for(i = 0; fmt[i]; i++){
|
||||||
c = fmt[i] & 0xff;
|
c = fmt[i] & 0xff;
|
||||||
|
|
36
proc.c
36
proc.c
|
@ -63,7 +63,7 @@ allocproc(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
|
||||||
for(i = 0; i < NPROC; i++){
|
for(i = 0; i < NPROC; i++){
|
||||||
p = &proc[i];
|
p = &proc[i];
|
||||||
if(p->state == UNUSED){
|
if(p->state == UNUSED){
|
||||||
|
@ -75,11 +75,11 @@ allocproc(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new process copying p as the parent.
|
// Create a new process copying p as the parent.
|
||||||
// Does not copy the kernel stack.
|
// Does not copy the kernel stack.
|
||||||
// Instead, sets up stack to return as if from system call.
|
// Instead, sets up stack to return as if from system call.
|
||||||
// Caller must arrange for process to run (set state to RUNNABLE).
|
// Caller must arrange for process to run (set state to RUNNABLE).
|
||||||
struct proc *
|
struct proc*
|
||||||
copyproc(struct proc* p)
|
copyproc(struct proc *p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct proc *np;
|
struct proc *np;
|
||||||
|
@ -115,7 +115,7 @@ copyproc(struct proc* p)
|
||||||
// Copy trapframe registers from parent.
|
// Copy trapframe registers from parent.
|
||||||
np->tf = (struct trapframe*)(np->kstack + KSTACKSIZE) - 1;
|
np->tf = (struct trapframe*)(np->kstack + KSTACKSIZE) - 1;
|
||||||
memmove(np->tf, p->tf, sizeof(*np->tf));
|
memmove(np->tf, p->tf, sizeof(*np->tf));
|
||||||
|
|
||||||
// Clear %eax so that fork system call returns 0 in child.
|
// Clear %eax so that fork system call returns 0 in child.
|
||||||
np->tf->eax = 0;
|
np->tf->eax = 0;
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ growproc(int n)
|
||||||
return cp->sz - n;
|
return cp->sz - n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-CPU process scheduler.
|
// Per-CPU process scheduler.
|
||||||
// Each CPU calls scheduler() after setting itself up.
|
// Each CPU calls scheduler() after setting itself up.
|
||||||
// Scheduler never returns. It loops, doing:
|
// Scheduler never returns. It loops, doing:
|
||||||
// - choose a process to run
|
// - choose a process to run
|
||||||
|
@ -176,8 +176,8 @@ scheduler(void)
|
||||||
p = &proc[i];
|
p = &proc[i];
|
||||||
if(p->state != RUNNABLE)
|
if(p->state != RUNNABLE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Switch to chosen process. It is the process's job
|
// Switch to chosen process. It is the process's job
|
||||||
// to release proc_table_lock and then reacquire it
|
// to release proc_table_lock and then reacquire it
|
||||||
// before jumping back to us.
|
// before jumping back to us.
|
||||||
|
|
||||||
|
@ -186,11 +186,11 @@ scheduler(void)
|
||||||
p->state = RUNNING;
|
p->state = RUNNING;
|
||||||
if(setjmp(&cpus[cpu()].jmpbuf) == 0)
|
if(setjmp(&cpus[cpu()].jmpbuf) == 0)
|
||||||
longjmp(&p->jmpbuf);
|
longjmp(&p->jmpbuf);
|
||||||
|
|
||||||
// Process is done running for now.
|
// Process is done running for now.
|
||||||
// It should have changed its p->state before coming back.
|
// It should have changed its p->state before coming back.
|
||||||
curproc[cpu()] = 0;
|
curproc[cpu()] = 0;
|
||||||
|
|
||||||
setupsegs(0);
|
setupsegs(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ forkret(void)
|
||||||
{
|
{
|
||||||
// Still holding proc_table_lock from scheduler.
|
// Still holding proc_table_lock from scheduler.
|
||||||
release(&proc_table_lock);
|
release(&proc_table_lock);
|
||||||
|
|
||||||
// Jump into assembly, never to return.
|
// Jump into assembly, never to return.
|
||||||
forkret1(curproc[cpu()]->tf);
|
forkret1(curproc[cpu()]->tf);
|
||||||
}
|
}
|
||||||
|
@ -246,9 +246,9 @@ sleep(void *chan, struct spinlock *lk)
|
||||||
if(lk == 0)
|
if(lk == 0)
|
||||||
panic("sleep without lk");
|
panic("sleep without lk");
|
||||||
|
|
||||||
// Must acquire proc_table_lock in order to
|
// Must acquire proc_table_lock in order to
|
||||||
// change p->state and then call sched.
|
// change p->state and then call sched.
|
||||||
// Once we hold proc_table_lock, we can be
|
// Once we hold proc_table_lock, we can be
|
||||||
// guaranteed that we won't miss any wakeup
|
// guaranteed that we won't miss any wakeup
|
||||||
// (wakeup runs with proc_table_lock locked),
|
// (wakeup runs with proc_table_lock locked),
|
||||||
// so it's okay to release lk.
|
// so it's okay to release lk.
|
||||||
|
@ -318,7 +318,7 @@ proc_kill(int pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit the current process. Does not return.
|
// Exit the current process. Does not return.
|
||||||
// Exited processes remain in the zombie state
|
// Exited processes remain in the zombie state
|
||||||
// until their parent calls wait() to find out they exited.
|
// until their parent calls wait() to find out they exited.
|
||||||
void
|
void
|
||||||
proc_exit(void)
|
proc_exit(void)
|
||||||
|
@ -334,7 +334,7 @@ proc_exit(void)
|
||||||
cp->fds[fd] = 0;
|
cp->fds[fd] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idecref(cp->cwd);
|
idecref(cp->cwd);
|
||||||
cp->cwd = 0;
|
cp->cwd = 0;
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ proc_exit(void)
|
||||||
for(p = proc; p < &proc[NPROC]; p++)
|
for(p = proc; p < &proc[NPROC]; p++)
|
||||||
if(p->ppid == cp->pid)
|
if(p->ppid == cp->pid)
|
||||||
p->ppid = 1;
|
p->ppid = 1;
|
||||||
|
|
||||||
// Jump into the scheduler, never to return.
|
// Jump into the scheduler, never to return.
|
||||||
cp->killed = 0;
|
cp->killed = 0;
|
||||||
cp->state = ZOMBIE;
|
cp->state = ZOMBIE;
|
||||||
|
@ -392,7 +392,7 @@ proc_wait(void)
|
||||||
release(&proc_table_lock);
|
release(&proc_table_lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for children to exit. (See wakeup1 call in proc_exit.)
|
// Wait for children to exit. (See wakeup1 call in proc_exit.)
|
||||||
sleep(cp, &proc_table_lock);
|
sleep(cp, &proc_table_lock);
|
||||||
}
|
}
|
||||||
|
|
2
rm.c
2
rm.c
|
@ -12,7 +12,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 1; i < argc; i++){
|
for(i = 1; i < argc; i++){
|
||||||
if (unlink(argv[i]) < 0) {
|
if(unlink(argv[i]) < 0) {
|
||||||
printf(2, "mkdir: %s failed to create\n", argv[i]);
|
printf(2, "mkdir: %s failed to create\n", argv[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
8
setjmp.S
8
setjmp.S
|
@ -1,7 +1,7 @@
|
||||||
.globl setjmp
|
.globl setjmp
|
||||||
setjmp:
|
setjmp:
|
||||||
movl 4(%esp), %eax
|
movl 4(%esp), %eax
|
||||||
|
|
||||||
movl %ebx, 0(%eax)
|
movl %ebx, 0(%eax)
|
||||||
movl %ecx, 4(%eax)
|
movl %ecx, 4(%eax)
|
||||||
movl %edx, 8(%eax)
|
movl %edx, 8(%eax)
|
||||||
|
@ -11,14 +11,14 @@ setjmp:
|
||||||
movl %ebp, 24(%eax)
|
movl %ebp, 24(%eax)
|
||||||
pushl 0(%esp) /* %eip */
|
pushl 0(%esp) /* %eip */
|
||||||
popl 28(%eax)
|
popl 28(%eax)
|
||||||
|
|
||||||
movl $0, %eax /* return value */
|
movl $0, %eax /* return value */
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.globl longjmp
|
.globl longjmp
|
||||||
longjmp:
|
longjmp:
|
||||||
movl 4(%esp), %eax
|
movl 4(%esp), %eax
|
||||||
|
|
||||||
movl 0(%eax), %ebx
|
movl 0(%eax), %ebx
|
||||||
movl 4(%eax), %ecx
|
movl 4(%eax), %ecx
|
||||||
movl 8(%eax), %edx
|
movl 8(%eax), %edx
|
||||||
|
@ -29,7 +29,7 @@ longjmp:
|
||||||
|
|
||||||
addl $4, %esp /* pop %eip into thin air */
|
addl $4, %esp /* pop %eip into thin air */
|
||||||
pushl 28(%eax) /* push new %eip */
|
pushl 28(%eax) /* push new %eip */
|
||||||
|
|
||||||
movl $1, %eax /* return value (appears to come from setjmp!) */
|
movl $1, %eax /* return value (appears to come from setjmp!) */
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
136
sh.c
136
sh.c
|
@ -25,7 +25,7 @@ struct cmd {
|
||||||
int argc;
|
int argc;
|
||||||
int token;
|
int token;
|
||||||
};
|
};
|
||||||
struct cmd cmdlist[MAXCMD];
|
struct cmd cmdlist[MAXCMD];
|
||||||
int nextcmd;
|
int nextcmd;
|
||||||
|
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
@ -43,15 +43,15 @@ main(void)
|
||||||
{
|
{
|
||||||
while(1){
|
while(1){
|
||||||
puts("$ ");
|
puts("$ ");
|
||||||
memset (buf, '\0', sizeof(buf));
|
memset(buf, '\0', sizeof(buf));
|
||||||
gets(buf, sizeof(buf));
|
gets(buf, sizeof(buf));
|
||||||
if (parse(buf) < 0)
|
if(parse(buf) < 0)
|
||||||
continue;
|
continue;
|
||||||
runcmd();
|
runcmd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
parse(char *s)
|
parse(char *s)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
|
@ -61,33 +61,33 @@ parse(char *s)
|
||||||
|
|
||||||
nextio = 0;
|
nextio = 0;
|
||||||
nextcmd = 0;
|
nextcmd = 0;
|
||||||
for (i = 0; i < MAXCMD; i++) {
|
for(i = 0; i < MAXCMD; i++) {
|
||||||
cmdlist[i].argc = 0;
|
cmdlist[i].argc = 0;
|
||||||
cmdlist[i].token = 0;
|
cmdlist[i].token = 0;
|
||||||
}
|
}
|
||||||
while (1) {
|
while(1) {
|
||||||
switch ((c = gettoken(0, &t))) {
|
switch((c = gettoken(0, &t))) {
|
||||||
|
|
||||||
case 'w': // Add an argument
|
case 'w': // Add an argument
|
||||||
if (cmdlist[nextcmd].argc >= MAXARGS) {
|
if(cmdlist[nextcmd].argc >= MAXARGS) {
|
||||||
printf(2, "too many arguments\n");
|
printf(2, "too many arguments\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cmdlist[nextcmd].argv[cmdlist[nextcmd].argc++] = t;
|
cmdlist[nextcmd].argv[cmdlist[nextcmd].argc++] = t;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<': // Input redirection
|
case '<': // Input redirection
|
||||||
// Grab the filename from the argument list
|
// Grab the filename from the argument list
|
||||||
if (gettoken(0, &t) != 'w') {
|
if(gettoken(0, &t) != 'w') {
|
||||||
printf(2, "syntax error: < not followed by word\n");
|
printf(2, "syntax error: < not followed by word\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
addio('<', t);
|
addio('<', t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>': // Output redirection
|
case '>': // Output redirection
|
||||||
// Grab the filename from the argument list
|
// Grab the filename from the argument list
|
||||||
if (gettoken(0, &t) != 'w') {
|
if(gettoken(0, &t) != 'w') {
|
||||||
printf(2, "syntax error: > not followed by word\n");
|
printf(2, "syntax error: > not followed by word\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -102,11 +102,11 @@ parse(char *s)
|
||||||
|
|
||||||
case 0: // String is complete
|
case 0: // String is complete
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf(2, "syntax error: bad return %d from gettoken", c);
|
printf(2, "syntax error: bad return %d from gettoken", c);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,90 +120,90 @@ runcmd(void)
|
||||||
|
|
||||||
// Return immediately if command line was empty.
|
// Return immediately if command line was empty.
|
||||||
if(cmdlist[0].argc == 0) {
|
if(cmdlist[0].argc == 0) {
|
||||||
if (debug)
|
if(debug)
|
||||||
printf(2, "EMPTY COMMAND\n");
|
printf(2, "EMPTY COMMAND\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 0; c <= nextcmd; c++) {
|
for(c = 0; c <= nextcmd; c++) {
|
||||||
// Clean up command line.
|
// Clean up command line.
|
||||||
// Read all commands from the filesystem: add an initial '/' to
|
// Read all commands from the filesystem: add an initial '/' to
|
||||||
// the command name.
|
// the command name.
|
||||||
// This essentially acts like 'PATH=/'.
|
// This essentially acts like 'PATH=/'.
|
||||||
if (cmdlist[c].argv[0][0] != '/') {
|
if(cmdlist[c].argv[0][0] != '/') {
|
||||||
cmdlist[c].argv0buf[0] = '/';
|
cmdlist[c].argv0buf[0] = '/';
|
||||||
strcpy(cmdlist[c].argv0buf + 1, cmdlist[c].argv[0]);
|
strcpy(cmdlist[c].argv0buf + 1, cmdlist[c].argv[0]);
|
||||||
cmdlist[c].argv[0] = cmdlist[c].argv0buf;
|
cmdlist[c].argv[0] = cmdlist[c].argv0buf;
|
||||||
}
|
}
|
||||||
cmdlist[c].argv[cmdlist[c].argc] = 0;
|
cmdlist[c].argv[cmdlist[c].argc] = 0;
|
||||||
|
|
||||||
// Print the command.
|
// Print the command.
|
||||||
if (debug) {
|
if(debug) {
|
||||||
printf(2, "[%d] SPAWN:", getpid());
|
printf(2, "[%d] SPAWN:", getpid());
|
||||||
for (i = 0; cmdlist[c].argv[i]; i++)
|
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++) {
|
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");
|
printf(2, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(cmdlist[c].argv[0], "/cd") == 0) {
|
if(strcmp(cmdlist[c].argv[0], "/cd") == 0) {
|
||||||
if (debug) printf (2, "/cd %s is build in\n", cmdlist[c].argv[1]);
|
if(debug) printf (2, "/cd %s is build in\n", cmdlist[c].argv[1]);
|
||||||
chdir(cmdlist[c].argv[1]);
|
chdir(cmdlist[c].argv[1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdlist[c].token == '|')
|
if(cmdlist[c].token == '|')
|
||||||
if (pipe(fdarray) < 0)
|
if(pipe(fdarray) < 0)
|
||||||
printf(2, "cmd %d pipe failed\n", c);
|
printf(2, "cmd %d pipe failed\n", c);
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == 0) {
|
if(pid == 0) {
|
||||||
if (cmdlist[c].token == '|') {
|
if(cmdlist[c].token == '|') {
|
||||||
if (close(1) < 0)
|
if(close(1) < 0)
|
||||||
printf(2, "close 1 failed\n");
|
printf(2, "close 1 failed\n");
|
||||||
if ((tfd = dup(fdarray[1])) < 0)
|
if((tfd = dup(fdarray[1])) < 0)
|
||||||
printf(2, "dup failed\n");
|
printf(2, "dup failed\n");
|
||||||
if (close(fdarray[0]) < 0)
|
if(close(fdarray[0]) < 0)
|
||||||
printf(2, "close fdarray[0] failed\n");
|
printf(2, "close fdarray[0] failed\n");
|
||||||
if (close(fdarray[1]) < 0)
|
if(close(fdarray[1]) < 0)
|
||||||
printf(2, "close fdarray[1] failed\n");
|
printf(2, "close fdarray[1] failed\n");
|
||||||
}
|
}
|
||||||
if (c > 0 && cmdlist[c-1].token == '|') {
|
if(c > 0 && cmdlist[c-1].token == '|') {
|
||||||
if (close(0) < 0)
|
if(close(0) < 0)
|
||||||
printf(2, "close 0 failed\n");
|
printf(2, "close 0 failed\n");
|
||||||
if ((tfd = dup(fdarray[0])) < 0)
|
if((tfd = dup(fdarray[0])) < 0)
|
||||||
printf(2, "dup failed\n");
|
printf(2, "dup failed\n");
|
||||||
if (close(fdarray[0]) < 0)
|
if(close(fdarray[0]) < 0)
|
||||||
printf(2, "close fdarray[0] failed\n");
|
printf(2, "close fdarray[0] failed\n");
|
||||||
if (close(fdarray[1]) < 0)
|
if(close(fdarray[1]) < 0)
|
||||||
printf(2, "close fdarray[1] failed\n");
|
printf(2, "close fdarray[1] failed\n");
|
||||||
}
|
}
|
||||||
if (ioredirection() < 0)
|
if(ioredirection() < 0)
|
||||||
exit();
|
exit();
|
||||||
if ((r = exec(cmdlist[c].argv0buf, (char**) cmdlist[c].argv)) < 0) {
|
if((r = exec(cmdlist[c].argv0buf, (char**) cmdlist[c].argv)) < 0) {
|
||||||
printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r);
|
printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
} else if (pid > 0) {
|
} else if(pid > 0) {
|
||||||
int p;
|
int p;
|
||||||
if (debug)
|
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 == '|') {
|
if(c > 0 && cmdlist[c-1].token == '|') {
|
||||||
close(fdarray[0]);
|
close(fdarray[0]);
|
||||||
close(fdarray[1]);
|
close(fdarray[1]);
|
||||||
}
|
}
|
||||||
if (cmdlist[c].token != '|') {
|
if(cmdlist[c].token != '|') {
|
||||||
if (debug)
|
if(debug)
|
||||||
printf(2, "[%d] WAIT for children\n", getpid());
|
printf(2, "[%d] WAIT for children\n", getpid());
|
||||||
do {
|
do {
|
||||||
p = wait();
|
p = wait();
|
||||||
if (debug)
|
if(debug)
|
||||||
printf(2, "[%d] WAIT child %d finished\n", getpid(), p);
|
printf(2, "[%d] WAIT child %d finished\n", getpid(), p);
|
||||||
} while (p > 0);
|
} while(p > 0);
|
||||||
if (debug)
|
if(debug)
|
||||||
printf(2, "[%d] wait finished\n", getpid());
|
printf(2, "[%d] wait finished\n", getpid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,26 +215,26 @@ ioredirection(void)
|
||||||
{
|
{
|
||||||
int i, fd;
|
int i, fd;
|
||||||
|
|
||||||
for (i = 0; i < nextio; i++) {
|
for(i = 0; i < nextio; i++) {
|
||||||
switch (iolist[i].token) {
|
switch(iolist[i].token) {
|
||||||
case '<':
|
case '<':
|
||||||
if (close(0) < 0)
|
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) {
|
if((fd = open(iolist[i].s, O_RDONLY)) < 0) {
|
||||||
printf(2, "failed to open %s for read: %d", iolist[i].s, fd);
|
printf(2, "failed to open %s for read: %d", iolist[i].s, fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (debug)
|
if(debug)
|
||||||
printf(2, "redirect 0 from %s\n", iolist[i].s);
|
printf(2, "redirect 0 from %s\n", iolist[i].s);
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
if (close(1) < 0)
|
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) {
|
if((fd = open(iolist[i].s, O_WRONLY|O_CREATE)) < 0) {
|
||||||
printf(2, "failed to open %s for write: %d", iolist[i].s, fd);
|
printf(2, "failed to open %s for write: %d", iolist[i].s, fd);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
if (debug)
|
if(debug)
|
||||||
printf(2, "redirect 1 to %s\n", iolist[i].s);
|
printf(2, "redirect 1 to %s\n", iolist[i].s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -245,11 +245,11 @@ ioredirection(void)
|
||||||
void
|
void
|
||||||
addio(int token, char *s)
|
addio(int token, char *s)
|
||||||
{
|
{
|
||||||
if (nextio >= MAXNODE) {
|
if(nextio >= MAXNODE) {
|
||||||
printf(2, "addio: ran out of nodes\n");
|
printf(2, "addio: ran out of nodes\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iolist[nextio].token = token;
|
iolist[nextio].token = token;
|
||||||
iolist[nextio].s = s;
|
iolist[nextio].s = s;
|
||||||
nextio++;
|
nextio++;
|
||||||
|
@ -267,9 +267,9 @@ int
|
||||||
gettoken(char *s, char **p1)
|
gettoken(char *s, char **p1)
|
||||||
{
|
{
|
||||||
static int c, nc;
|
static int c, nc;
|
||||||
static char* np1, *np2;
|
static char *np1, *np2;
|
||||||
|
|
||||||
if (s) {
|
if(s) {
|
||||||
nc = _gettoken(s, &np1, &np2);
|
nc = _gettoken(s, &np1, &np2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -299,39 +299,39 @@ _gettoken(char *s, char **p1, char **p2)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
if (s == 0) {
|
if(s == 0) {
|
||||||
if (debug > 1)
|
if(debug > 1)
|
||||||
printf(2, "GETTOKEN NULL\n");
|
printf(2, "GETTOKEN NULL\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug > 1)
|
if(debug > 1)
|
||||||
printf(2, "GETTOKEN: %s\n", s);
|
printf(2, "GETTOKEN: %s\n", s);
|
||||||
|
|
||||||
*p1 = 0;
|
*p1 = 0;
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
|
|
||||||
while (strchr(WHITESPACE, *s))
|
while(strchr(WHITESPACE, *s))
|
||||||
*s++ = 0;
|
*s++ = 0;
|
||||||
if (*s == 0) {
|
if(*s == 0) {
|
||||||
if (debug > 1)
|
if(debug > 1)
|
||||||
printf(2, "EOL\n");
|
printf(2, "EOL\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strchr(SYMBOLS, *s)) {
|
if(strchr(SYMBOLS, *s)) {
|
||||||
t = *s;
|
t = *s;
|
||||||
*p1 = s;
|
*p1 = s;
|
||||||
*s++ = 0;
|
*s++ = 0;
|
||||||
*p2 = s;
|
*p2 = s;
|
||||||
if (debug > 1)
|
if(debug > 1)
|
||||||
printf(2, "TOK %c\n", t);
|
printf(2, "TOK %c\n", t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
*p1 = s;
|
*p1 = s;
|
||||||
while (*s && !strchr(WHITESPACE SYMBOLS, *s))
|
while(*s && !strchr(WHITESPACE SYMBOLS, *s))
|
||||||
s++;
|
s++;
|
||||||
*p2 = s;
|
*p2 = s;
|
||||||
if (debug > 1) {
|
if(debug > 1) {
|
||||||
t = **p2;
|
t = **p2;
|
||||||
**p2 = 0;
|
**p2 = 0;
|
||||||
printf(2, "WORD: %s\n", *p1);
|
printf(2, "WORD: %s\n", *p1);
|
||||||
|
|
|
@ -29,7 +29,7 @@ getcallerpcs(void *v, uint pcs[])
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
acquire(struct spinlock * lock)
|
acquire(struct spinlock *lock)
|
||||||
{
|
{
|
||||||
if(holding(lock))
|
if(holding(lock))
|
||||||
panic("acquire");
|
panic("acquire");
|
||||||
|
@ -37,7 +37,7 @@ acquire(struct spinlock * lock)
|
||||||
if(cpus[cpu()].nlock == 0)
|
if(cpus[cpu()].nlock == 0)
|
||||||
cli();
|
cli();
|
||||||
cpus[cpu()].nlock++;
|
cpus[cpu()].nlock++;
|
||||||
|
|
||||||
while(cmpxchg(0, 1, &lock->locked) == 1)
|
while(cmpxchg(0, 1, &lock->locked) == 1)
|
||||||
;
|
;
|
||||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||||
|
@ -46,7 +46,7 @@ acquire(struct spinlock * lock)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
release(struct spinlock * lock)
|
release(struct spinlock *lock)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!holding(lock))
|
if(!holding(lock))
|
||||||
|
|
24
string.c
24
string.c
|
@ -1,10 +1,10 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
void *
|
void*
|
||||||
memset(void *dst, int c, uint n)
|
memset(void *dst, int c, uint n)
|
||||||
{
|
{
|
||||||
char *d = (char *) dst;
|
char *d = (char*) dst;
|
||||||
|
|
||||||
while(n-- > 0)
|
while(n-- > 0)
|
||||||
*d++ = c;
|
*d++ = c;
|
||||||
|
@ -15,11 +15,11 @@ memset(void *dst, int c, uint n)
|
||||||
int
|
int
|
||||||
memcmp(const void *v1, const void *v2, uint n)
|
memcmp(const void *v1, const void *v2, uint n)
|
||||||
{
|
{
|
||||||
const uchar *s1 = (const uchar *) v1;
|
const uchar *s1 = (const uchar*) v1;
|
||||||
const uchar *s2 = (const uchar *) v2;
|
const uchar *s2 = (const uchar*) v2;
|
||||||
|
|
||||||
while (n-- > 0) {
|
while(n-- > 0) {
|
||||||
if (*s1 != *s2)
|
if(*s1 != *s2)
|
||||||
return (int) *s1 - (int) *s2;
|
return (int) *s1 - (int) *s2;
|
||||||
s1++, s2++;
|
s1++, s2++;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ memcmp(const void *v1, const void *v2, uint n)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void*
|
||||||
memmove(void *dst, const void *src, uint n)
|
memmove(void *dst, const void *src, uint n)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
|
@ -35,13 +35,13 @@ memmove(void *dst, const void *src, uint n)
|
||||||
|
|
||||||
s = src;
|
s = src;
|
||||||
d = dst;
|
d = dst;
|
||||||
if (s < d && s + n > d) {
|
if(s < d && s + n > d) {
|
||||||
s += n;
|
s += n;
|
||||||
d += n;
|
d += n;
|
||||||
while (n-- > 0)
|
while(n-- > 0)
|
||||||
*--d = *--s;
|
*--d = *--s;
|
||||||
} else
|
} else
|
||||||
while (n-- > 0)
|
while(n-- > 0)
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
|
@ -50,9 +50,9 @@ memmove(void *dst, const void *src, uint n)
|
||||||
int
|
int
|
||||||
strncmp(const char *p, const char *q, uint n)
|
strncmp(const char *p, const char *q, uint n)
|
||||||
{
|
{
|
||||||
while (n > 0 && *p && *p == *q)
|
while(n > 0 && *p && *p == *q)
|
||||||
n--, p++, q++;
|
n--, p++, q++;
|
||||||
if (n == 0)
|
if(n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return (int) ((uchar) *p - (uchar) *q);
|
return (int) ((uchar) *p - (uchar) *q);
|
||||||
|
|
50
syscall.c
50
syscall.c
|
@ -41,7 +41,7 @@ fetchint(struct proc *p, uint addr, int *ip)
|
||||||
// Fetch byte from a user-supplied pointer.
|
// Fetch byte from a user-supplied pointer.
|
||||||
// Returns 0 on success, -1 if pointer is illegal.
|
// Returns 0 on success, -1 if pointer is illegal.
|
||||||
int
|
int
|
||||||
fetchbyte(struct proc *p, uint addr, char* c)
|
fetchbyte(struct proc *p, uint addr, char *c)
|
||||||
{
|
{
|
||||||
if(addr >= p->sz)
|
if(addr >= p->sz)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -262,10 +262,10 @@ sys_open(void)
|
||||||
|
|
||||||
iunlock(ip);
|
iunlock(ip);
|
||||||
fd->type = FD_FILE;
|
fd->type = FD_FILE;
|
||||||
if (arg1 & O_RDWR) {
|
if(arg1 & O_RDWR) {
|
||||||
fd->readable = 1;
|
fd->readable = 1;
|
||||||
fd->writeable = 1;
|
fd->writeable = 1;
|
||||||
} else if (arg1 & O_WRONLY) {
|
} else if(arg1 & O_WRONLY) {
|
||||||
fd->readable = 0;
|
fd->readable = 0;
|
||||||
fd->writeable = 1;
|
fd->writeable = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -287,7 +287,7 @@ sys_mknod(void)
|
||||||
uint arg0, arg1, arg2, arg3;
|
uint arg0, arg1, arg2, arg3;
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0 ||
|
if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0 ||
|
||||||
fetcharg(2, &arg2) < 0 || fetcharg(3, &arg3) < 0)
|
fetcharg(2, &arg2) < 0 || fetcharg(3, &arg3) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ sys_mknod(void)
|
||||||
if(l >= DIRSIZ)
|
if(l >= DIRSIZ)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nip = mknod (cp->mem + arg0, (short) arg1, (short) arg2, (short) arg3);
|
nip = mknod(cp->mem + arg0, (short) arg1, (short) arg2, (short) arg3);
|
||||||
if(nip)
|
if(nip)
|
||||||
iput(nip);
|
iput(nip);
|
||||||
return (nip == 0) ? -1 : 0;
|
return (nip == 0) ? -1 : 0;
|
||||||
|
@ -314,7 +314,7 @@ sys_mkdir(void)
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
char *last;
|
char *last;
|
||||||
|
|
||||||
if(fetcharg(0, &arg0) < 0)
|
if(fetcharg(0, &arg0) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if((l = checkstring(arg0)) < 0)
|
if((l = checkstring(arg0)) < 0)
|
||||||
|
@ -332,15 +332,15 @@ sys_mkdir(void)
|
||||||
|
|
||||||
dp->nlink += 1;
|
dp->nlink += 1;
|
||||||
iupdate(dp);
|
iupdate(dp);
|
||||||
|
|
||||||
memset (de.name, '\0', DIRSIZ);
|
memset(de.name, '\0', DIRSIZ);
|
||||||
de.name[0] = '.';
|
de.name[0] = '.';
|
||||||
de.inum = nip->inum;
|
de.inum = nip->inum;
|
||||||
writei (nip, (char *) &de, 0, sizeof(de));
|
writei(nip, (char*) &de, 0, sizeof(de));
|
||||||
|
|
||||||
de.inum = dp->inum;
|
de.inum = dp->inum;
|
||||||
de.name[1] = '.';
|
de.name[1] = '.';
|
||||||
writei (nip, (char *) &de, sizeof(de), sizeof(de));
|
writei(nip, (char*) &de, sizeof(de), sizeof(de));
|
||||||
|
|
||||||
iput(dp);
|
iput(dp);
|
||||||
iput(nip);
|
iput(nip);
|
||||||
|
@ -356,22 +356,22 @@ sys_chdir(void)
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
uint arg0;
|
uint arg0;
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
if(fetcharg(0, &arg0) < 0)
|
if(fetcharg(0, &arg0) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if((l = checkstring(arg0)) < 0)
|
if((l = checkstring(arg0)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0)) == 0)
|
if((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0)) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ip == cp->cwd) {
|
if(ip == cp->cwd) {
|
||||||
iput (ip);
|
iput(ip);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip->type != T_DIR) {
|
if(ip->type != T_DIR) {
|
||||||
iput(ip);
|
iput(ip);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -388,7 +388,7 @@ sys_unlink(void)
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
uint arg0;
|
uint arg0;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(fetcharg(0, &arg0) < 0)
|
if(fetcharg(0, &arg0) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(checkstring(arg0) < 0)
|
if(checkstring(arg0) < 0)
|
||||||
|
@ -403,7 +403,7 @@ sys_fstat(void)
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
uint fd, addr;
|
uint fd, addr;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(fetcharg(0, &fd) < 0)
|
if(fetcharg(0, &fd) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(fetcharg(1, &addr) < 0)
|
if(fetcharg(1, &addr) < 0)
|
||||||
|
@ -414,7 +414,7 @@ sys_fstat(void)
|
||||||
return -1;
|
return -1;
|
||||||
if(addr + sizeof(struct stat) > cp->sz)
|
if(addr + sizeof(struct stat) > cp->sz)
|
||||||
return -1;
|
return -1;
|
||||||
r = fd_stat (cp->fds[fd], (struct stat *)(cp->mem + addr));
|
r = fd_stat(cp->fds[fd], (struct stat*)(cp->mem + addr));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,14 +423,14 @@ sys_dup(void)
|
||||||
{
|
{
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
uint fd, ufd1;
|
uint fd, ufd1;
|
||||||
|
|
||||||
if(fetcharg(0, &fd) < 0)
|
if(fetcharg(0, &fd) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(fd < 0 || fd >= NOFILE)
|
if(fd < 0 || fd >= NOFILE)
|
||||||
return -1;
|
return -1;
|
||||||
if(cp->fds[fd] == 0)
|
if(cp->fds[fd] == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if ((ufd1 = fd_ualloc()) < 0)
|
if((ufd1 = fd_ualloc()) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
cp->fds[ufd1] = cp->fds[fd];
|
cp->fds[ufd1] = cp->fds[fd];
|
||||||
fd_incref(cp->fds[ufd1]);
|
fd_incref(cp->fds[ufd1]);
|
||||||
|
@ -443,7 +443,7 @@ sys_link(void)
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
uint name1, name2;
|
uint name1, name2;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(fetcharg(0, &name1) < 0 || checkstring(name1) < 0)
|
if(fetcharg(0, &name1) < 0 || checkstring(name1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(fetcharg(1, &name2) < 0 || checkstring(name2) < 0)
|
if(fetcharg(1, &name2) < 0 || checkstring(name2) < 0)
|
||||||
|
@ -471,7 +471,7 @@ sys_sbrk(void)
|
||||||
return -1;
|
return -1;
|
||||||
if((addr = growproc(n)) == 0xffffffff)
|
if((addr = growproc(n)) == 0xffffffff)
|
||||||
return -1;
|
return -1;
|
||||||
setupsegs(cp);
|
setupsegs(cp);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ sys_exec(void)
|
||||||
goto bad;
|
goto bad;
|
||||||
sz += ph.memsz;
|
sz += ph.memsz;
|
||||||
}
|
}
|
||||||
|
|
||||||
sz += 4096 - (sz % 4096);
|
sz += 4096 - (sz % 4096);
|
||||||
sz += 4096;
|
sz += 4096;
|
||||||
|
|
||||||
|
|
4
trap.c
4
trap.c
|
@ -57,7 +57,7 @@ trap(struct trapframe *tf)
|
||||||
// out to its regular system call return.)
|
// out to its regular system call return.)
|
||||||
if((tf->cs&3) == 3 && cp->killed)
|
if((tf->cs&3) == 3 && cp->killed)
|
||||||
proc_exit();
|
proc_exit();
|
||||||
|
|
||||||
// Force process to give up CPU and let others run.
|
// Force process to give up CPU and let others run.
|
||||||
if(cp->state == RUNNING)
|
if(cp->state == RUNNING)
|
||||||
yield();
|
yield();
|
||||||
|
@ -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---terminate process\n",
|
||||||
curproc[cpu()]->pid, v, cpu(), tf->eip);
|
curproc[cpu()]->pid, v, cpu(), tf->eip);
|
||||||
proc_exit();
|
proc_exit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ alltraps:
|
||||||
call trap # and call trap()
|
call trap # and call trap()
|
||||||
addl $4, %esp
|
addl $4, %esp
|
||||||
# return falls through to trapret...
|
# return falls through to trapret...
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* a forked process RETs here
|
* a forked process RETs here
|
||||||
* expects ESP to point to a Trapframe
|
* expects ESP to point to a Trapframe
|
||||||
|
@ -32,7 +32,7 @@ trapret:
|
||||||
forkret1:
|
forkret1:
|
||||||
movl 4(%esp), %esp
|
movl 4(%esp), %esp
|
||||||
jmp trapret
|
jmp trapret
|
||||||
|
|
||||||
.globl acpu
|
.globl acpu
|
||||||
acpu:
|
acpu:
|
||||||
.long 0
|
.long 0
|
||||||
|
|
2
traps.h
2
traps.h
|
@ -6,7 +6,7 @@
|
||||||
#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 generated by recent processors)
|
||||||
#define T_TSS 10 // invalid task switch segment
|
#define T_TSS 10 // invalid task switch segment
|
||||||
|
|
16
ulib.c
16
ulib.c
|
@ -13,7 +13,7 @@ char*
|
||||||
strcpy(char *s, char *t)
|
strcpy(char *s, char *t)
|
||||||
{
|
{
|
||||||
char *os;
|
char *os;
|
||||||
|
|
||||||
os = s;
|
os = s;
|
||||||
while((*s++ = *t++) != 0)
|
while((*s++ = *t++) != 0)
|
||||||
;
|
;
|
||||||
|
@ -23,7 +23,7 @@ strcpy(char *s, char *t)
|
||||||
int
|
int
|
||||||
strcmp(const char *p, const char *q)
|
strcmp(const char *p, const char *q)
|
||||||
{
|
{
|
||||||
while (*p && *p == *q)
|
while(*p && *p == *q)
|
||||||
p++, q++;
|
p++, q++;
|
||||||
return (int) ((unsigned char) *p - (unsigned char) *q);
|
return (int) ((unsigned char) *p - (unsigned char) *q);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ strlen(char *s)
|
||||||
void*
|
void*
|
||||||
memset(void *dst, int c, unsigned int n)
|
memset(void *dst, int c, unsigned int n)
|
||||||
{
|
{
|
||||||
char *d = (char *) dst;
|
char *d = (char*) dst;
|
||||||
|
|
||||||
while(n-- > 0)
|
while(n-- > 0)
|
||||||
*d++ = c;
|
*d++ = c;
|
||||||
|
@ -51,9 +51,9 @@ memset(void *dst, int c, unsigned int n)
|
||||||
char*
|
char*
|
||||||
strchr(const char *s, char c)
|
strchr(const char *s, char c)
|
||||||
{
|
{
|
||||||
for (; *s; s++)
|
for(; *s; s++)
|
||||||
if (*s == c)
|
if(*s == c)
|
||||||
return (char *) s;
|
return (char*) s;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ gets(char *buf, int max)
|
||||||
{
|
{
|
||||||
int i = 0, cc;
|
int i = 0, cc;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while(i+1 < max){
|
while(i+1 < max){
|
||||||
cc = read(0, &c, 1);
|
cc = read(0, &c, 1);
|
||||||
if(cc < 1)
|
if(cc < 1)
|
||||||
|
@ -82,7 +82,7 @@ stat(char *n, struct stat *st)
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
fd = open(n, O_RDONLY);
|
fd = open(n, O_RDONLY);
|
||||||
if (fd < 0) return -1;
|
if(fd < 0) return -1;
|
||||||
r = fstat(fd, st);
|
r = fstat(fd, st);
|
||||||
close(fd);
|
close(fd);
|
||||||
return r;
|
return r;
|
||||||
|
|
40
umalloc.c
40
umalloc.c
|
@ -3,7 +3,7 @@
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
|
|
||||||
// Memory allocator by Kernighan and Ritchie, The C programming Language,
|
// Memory allocator by Kernighan and Ritchie, The C programming Language,
|
||||||
// 2nd ed. Section 8.7.
|
// 2nd ed. Section 8.7.
|
||||||
|
|
||||||
typedef long Align;
|
typedef long Align;
|
||||||
|
@ -26,16 +26,16 @@ free(void *ap)
|
||||||
{
|
{
|
||||||
Header *bp, *p;
|
Header *bp, *p;
|
||||||
|
|
||||||
bp = (Header *) ap - 1;
|
bp = (Header*) ap - 1;
|
||||||
for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
|
for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
|
||||||
if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
|
if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))
|
||||||
break;
|
break;
|
||||||
if (bp + bp->s.size == p->s.ptr) {
|
if(bp + bp->s.size == p->s.ptr) {
|
||||||
bp->s.size += p->s.ptr->s.size;
|
bp->s.size += p->s.ptr->s.size;
|
||||||
bp->s.ptr = p->s.ptr->s.ptr;
|
bp->s.ptr = p->s.ptr->s.ptr;
|
||||||
} else
|
} else
|
||||||
bp->s.ptr = p->s.ptr;
|
bp->s.ptr = p->s.ptr;
|
||||||
if (p + p->s.size == bp) {
|
if(p + p->s.size == bp) {
|
||||||
p->s.size += bp->s.size;
|
p->s.size += bp->s.size;
|
||||||
p->s.ptr = bp->s.ptr;
|
p->s.ptr = bp->s.ptr;
|
||||||
} else
|
} else
|
||||||
|
@ -43,37 +43,37 @@ free(void *ap)
|
||||||
freep = p;
|
freep = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Header *
|
static Header*
|
||||||
morecore(uint nu)
|
morecore(uint nu)
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
Header *up;
|
Header *up;
|
||||||
|
|
||||||
if (nu < PAGE)
|
if(nu < PAGE)
|
||||||
nu = PAGE;
|
nu = PAGE;
|
||||||
cp = sbrk(nu * sizeof(Header));
|
cp = sbrk(nu * sizeof(Header));
|
||||||
if (cp == (char *) -1)
|
if(cp == (char*) -1)
|
||||||
return 0;
|
return 0;
|
||||||
up = (Header *) cp;
|
up = (Header*) cp;
|
||||||
up->s.size = nu;
|
up->s.size = nu;
|
||||||
free((void *)(up + 1));
|
free((void*)(up + 1));
|
||||||
return freep;
|
return freep;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void*
|
||||||
malloc(uint nbytes)
|
malloc(uint nbytes)
|
||||||
{
|
{
|
||||||
Header *p, *prevp;
|
Header *p, *prevp;
|
||||||
uint nunits;
|
uint nunits;
|
||||||
|
|
||||||
nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
|
nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
|
||||||
if ((prevp = freep) == 0) {
|
if((prevp = freep) == 0) {
|
||||||
base.s.ptr = freep = prevp = &base;
|
base.s.ptr = freep = prevp = &base;
|
||||||
base.s.size = 0;
|
base.s.size = 0;
|
||||||
}
|
}
|
||||||
for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
|
for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
|
||||||
if (p->s.size >= nunits) {
|
if(p->s.size >= nunits) {
|
||||||
if (p->s.size == nunits)
|
if(p->s.size == nunits)
|
||||||
prevp->s.ptr = p->s.ptr;
|
prevp->s.ptr = p->s.ptr;
|
||||||
else {
|
else {
|
||||||
p->s.size -= nunits;
|
p->s.size -= nunits;
|
||||||
|
@ -81,10 +81,10 @@ malloc(uint nbytes)
|
||||||
p->s.size = nunits;
|
p->s.size = nunits;
|
||||||
}
|
}
|
||||||
freep = prevp;
|
freep = prevp;
|
||||||
return (void *) (p + 1);
|
return (void*) (p + 1);
|
||||||
}
|
}
|
||||||
if (p == freep)
|
if(p == freep)
|
||||||
if ((p = morecore(nunits)) == 0)
|
if((p = morecore(nunits)) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
user.h
36
user.h
|
@ -7,27 +7,27 @@ int write(int, void*, int);
|
||||||
int read(int, void*, int);
|
int read(int, void*, int);
|
||||||
int close(int);
|
int close(int);
|
||||||
int kill(int);
|
int kill(int);
|
||||||
int exec(char *, char **);
|
int exec(char*, char**);
|
||||||
int open(char *, int);
|
int open(char*, int);
|
||||||
int mknod (char*,short,short,short);
|
int mknod(char*, short, short, short);
|
||||||
int unlink (char*);
|
int unlink(char*);
|
||||||
int fstat (int fd, struct stat *stat);
|
int fstat(int fd, struct stat*);
|
||||||
int link(char *, char *);
|
int link(char*, char*);
|
||||||
int mkdir(char *);
|
int mkdir(char*);
|
||||||
int chdir(char *);
|
int chdir(char*);
|
||||||
int dup(int);
|
int dup(int);
|
||||||
int getpid();
|
int getpid();
|
||||||
char *sbrk(int);
|
char* sbrk(int);
|
||||||
|
|
||||||
// ulib.c
|
// ulib.c
|
||||||
int stat(char *, struct stat *stat);
|
int stat(char*, struct stat*);
|
||||||
int puts(char*);
|
int puts(char*);
|
||||||
char* strcpy(char*, char*);
|
char* strcpy(char*, char*);
|
||||||
char *strchr(const char *s, char c);
|
char* strchr(const char*, char c);
|
||||||
int strcmp(const char *p, const char *q);
|
int strcmp(const char*, const char*);
|
||||||
void printf(int fd, char *fmt, ...);
|
void printf(int, char*, ...);
|
||||||
char *gets(char *, int max);
|
char* gets(char*, int max);
|
||||||
unsigned int strlen(char *);
|
unsigned int strlen(char*);
|
||||||
void * memset(void *dst, int c, unsigned int n);
|
void* memset(void*, int, unsigned int);
|
||||||
void *malloc(uint);
|
void* malloc(uint);
|
||||||
void free(void *);
|
void free(void*);
|
||||||
|
|
54
userfs.c
54
userfs.c
|
@ -34,7 +34,7 @@ opentest(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
writetest(void)
|
writetest(void)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -47,12 +47,12 @@ writetest(void)
|
||||||
printf(stdout, "error: creat small failed!\n");
|
printf(stdout, "error: creat small failed!\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
for (i = 0; i < 100; i++) {
|
for(i = 0; i < 100; i++) {
|
||||||
if (write (fd, "aaaaaaaaaa", 10) != 10) {
|
if(write(fd, "aaaaaaaaaa", 10) != 10) {
|
||||||
printf(stdout, "error: write aa %d new file failed\n", i);
|
printf(stdout, "error: write aa %d new file failed\n", i);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
if (write (fd, "bbbbbbbbbb", 10) != 10) {
|
if(write(fd, "bbbbbbbbbb", 10) != 10) {
|
||||||
printf(stdout, "error: write bb %d new file failed\n", i);
|
printf(stdout, "error: write bb %d new file failed\n", i);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ writetest(void)
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
i = read(fd, buf, 2000);
|
i = read(fd, buf, 2000);
|
||||||
if (i == 2000) {
|
if(i == 2000) {
|
||||||
printf(stdout, "read succeeded\n");
|
printf(stdout, "read succeeded\n");
|
||||||
} else {
|
} else {
|
||||||
printf(stdout, "read failed\n");
|
printf(stdout, "read failed\n");
|
||||||
|
@ -75,13 +75,13 @@ writetest(void)
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (unlink("small") < 0) {
|
if(unlink("small") < 0) {
|
||||||
printf(stdout, "unlink small failed\n");
|
printf(stdout, "unlink small failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
writetest1(void)
|
writetest1(void)
|
||||||
{
|
{
|
||||||
int i, fd, n;
|
int i, fd, n;
|
||||||
|
@ -94,9 +94,9 @@ writetest1(void)
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAXFILE; i++) {
|
for(i = 0; i < MAXFILE; i++) {
|
||||||
((int *) buf)[0] = i;
|
((int*) buf)[0] = i;
|
||||||
if (write (fd, buf, 512) != 512) {
|
if(write(fd, buf, 512) != 512) {
|
||||||
printf(stdout, "error: write big file failed\n", i);
|
printf(stdout, "error: write big file failed\n", i);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
@ -111,26 +111,26 @@ writetest1(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
while (1) {
|
while(1) {
|
||||||
i = read(fd, buf, 512);
|
i = read(fd, buf, 512);
|
||||||
if (i == 0) {
|
if(i == 0) {
|
||||||
if (n == MAXFILE - 1) {
|
if(n == MAXFILE - 1) {
|
||||||
printf(stdout, "read only %d blocks from big", n);
|
printf(stdout, "read only %d blocks from big", n);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (i != 512) {
|
} else if(i != 512) {
|
||||||
printf(stdout, "read failed %d\n", i);
|
printf(stdout, "read failed %d\n", i);
|
||||||
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++;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
if (unlink("big") < 0) {
|
if(unlink("big") < 0) {
|
||||||
printf(stdout, "unlink big failed\n");
|
printf(stdout, "unlink big failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
@ -145,14 +145,14 @@ createtest(void)
|
||||||
|
|
||||||
name[0] = 'a';
|
name[0] = 'a';
|
||||||
name[2] = '\0';
|
name[2] = '\0';
|
||||||
for (i = 0; i < 52; i++) {
|
for(i = 0; i < 52; i++) {
|
||||||
name[1] = '0' + i;
|
name[1] = '0' + i;
|
||||||
fd = open(name, O_CREATE|O_RDWR);
|
fd = open(name, O_CREATE|O_RDWR);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
name[0] = 'a';
|
name[0] = 'a';
|
||||||
name[2] = '\0';
|
name[2] = '\0';
|
||||||
for (i = 0; i < 52; i++) {
|
for(i = 0; i < 52; i++) {
|
||||||
name[1] = '0' + i;
|
name[1] = '0' + i;
|
||||||
unlink(name);
|
unlink(name);
|
||||||
}
|
}
|
||||||
|
@ -162,22 +162,22 @@ void dirtest(void)
|
||||||
{
|
{
|
||||||
printf(stdout, "mkdir\n");
|
printf(stdout, "mkdir\n");
|
||||||
|
|
||||||
if (mkdir("dir0") < 0) {
|
if(mkdir("dir0") < 0) {
|
||||||
printf(stdout, "mkdir failed\n");
|
printf(stdout, "mkdir failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chdir("dir0") < 0) {
|
if(chdir("dir0") < 0) {
|
||||||
printf(stdout, "chdir dir0 failed\n");
|
printf(stdout, "chdir dir0 failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chdir("..") < 0) {
|
if(chdir("..") < 0) {
|
||||||
printf(stdout, "chdir .. failed\n");
|
printf(stdout, "chdir .. failed\n");
|
||||||
exit ();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlink("dir0") < 0) {
|
if(unlink("dir0") < 0) {
|
||||||
printf(stdout, "unlink dir0 failed\n");
|
printf(stdout, "unlink dir0 failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
@ -186,11 +186,11 @@ void dirtest(void)
|
||||||
void
|
void
|
||||||
exectest(void)
|
exectest(void)
|
||||||
{
|
{
|
||||||
if (exec("echo", echo_args) < 0) {
|
if(exec("echo", echo_args) < 0) {
|
||||||
printf(stdout, "exec echo failed\n");
|
printf(stdout, "exec echo failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
if (exec("cat", cat_args) < 0) {
|
if(exec("cat", cat_args) < 0) {
|
||||||
printf(stdout, "exec cat failed\n");
|
printf(stdout, "exec cat failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
12
usertests.c
12
usertests.c
|
@ -67,7 +67,7 @@ preempt(void)
|
||||||
if(pid1 == 0)
|
if(pid1 == 0)
|
||||||
for(;;)
|
for(;;)
|
||||||
;
|
;
|
||||||
|
|
||||||
pid2 = fork();
|
pid2 = fork();
|
||||||
if(pid2 == 0)
|
if(pid2 == 0)
|
||||||
for(;;)
|
for(;;)
|
||||||
|
@ -131,17 +131,17 @@ mem(void)
|
||||||
|
|
||||||
if((pid = fork()) == 0){
|
if((pid = fork()) == 0){
|
||||||
m1 = 0;
|
m1 = 0;
|
||||||
while ((m2 = malloc(10001)) != 0) {
|
while((m2 = malloc(10001)) != 0) {
|
||||||
*(char **) m2 = m1;
|
*(char**) m2 = m1;
|
||||||
m1 = m2;
|
m1 = m2;
|
||||||
}
|
}
|
||||||
while (m1) {
|
while(m1) {
|
||||||
m2 = *(char **)m1;
|
m2 = *(char**)m1;
|
||||||
free(m1);
|
free(m1);
|
||||||
m1 = m2;
|
m1 = m2;
|
||||||
}
|
}
|
||||||
m1 = malloc(1024*20);
|
m1 = malloc(1024*20);
|
||||||
if (m1 == 0) {
|
if(m1 == 0) {
|
||||||
puts("couldn't allocate mem?!!\n");
|
puts("couldn't allocate mem?!!\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
2
usys.S
2
usys.S
|
@ -6,7 +6,7 @@
|
||||||
name: \
|
name: \
|
||||||
movl $SYS_ ## name, %eax; \
|
movl $SYS_ ## name, %eax; \
|
||||||
int $T_SYSCALL; \
|
int $T_SYSCALL; \
|
||||||
ret
|
ret
|
||||||
|
|
||||||
STUB(fork)
|
STUB(fork)
|
||||||
STUB(exit)
|
STUB(exit)
|
||||||
|
|
14
x86.h
14
x86.h
|
@ -42,7 +42,7 @@ static __inline void
|
||||||
lgdt(struct segdesc *p, int size)
|
lgdt(struct segdesc *p, int size)
|
||||||
{
|
{
|
||||||
volatile ushort pd[3];
|
volatile ushort pd[3];
|
||||||
|
|
||||||
pd[0] = size-1;
|
pd[0] = size-1;
|
||||||
pd[1] = (uint)p;
|
pd[1] = (uint)p;
|
||||||
pd[2] = (uint)p >> 16;
|
pd[2] = (uint)p >> 16;
|
||||||
|
@ -56,11 +56,11 @@ static __inline void
|
||||||
lidt(struct gatedesc *p, int size)
|
lidt(struct gatedesc *p, int size)
|
||||||
{
|
{
|
||||||
volatile ushort pd[3];
|
volatile ushort pd[3];
|
||||||
|
|
||||||
pd[0] = size-1;
|
pd[0] = size-1;
|
||||||
pd[1] = (uint)p;
|
pd[1] = (uint)p;
|
||||||
pd[2] = (uint)p >> 16;
|
pd[2] = (uint)p >> 16;
|
||||||
|
|
||||||
asm volatile("lidt (%0)" : : "g" (pd));
|
asm volatile("lidt (%0)" : : "g" (pd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,13 +91,13 @@ cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
|
||||||
asm volatile("cpuid" :
|
asm volatile("cpuid" :
|
||||||
"=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) :
|
"=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) :
|
||||||
"a" (info));
|
"a" (info));
|
||||||
if (eaxp)
|
if(eaxp)
|
||||||
*eaxp = eax;
|
*eaxp = eax;
|
||||||
if (ebxp)
|
if(ebxp)
|
||||||
*ebxp = ebx;
|
*ebxp = ebx;
|
||||||
if (ecxp)
|
if(ecxp)
|
||||||
*ecxp = ecx;
|
*ecxp = ecx;
|
||||||
if (edxp)
|
if(edxp)
|
||||||
*edxp = edx;
|
*edxp = edx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue