Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
a650c606
提交
a650c606
9月 06, 2006
创建
作者:
rsc
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
spacing fixes: no tabs, 2-space indents (for rtm)
上级
45854caa
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
33 个修改的文件
包含
798 行增加
和
790 行删除
+798
-790
asm.h
asm.h
+14
-13
bootasm.S
bootasm.S
+73
-66
bootmain.c
bootmain.c
+56
-56
bootother.S
bootother.S
+50
-49
cat.c
cat.c
+4
-4
console.c
console.c
+87
-87
elf.h
elf.h
+23
-23
fs.c
fs.c
+13
-13
ide.c
ide.c
+5
-4
ioapic.c
ioapic.c
+3
-3
ioapic.h
ioapic.h
+69
-69
ls.c
ls.c
+9
-9
main.c
main.c
+1
-1
mkfs.c
mkfs.c
+10
-10
mmu.h
mmu.h
+0
-0
mp.c
mp.c
+29
-29
mp.h
mp.h
+85
-85
picirq.c
picirq.c
+9
-9
printf.c
printf.c
+2
-2
setjmp.S
setjmp.S
+28
-30
sh.c
sh.c
+62
-62
sign.pl
sign.pl
+2
-2
spinlock.c
spinlock.c
+2
-2
string.c
string.c
+7
-7
trap.c
trap.c
+1
-1
trapasm.S
trapasm.S
+27
-27
traps.h
traps.h
+24
-24
ulib.c
ulib.c
+16
-16
umalloc.c
umalloc.c
+5
-5
userfs.c
userfs.c
+2
-2
usys.S
usys.S
+5
-5
vectors.pl
vectors.pl
+4
-4
x86.h
x86.h
+71
-71
没有找到文件。
asm.h
浏览文件 @
a650c606
...
...
@@ -2,17 +2,18 @@
// macros to create x86 segments from assembler
//
#define SEG_NULLASM \
.word 0, 0; \
.byte 0, 0, 0, 0
#define SEG_ASM(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
#define SEG_NULLASM \
.word 0, 0; \
.byte 0, 0, 0, 0
#define STA_X 0x8 // Executable segment
#define STA_E 0x4 // Expand down (non-executable segments)
#define STA_C 0x4 // Conforming code segment (executable only)
#define STA_W 0x2 // Writeable (non-executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed
#define SEG_ASM(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
#define STA_X 0x8 // Executable segment
#define STA_E 0x4 // Expand down (non-executable segments)
#define STA_C 0x4 // Conforming code segment (executable only)
#define STA_W 0x2 // Writeable (non-executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed
bootasm.S
浏览文件 @
a650c606
#include "asm.h"
.set PROT_MODE_CSEG,0x8
# code segment selector
.set PROT_MODE_CSEG,0x8
# code segment selector
.set PROT_MODE_DSEG,0x10 # data segment selector
.set CR0_PE_ON,0x1
# protected mode enable flag
.set CR0_PE_ON,0x1
# protected mode enable flag
###################################################################################
# ENTRY POINT
# ENTRY POINT
# This code should be stored in the first sector of the hard disk.
# After the BIOS initializes the hardware on startup or system reset,
# it loads this code at physical address 0x7c00 - 0x7d00 (512 bytes).
# Then the BIOS jumps to the beginning of it, address 0x7c00,
# while running in 16-bit real-mode (8086 compatibility mode).
# The Code Segment register (CS) is initially zero on entry.
#
#
# This code switches into 32-bit protected mode so that all of
# memory can accessed, then calls into C.
###################################################################################
.globl start # Entry point
start: .code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
.globl start # Entry point
start:
.code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax
# Segment number zero
movw %ax,%ds
# -> Data Segment
movw %ax,%es
# -> Extra Segment
movw %ax,%ss
# -> Stack Segment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax
# Segment number zero
movw %ax,%ds
# -> Data Segment
movw %ax,%es
# -> Extra Segment
movw %ax,%ss
# -> Stack Segment
# Set up the stack pointer, growing downward from 0x7c00.
movw $start,%sp
# Stack Pointer
# Set up the stack pointer, growing downward from 0x7c00.
movw $start,%sp
# Stack Pointer
#### Enable A20:
#### For fascinating historical reasons (related to the fact that
#### the earliest 8086-based PCs could only address 1MB of physical memory
...
...
@@ -38,59 +39,65 @@ start: .code16 # This runs in real mode
#### physical address line 20 is tied to low when the machine boots.
#### Obviously this a bit of a drag for us, especially when trying to
#### address memory above 1MB. This code undoes this.
seta20.1: inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.1 # Yes
movb $0xd1,%al # Command: Write
outb %al,$0x64 # output port
seta20.2: inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.2 # Yes
movb $0xdf,%al # Enable
outb %al,$0x60 # A20
seta20.1:
inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.1 # Yes
movb $0xd1,%al # Command: Write
outb %al,$0x64 # output port
#### Switch from real to protected mode
seta20.2:
inb $0x64,%al # Get status
testb $0x2,%al # Busy?
jnz seta20.2 # Yes
movb $0xdf,%al # Enable
outb %al,$0x60 # A20
#### Switch from real to protected mode
#### The descriptors in our GDT allow all physical memory to be accessed.
#### Furthermore, the descriptors have base addresses of 0, so that the
#### segment translation is a NOP, ie. virtual addresses are identical to
#### their physical addresses. With this setup, immediately after
#### enabling protected mode it will still appear to this code
#### that it is running directly on physical memory with no translation.
#### This initial NOP-translation setup is required by the processor
#### to ensure that the transition to protected mode occurs smoothly.
real_to_prot: cli # Mandatory since we dont set up an IDT
lgdt gdtdesc # load GDT -- mandatory in protected mode
movl %cr0, %eax # turn on protected mode
orl $CR0_PE_ON, %eax #
movl %eax, %cr0 #
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp $PROT_MODE_CSEG, $protcseg
#### enabling protected mode it will still appear to this code
#### that it is running directly on physical memory with no translation.
#### This initial NOP-translation setup is required by the processor
#### to ensure that the transition to protected mode occurs smoothly.
real_to_prot:
cli # Mandatory since we dont set up an IDT
lgdt gdtdesc # load GDT -- mandatory in protected mode
movl %cr0, %eax # turn on protected mode
orl $CR0_PE_ON, %eax #
movl %eax, %cr0 #
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp $PROT_MODE_CSEG, $protcseg
#### we are in 32-bit protected mode (hence the .code32)
.code32
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
call cmain # finish the boot load from C.
# cmain() should not return
spin: jmp spin # ..but in case it does, spin
.p2align 2 # force 4 byte alignment
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
call cmain # finish the boot load from C.
# cmain() should not return
spin:
jmp spin # ..but in case it does, spin
.p2align 2 # force 4 byte alignment
gdt:
SEG_NULLASM
# null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
# code seg
SEG_ASM(STA_W, 0x0, 0xffffffff)
# data seg
SEG_NULLASM
# null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
# code seg
SEG_ASM(STA_W, 0x0, 0xffffffff)
# data seg
gdtdesc:
.word 0x17
# sizeof(gdt) - 1
.long gdt
# address gdt
.word 0x17
# sizeof(gdt) - 1
.long gdt
# address gdt
bootmain.c
浏览文件 @
a650c606
...
...
@@ -11,10 +11,10 @@
* be stored in the first sector of the disk.
*
* * The 2nd sector onward holds the kernel image.
*
*
* * The kernel image must be in ELF format.
*
* BOOT UP STEPS
* BOOT UP STEPS
* * when the CPU boots it loads the BIOS into memory and executes it
*
* * the BIOS intializes devices, sets of the interrupt routines, and
...
...
@@ -30,8 +30,8 @@
* * cmain() in this file takes over, reads in the kernel and jumps to it.
**********************************************************************/
#define SECTSIZE
512
#define ELFHDR
((struct elfhdr *) 0x10000) // scratch space
#define SECTSIZE
512
#define ELFHDR
((struct elfhdr *) 0x10000) // scratch space
void
readsect
(
void
*
,
uint
);
void
readseg
(
uint
,
uint
,
uint
);
...
...
@@ -39,30 +39,30 @@ void readseg(uint, uint, uint);
void
cmain
(
void
)
{
struct
proghdr
*
ph
,
*
eph
;
struct
proghdr
*
ph
,
*
eph
;
// read 1st page off disk
readseg
((
uint
)
ELFHDR
,
SECTSIZE
*
8
,
0
);
// read 1st page off disk
readseg
((
uint
)
ELFHDR
,
SECTSIZE
*
8
,
0
);
// is this a valid ELF?
if
(
ELFHDR
->
magic
!=
ELF_MAGIC
)
goto
bad
;
// is this a valid ELF?
if
(
ELFHDR
->
magic
!=
ELF_MAGIC
)
goto
bad
;
// load each program segment (ignores ph flags)
ph
=
(
struct
proghdr
*
)
((
uchar
*
)
ELFHDR
+
ELFHDR
->
phoff
);
eph
=
ph
+
ELFHDR
->
phnum
;
for
(;
ph
<
eph
;
ph
++
)
readseg
(
ph
->
va
,
ph
->
memsz
,
ph
->
offset
);
// load each program segment (ignores ph flags)
ph
=
(
struct
proghdr
*
)
((
uchar
*
)
ELFHDR
+
ELFHDR
->
phoff
);
eph
=
ph
+
ELFHDR
->
phnum
;
for
(;
ph
<
eph
;
ph
++
)
readseg
(
ph
->
va
,
ph
->
memsz
,
ph
->
offset
);
// call the entry point from the ELF header
// note: does not return!
((
void
(
*
)(
void
))
(
ELFHDR
->
entry
&
0xFFFFFF
))();
// call the entry point from the ELF header
// note: does not return!
((
void
(
*
)(
void
))
(
ELFHDR
->
entry
&
0xFFFFFF
))();
bad:
outw
(
0x8A00
,
0x8A00
);
outw
(
0x8A00
,
0x8E00
);
while
(
1
)
/* do nothing */
;
outw
(
0x8A00
,
0x8A00
);
outw
(
0x8A00
,
0x8E00
);
while
(
1
)
/* do nothing */
;
}
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
...
...
@@ -70,52 +70,52 @@ bad:
void
readseg
(
uint
va
,
uint
count
,
uint
offset
)
{
uint
end_va
;
va
&=
0xFFFFFF
;
end_va
=
va
+
count
;
// round down to sector boundary
va
&=
~
(
SECTSIZE
-
1
);
// translate from bytes to sectors, and kernel starts at sector 1
offset
=
(
offset
/
SECTSIZE
)
+
1
;
// If this is too slow, we could read lots of sectors at a time.
// We'd write more to memory than asked, but it doesn't matter --
// we load in increasing order.
while
(
va
<
end_va
)
{
readsect
((
uchar
*
)
va
,
offset
);
va
+=
SECTSIZE
;
offset
++
;
}
uint
end_va
;
va
&=
0xFFFFFF
;
end_va
=
va
+
count
;
// round down to sector boundary
va
&=
~
(
SECTSIZE
-
1
);
// translate from bytes to sectors, and kernel starts at sector 1
offset
=
(
offset
/
SECTSIZE
)
+
1
;
// If this is too slow, we could read lots of sectors at a time.
// We'd write more to memory than asked, but it doesn't matter --
// we load in increasing order.
while
(
va
<
end_va
)
{
readsect
((
uchar
*
)
va
,
offset
);
va
+=
SECTSIZE
;
offset
++
;
}
}
void
waitdisk
(
void
)
{
// wait for disk reaady
while
((
inb
(
0x1F7
)
&
0xC0
)
!=
0x40
)
/* do nothing */
;
// wait for disk reaady
while
((
inb
(
0x1F7
)
&
0xC0
)
!=
0x40
)
/* do nothing */
;
}
void
readsect
(
void
*
dst
,
uint
offset
)
{
// wait for disk to be ready
waitdisk
();
// wait for disk to be ready
waitdisk
();
outb
(
0x1F2
,
1
);
// count = 1
outb
(
0x1F3
,
offset
);
outb
(
0x1F4
,
offset
>>
8
);
outb
(
0x1F5
,
offset
>>
16
);
outb
(
0x1F6
,
(
offset
>>
24
)
|
0xE0
);
outb
(
0x1F7
,
0x20
);
// cmd 0x20 - read sectors
outb
(
0x1F2
,
1
);
// count = 1
outb
(
0x1F3
,
offset
);
outb
(
0x1F4
,
offset
>>
8
);
outb
(
0x1F5
,
offset
>>
16
);
outb
(
0x1F6
,
(
offset
>>
24
)
|
0xE0
);
outb
(
0x1F7
,
0x20
);
// cmd 0x20 - read sectors
// wait for disk to be ready
waitdisk
();
// wait for disk to be ready
waitdisk
();
// read a sector
insl
(
0x1F0
,
dst
,
SECTSIZE
/
4
);
// read a sector
insl
(
0x1F0
,
dst
,
SECTSIZE
/
4
);
}
bootother.S
浏览文件 @
a650c606
#include "asm.h"
/*
* Start an Application Processor. This must be placed on a 4KB boundary
* somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
...
...
@@ -13,67 +13,68 @@
* mp.c causes each non-boot CPU in turn to jump to start.
* mp.c puts the correct %esp in start-4, and the place to jump
* to in start-8.
*
*
*/
.set PROT_MODE_CSEG,0x8
# code segment selector
.set PROT_MODE_CSEG,0x8
# code segment selector
.set PROT_MODE_DSEG,0x10 # data segment selector
.set CR0_PE_ON,0x1
# protected mode enable flag
.set CR0_PE_ON,0x1
# protected mode enable flag
.globl start
start: .code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
start:
.code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax
# Segment number zero
movw %ax,%ds
# -> Data Segment
movw %ax,%es
# -> Extra Segment
movw %ax,%ss
# -> Stack Segment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax
# Segment number zero
movw %ax,%ds
# -> Data Segment
movw %ax,%es
# -> Extra Segment
movw %ax,%ss
# -> Stack Segment
# Set up the stack pointer, growing downward from 0x7000-8.
movw $start-8,%sp
# Stack Pointer
#### Switch from real to protected mode
# Set up the stack pointer, growing downward from 0x7000-8.
movw $start-8,%sp
# Stack Pointer
#### Switch from real to protected mode
#### The descriptors in our GDT allow all physical memory to be accessed.
#### Furthermore, the descriptors have base addresses of 0, so that the
#### segment translation is a NOP, ie. virtual addresses are identical to
#### their physical addresses. With this setup, immediately after
####
enabling protected mode it will still appear to this code
####
that it is running directly on physical memory with no translation.
####
This initial NOP-translation setup is required by the processor
####
to ensure that the transition to protected mode occurs smoothly.
lgdt gdtdesc
# load GDT -- mandatory in protected mode
movl %cr0, %eax
# turn on protected mode
orl $CR0_PE_ON, %eax
#
movl %eax, %cr0
#
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp
$PROT_MODE_CSEG, $protcseg
####
enabling protected mode it will still appear to this code
####
that it is running directly on physical memory with no translation.
####
This initial NOP-translation setup is required by the processor
####
to ensure that the transition to protected mode occurs smoothly.
lgdt gdtdesc
# load GDT -- mandatory in protected mode
movl %cr0, %eax
# turn on protected mode
orl $CR0_PE_ON, %eax
#
movl %eax, %cr0
#
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp
$PROT_MODE_CSEG, $protcseg
#### we are in 32-bit protected mode (hence the .code32)
.code32
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax
# Our data segment selector
movw %ax, %ds
# -> DS: Data Segment
movw %ax, %es
# -> ES: Extra Segment
movw %ax, %fs
# -> FS
movw %ax, %gs
# -> GS
movw %ax, %ss
# -> SS: Stack Segment
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax
# Our data segment selector
movw %ax, %ds
# -> DS: Data Segment
movw %ax, %es
# -> ES: Extra Segment
movw %ax, %fs
# -> FS
movw %ax, %gs
# -> GS
movw %ax, %ss
# -> SS: Stack Segment
movl start-8, %eax
movl start-4, %esp
jmp
*%eax
.p2align 2
# force 4 byte alignment
movl start-8, %eax
movl start-4, %esp
jmp
*%eax
.p2align 2
# force 4 byte alignment
gdt:
SEG_NULLASM
# null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
# code seg
SEG_ASM(STA_W, 0x0, 0xffffffff)
# data seg
SEG_NULLASM
# null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
# code seg
SEG_ASM(STA_W, 0x0, 0xffffffff)
# data seg
gdtdesc:
.word 0x17
# sizeof(gdt) - 1
.long gdt
# address gdt
.word 0x17
# sizeof(gdt) - 1
.long gdt
# address gdt
cat.c
浏览文件 @
a650c606
...
...
@@ -30,10 +30,10 @@ main(int argc, char *argv[])
for
(
i
=
1
;
i
<
argc
;
i
++
){
fd
=
open
(
argv
[
i
],
0
);
if
(
fd
<
0
){
puts
(
"cat: cannot open "
);
puts
(
argv
[
i
]);
puts
(
"
\n
"
);
exit
();
puts
(
"cat: cannot open "
);
puts
(
argv
[
i
]);
puts
(
"
\n
"
);
exit
();
}
rfile
(
fd
);
close
(
fd
);
...
...
console.c
浏览文件 @
a650c606
...
...
@@ -18,13 +18,13 @@ int use_console_lock = 0;
static
void
lpt_putc
(
int
c
)
{
int
i
;
int
i
;
for
(
i
=
0
;
!
(
inb
(
0x378
+
1
)
&
0x80
)
&&
i
<
12800
;
i
++
)
;
outb
(
0x378
+
0
,
c
);
outb
(
0x378
+
2
,
0x08
|
0x04
|
0x01
);
outb
(
0x378
+
2
,
0x08
);
for
(
i
=
0
;
!
(
inb
(
0x378
+
1
)
&
0x80
)
&&
i
<
12800
;
i
++
)
;
outb
(
0x378
+
0
,
c
);
outb
(
0x378
+
2
,
0x08
|
0x04
|
0x01
);
outb
(
0x378
+
2
,
0x08
);
}
static
void
...
...
@@ -183,117 +183,117 @@ console_write (int minor, char *buf, int n)
/* This is i8042reg.h + kbdreg.h from NetBSD. */
#define
KBSTATP 0x64
/* kbd controller status port(I) */
#define
KBS_DIB 0x01
/* kbd data in buffer */
#define
KBDATAP 0x60
/* kbd data port(I) */
#define
KBSTATP 0x64
/* kbd controller status port(I) */
#define
KBS_DIB 0x01
/* kbd data in buffer */
#define
KBDATAP 0x60
/* kbd data port(I) */
#define NO
0
#define NO
0
#define SHIFT
(1<<0)
#define CTL
(1<<1)
#define ALT
(1<<2)
#define SHIFT
(1<<0)
#define CTL
(1<<1)
#define ALT
(1<<2)
#define CAPSLOCK
(1<<3)
#define NUMLOCK
(1<<4)
#define SCROLLLOCK
(1<<5)
#define CAPSLOCK
(1<<3)
#define NUMLOCK
(1<<4)
#define SCROLLLOCK
(1<<5)
#define E0ESC
(1<<6)
#define E0ESC
(1<<6)
// Special keycodes
#define KEY_HOME
0xE0
#define KEY_END
0xE1
#define KEY_UP
0xE2
#define KEY_DN
0xE3
#define KEY_LF
0xE4
#define KEY_RT
0xE5
#define KEY_PGUP
0xE6
#define KEY_PGDN
0xE7
#define KEY_INS
0xE8
#define KEY_DEL
0xE9
#define KEY_HOME
0xE0
#define KEY_END
0xE1
#define KEY_UP
0xE2
#define KEY_DN
0xE3
#define KEY_LF
0xE4
#define KEY_RT
0xE5
#define KEY_PGUP
0xE6
#define KEY_PGDN
0xE7
#define KEY_INS
0xE8
#define KEY_DEL
0xE9
static
uchar
shiftcode
[
256
]
=
{
[
0x1D
]
CTL
,
[
0x2A
]
SHIFT
,
[
0x36
]
SHIFT
,
[
0x38
]
ALT
,
[
0x9D
]
CTL
,
[
0xB8
]
ALT
[
0x1D
]
CTL
,
[
0x2A
]
SHIFT
,
[
0x36
]
SHIFT
,
[
0x38
]
ALT
,
[
0x9D
]
CTL
,
[
0xB8
]
ALT
};
static
uchar
togglecode
[
256
]
=
{
[
0x3A
]
CAPSLOCK
,
[
0x45
]
NUMLOCK
,
[
0x46
]
SCROLLLOCK
[
0x3A
]
CAPSLOCK
,
[
0x45
]
NUMLOCK
,
[
0x46
]
SCROLLLOCK
};
static
uchar
normalmap
[
256
]
=
{
NO
,
0x1B
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
// 0x00
'7'
,
'8'
,
'9'
,
'0'
,
'-'
,
'='
,
'\b'
,
'\t'
,
'q'
,
'w'
,
'e'
,
'r'
,
't'
,
'y'
,
'u'
,
'i'
,
// 0x10
'o'
,
'p'
,
'['
,
']'
,
'\n'
,
NO
,
'a'
,
's'
,
'd'
,
'f'
,
'g'
,
'h'
,
'j'
,
'k'
,
'l'
,
';'
,
// 0x20
'\''
,
'`'
,
NO
,
'\\'
,
'z'
,
'x'
,
'c'
,
'v'
,
'b'
,
'n'
,
'm'
,
','
,
'.'
,
'/'
,
NO
,
'*'
,
// 0x30
NO
,
' '
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
'7'
,
// 0x40
'8'
,
'9'
,
'-'
,
'4'
,
'5'
,
'6'
,
'+'
,
'1'
,
'2'
,
'3'
,
'0'
,
'.'
,
NO
,
NO
,
NO
,
NO
,
// 0x50
[
0x97
]
KEY_HOME
,
[
0x9C
]
'\n'
/*KP_Enter*/
,
[
0xB5
]
'/'
/*KP_Div*/
,
[
0xC8
]
KEY_UP
,
[
0xC9
]
KEY_PGUP
,
[
0xCB
]
KEY_LF
,
[
0xCD
]
KEY_RT
,
[
0xCF
]
KEY_END
,
[
0xD0
]
KEY_DN
,
[
0xD1
]
KEY_PGDN
,
[
0xD2
]
KEY_INS
,
[
0xD3
]
KEY_DEL
NO
,
0x1B
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
// 0x00
'7'
,
'8'
,
'9'
,
'0'
,
'-'
,
'='
,
'\b'
,
'\t'
,
'q'
,
'w'
,
'e'
,
'r'
,
't'
,
'y'
,
'u'
,
'i'
,
// 0x10
'o'
,
'p'
,
'['
,
']'
,
'\n'
,
NO
,
'a'
,
's'
,
'd'
,
'f'
,
'g'
,
'h'
,
'j'
,
'k'
,
'l'
,
';'
,
// 0x20
'\''
,
'`'
,
NO
,
'\\'
,
'z'
,
'x'
,
'c'
,
'v'
,
'b'
,
'n'
,
'm'
,
','
,
'.'
,
'/'
,
NO
,
'*'
,
// 0x30
NO
,
' '
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
'7'
,
// 0x40
'8'
,
'9'
,
'-'
,
'4'
,
'5'
,
'6'
,
'+'
,
'1'
,
'2'
,
'3'
,
'0'
,
'.'
,
NO
,
NO
,
NO
,
NO
,
// 0x50
[
0x97
]
KEY_HOME
,
[
0x9C
]
'\n'
/*KP_Enter*/
,
[
0xB5
]
'/'
/*KP_Div*/
,
[
0xC8
]
KEY_UP
,
[
0xC9
]
KEY_PGUP
,
[
0xCB
]
KEY_LF
,
[
0xCD
]
KEY_RT
,
[
0xCF
]
KEY_END
,
[
0xD0
]
KEY_DN
,
[
0xD1
]
KEY_PGDN
,
[
0xD2
]
KEY_INS
,
[
0xD3
]
KEY_DEL
};
static
uchar
shiftmap
[
256
]
=
{
NO
,
033
,
'!'
,
'@'
,
'#'
,
'$'
,
'%'
,
'^'
,
// 0x00
'&'
,
'*'
,
'('
,
')'
,
'_'
,
'+'
,
'\b'
,
'\t'
,
'Q'
,
'W'
,
'E'
,
'R'
,
'T'
,
'Y'
,
'U'
,
'I'
,
// 0x10
'O'
,
'P'
,
'{'
,
'}'
,
'\n'
,
NO
,
'A'
,
'S'
,
'D'
,
'F'
,
'G'
,
'H'
,
'J'
,
'K'
,
'L'
,
':'
,
// 0x20
'"'
,
'~'
,
NO
,
'|'
,
'Z'
,
'X'
,
'C'
,
'V'
,
'B'
,
'N'
,
'M'
,
'<'
,
'>'
,
'?'
,
NO
,
'*'
,
// 0x30
NO
,
' '
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
'7'
,
// 0x40
'8'
,
'9'
,
'-'
,
'4'
,
'5'
,
'6'
,
'+'
,
'1'
,
'2'
,
'3'
,
'0'
,
'.'
,
NO
,
NO
,
NO
,
NO
,
// 0x50
[
0x97
]
KEY_HOME
,
[
0x9C
]
'\n'
/*KP_Enter*/
,
[
0xB5
]
'/'
/*KP_Div*/
,
[
0xC8
]
KEY_UP
,
[
0xC9
]
KEY_PGUP
,
[
0xCB
]
KEY_LF
,
[
0xCD
]
KEY_RT
,
[
0xCF
]
KEY_END
,
[
0xD0
]
KEY_DN
,
[
0xD1
]
KEY_PGDN
,
[
0xD2
]
KEY_INS
,
[
0xD3
]
KEY_DEL
NO
,
033
,
'!'
,
'@'
,
'#'
,
'$'
,
'%'
,
'^'
,
// 0x00
'&'
,
'*'
,
'('
,
')'
,
'_'
,
'+'
,
'\b'
,
'\t'
,
'Q'
,
'W'
,
'E'
,
'R'
,
'T'
,
'Y'
,
'U'
,
'I'
,
// 0x10
'O'
,
'P'
,
'{'
,
'}'
,
'\n'
,
NO
,
'A'
,
'S'
,
'D'
,
'F'
,
'G'
,
'H'
,
'J'
,
'K'
,
'L'
,
':'
,
// 0x20
'"'
,
'~'
,
NO
,
'|'
,
'Z'
,
'X'
,
'C'
,
'V'
,
'B'
,
'N'
,
'M'
,
'<'
,
'>'
,
'?'
,
NO
,
'*'
,
// 0x30
NO
,
' '
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
'7'
,
// 0x40
'8'
,
'9'
,
'-'
,
'4'
,
'5'
,
'6'
,
'+'
,
'1'
,
'2'
,
'3'
,
'0'
,
'.'
,
NO
,
NO
,
NO
,
NO
,
// 0x50
[
0x97
]
KEY_HOME
,
[
0x9C
]
'\n'
/*KP_Enter*/
,
[
0xB5
]
'/'
/*KP_Div*/
,
[
0xC8
]
KEY_UP
,
[
0xC9
]
KEY_PGUP
,
[
0xCB
]
KEY_LF
,
[
0xCD
]
KEY_RT
,
[
0xCF
]
KEY_END
,
[
0xD0
]
KEY_DN
,
[
0xD1
]
KEY_PGDN
,
[
0xD2
]
KEY_INS
,
[
0xD3
]
KEY_DEL
};
#define C(x) (x - '@')
static
uchar
ctlmap
[
256
]
=
{
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
C
(
'Q'
),
C
(
'W'
),
C
(
'E'
),
C
(
'R'
),
C
(
'T'
),
C
(
'Y'
),
C
(
'U'
),
C
(
'I'
),
C
(
'O'
),
C
(
'P'
),
NO
,
NO
,
'\r'
,
NO
,
C
(
'A'
),
C
(
'S'
),
C
(
'D'
),
C
(
'F'
),
C
(
'G'
),
C
(
'H'
),
C
(
'J'
),
C
(
'K'
),
C
(
'L'
),
NO
,
NO
,
NO
,
NO
,
C
(
'\\'
),
C
(
'Z'
),
C
(
'X'
),
C
(
'C'
),
C
(
'V'
),
C
(
'B'
),
C
(
'N'
),
C
(
'M'
),
NO
,
NO
,
C
(
'/'
),
NO
,
NO
,
[
0x97
]
KEY_HOME
,
[
0xB5
]
C
(
'/'
),
[
0xC8
]
KEY_UP
,
[
0xC9
]
KEY_PGUP
,
[
0xCB
]
KEY_LF
,
[
0xCD
]
KEY_RT
,
[
0xCF
]
KEY_END
,
[
0xD0
]
KEY_DN
,
[
0xD1
]
KEY_PGDN
,
[
0xD2
]
KEY_INS
,
[
0xD3
]
KEY_DEL
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
NO
,
C
(
'Q'
),
C
(
'W'
),
C
(
'E'
),
C
(
'R'
),
C
(
'T'
),
C
(
'Y'
),
C
(
'U'
),
C
(
'I'
),
C
(
'O'
),
C
(
'P'
),
NO
,
NO
,
'\r'
,
NO
,
C
(
'A'
),
C
(
'S'
),
C
(
'D'
),
C
(
'F'
),
C
(
'G'
),
C
(
'H'
),
C
(
'J'
),
C
(
'K'
),
C
(
'L'
),
NO
,
NO
,
NO
,
NO
,
C
(
'\\'
),
C
(
'Z'
),
C
(
'X'
),
C
(
'C'
),
C
(
'V'
),
C
(
'B'
),
C
(
'N'
),
C
(
'M'
),
NO
,
NO
,
C
(
'/'
),
NO
,
NO
,
[
0x97
]
KEY_HOME
,
[
0xB5
]
C
(
'/'
),
[
0xC8
]
KEY_UP
,
[
0xC9
]
KEY_PGUP
,
[
0xCB
]
KEY_LF
,
[
0xCD
]
KEY_RT
,
[
0xCF
]
KEY_END
,
[
0xD0
]
KEY_DN
,
[
0xD1
]
KEY_PGDN
,
[
0xD2
]
KEY_INS
,
[
0xD3
]
KEY_DEL
};
static
uchar
*
charcode
[
4
]
=
{
normalmap
,
shiftmap
,
ctlmap
,
ctlmap
normalmap
,
shiftmap
,
ctlmap
,
ctlmap
};
#define KBD_BUF 64
...
...
elf.h
浏览文件 @
a650c606
...
...
@@ -5,32 +5,32 @@
#define ELF_MAGIC 0x464C457FU
/* "\x7FELF" in little endian */
struct
elfhdr
{
uint
magic
;
// must equal ELF_MAGIC
uchar
elf
[
12
];
ushort
type
;
ushort
machine
;
uint
version
;
uint
entry
;
uint
phoff
;
uint
shoff
;
uint
flags
;
ushort
ehsize
;
ushort
phentsize
;
ushort
phnum
;
ushort
shentsize
;
ushort
shnum
;
ushort
shstrndx
;
uint
magic
;
// must equal ELF_MAGIC
uchar
elf
[
12
];
ushort
type
;
ushort
machine
;
uint
version
;
uint
entry
;
uint
phoff
;
uint
shoff
;
uint
flags
;
ushort
ehsize
;
ushort
phentsize
;
ushort
phnum
;
ushort
shentsize
;
ushort
shnum
;
ushort
shstrndx
;
};
struct
proghdr
{
uint
type
;
uint
offset
;
uint
va
;
uint
pa
;
uint
filesz
;
uint
memsz
;
uint
flags
;
uint
align
;
uint
type
;
uint
offset
;
uint
va
;
uint
pa
;
uint
filesz
;
uint
memsz
;
uint
flags
;
uint
align
;
};
// Values for Proghdr type
...
...
fs.c
浏览文件 @
a650c606
...
...
@@ -270,16 +270,16 @@ itrunc(struct inode *ip)
for
(
i
=
0
;
i
<
NADDRS
;
i
++
)
{
if
(
ip
->
addrs
[
i
]
!=
0
)
{
if
(
i
==
INDIRECT
)
{
inbp
=
bread
(
ip
->
dev
,
ip
->
addrs
[
INDIRECT
]);
inbp
=
bread
(
ip
->
dev
,
ip
->
addrs
[
INDIRECT
]);
uint
*
a
=
(
uint
*
)
inbp
->
data
;
for
(
j
=
0
;
j
<
NINDIRECT
;
j
++
)
{
if
(
a
[
j
]
!=
0
)
{
bfree
(
ip
->
dev
,
a
[
j
]);
a
[
j
]
=
0
;
}
}
brelse
(
inbp
);
}
for
(
j
=
0
;
j
<
NINDIRECT
;
j
++
)
{
if
(
a
[
j
]
!=
0
)
{
bfree
(
ip
->
dev
,
a
[
j
]);
a
[
j
]
=
0
;
}
}
brelse
(
inbp
);
}
bfree
(
ip
->
dev
,
ip
->
addrs
[
i
]);
ip
->
addrs
[
i
]
=
0
;
}
...
...
@@ -411,8 +411,8 @@ writei(struct inode *ip, char *addr, uint off, uint n)
lbn
=
off
/
BSIZE
;
if
(
lbn
>=
MAXFILE
)
return
r
;
if
(
newblock
(
ip
,
lbn
)
<
0
)
{
cprintf
(
"newblock failed
\n
"
);
return
r
;
cprintf
(
"newblock failed
\n
"
);
return
r
;
}
m
=
min
(
BSIZE
-
off
%
BSIZE
,
n
-
r
);
bp
=
bread
(
ip
->
dev
,
bmap
(
ip
,
lbn
));
...
...
@@ -424,8 +424,8 @@ writei(struct inode *ip, char *addr, uint off, uint n)
}
if
(
r
>
0
)
{
if
(
off
>
ip
->
size
)
{
if
(
ip
->
type
==
T_DIR
)
ip
->
size
=
((
off
/
BSIZE
)
+
1
)
*
BSIZE
;
else
ip
->
size
=
off
;
if
(
ip
->
type
==
T_DIR
)
ip
->
size
=
((
off
/
BSIZE
)
+
1
)
*
BSIZE
;
else
ip
->
size
=
off
;
}
iupdate
(
ip
);
}
...
...
ide.c
浏览文件 @
a650c606
...
...
@@ -11,8 +11,8 @@
#include "traps.h"
#include "spinlock.h"
#define IDE_BSY
0x80
#define IDE_DRDY
0x40
#define IDE_BSY
0x80
#define IDE_DRDY
0x40
#define IDE_DF 0x20
#define IDE_ERR 0x01
...
...
@@ -23,6 +23,7 @@ struct ide_request {
uint
nsecs
;
uint
read
;
};
struct
ide_request
request
[
NREQUEST
];
int
head
,
tail
;
struct
spinlock
ide_lock
;
...
...
@@ -154,7 +155,7 @@ int
ide_write
(
int
diskno
,
uint
secno
,
const
void
*
src
,
uint
nsecs
)
{
int
r
;
if
(
nsecs
>
256
)
panic
(
"ide_write"
);
...
...
@@ -165,7 +166,7 @@ ide_write(int diskno, uint secno, const void *src, uint nsecs)
outb
(
0x1F4
,
(
secno
>>
8
)
&
0xFF
);
outb
(
0x1F5
,
(
secno
>>
16
)
&
0xFF
);
outb
(
0x1F6
,
0xE0
|
((
diskno
&
1
)
<<
4
)
|
((
secno
>>
24
)
&
0x0F
));
outb
(
0x1F7
,
0x30
);
// CMD 0x30 means write sector
outb
(
0x1F7
,
0x30
);
// CMD 0x30 means write sector
for
(;
nsecs
>
0
;
nsecs
--
,
src
+=
512
)
{
if
((
r
=
ide_wait_ready
(
1
))
<
0
)
...
...
ioapic.c
浏览文件 @
a650c606
...
...
@@ -11,8 +11,8 @@ struct ioapic {
};
#define
IOAPIC_REDTBL_LO(i)
(IOAPIC_REDTBL + (i) * 2)
#define
IOAPIC_REDTBL_HI(i)
(IOAPIC_REDTBL_LO(i) + 1)
#define
IOAPIC_REDTBL_LO(i)
(IOAPIC_REDTBL + (i) * 2)
#define
IOAPIC_REDTBL_HI(i)
(IOAPIC_REDTBL_LO(i) + 1)
static
uint
ioapic_read
(
struct
ioapic
*
io
,
int
reg
)
...
...
@@ -40,7 +40,7 @@ ioapic_init(void)
io
=
(
struct
ioapic
*
)
IO_APIC_BASE
;
l
=
ioapic_read
(
io
,
IOAPIC_VER
);
nintr
=
((
l
&
IOART_VER_MAXREDIR
)
>>
MAXREDIRSHIFT
)
+
1
;
id
=
ioapic_read
(
io
,
IOAPIC_ID
)
>>
APIC_ID_SHIFT
;
id
=
ioapic_read
(
io
,
IOAPIC_ID
)
>>
APIC_ID_SHIFT
;
if
(
id
!=
ioapic_id
)
panic
(
"ioapic_init: id isn't equal to ioapic_id
\n
"
);
for
(
i
=
0
;
i
<
nintr
;
i
++
)
{
...
...
ioapic.h
浏览文件 @
a650c606
#define IO_APIC_BASE
0xFEC00000
/* default physical locations of an IO APIC */
#define IOAPIC_WINDOW
0x10
/* window register offset */
#define IO_APIC_BASE
0xFEC00000
/* default physical locations of an IO APIC */
#define IOAPIC_WINDOW
0x10
/* window register offset */
/* constants relating to APIC ID registers */
#define APIC_ID_MASK
0xff000000
#define
APIC_ID_SHIFT
24
#define
APIC_ID_CLUSTER
0xf0
#define
APIC_ID_CLUSTER_ID
0x0f
#define
APIC_MAX_CLUSTER
0xe
#define
APIC_MAX_INTRACLUSTER_ID 3
#define
APIC_ID_CLUSTER_SHIFT
4
#define APIC_ID_MASK
0xff000000
#define
APIC_ID_SHIFT
24
#define
APIC_ID_CLUSTER
0xf0
#define
APIC_ID_CLUSTER_ID
0x0f
#define
APIC_MAX_CLUSTER
0xe
#define
APIC_MAX_INTRACLUSTER_ID 3
#define
APIC_ID_CLUSTER_SHIFT
4
/* fields in VER */
#define APIC_VER_VERSION
0x000000ff
#define APIC_VER_MAXLVT
0x00ff0000
#define MAXLVTSHIFT
16
#define APIC_VER_VERSION
0x000000ff
#define APIC_VER_MAXLVT
0x00ff0000
#define MAXLVTSHIFT
16
/* Indexes into IO APIC */
#define IOAPIC_ID
0x00
#define IOAPIC_VER
0x01
#define IOAPIC_ARB
0x02
#define IOAPIC_REDTBL
0x10
#define IOAPIC_REDTBL0
IOAPIC_REDTBL
#define IOAPIC_REDTBL1
(IOAPIC_REDTBL+0x02)
#define IOAPIC_REDTBL2
(IOAPIC_REDTBL+0x04)
#define IOAPIC_REDTBL3
(IOAPIC_REDTBL+0x06)
#define IOAPIC_REDTBL4
(IOAPIC_REDTBL+0x08)
#define IOAPIC_REDTBL5
(IOAPIC_REDTBL+0x0a)
#define IOAPIC_REDTBL6
(IOAPIC_REDTBL+0x0c)
#define IOAPIC_REDTBL7
(IOAPIC_REDTBL+0x0e)
#define IOAPIC_REDTBL8
(IOAPIC_REDTBL+0x10)
#define IOAPIC_REDTBL9
(IOAPIC_REDTBL+0x12)
#define IOAPIC_REDTBL10
(IOAPIC_REDTBL+0x14)
#define IOAPIC_REDTBL11
(IOAPIC_REDTBL+0x16)
#define IOAPIC_REDTBL12
(IOAPIC_REDTBL+0x18)
#define IOAPIC_REDTBL13
(IOAPIC_REDTBL+0x1a)
#define IOAPIC_REDTBL14
(IOAPIC_REDTBL+0x1c)
#define IOAPIC_REDTBL15
(IOAPIC_REDTBL+0x1e)
#define IOAPIC_REDTBL16
(IOAPIC_REDTBL+0x20)
#define IOAPIC_REDTBL17
(IOAPIC_REDTBL+0x22)
#define IOAPIC_REDTBL18
(IOAPIC_REDTBL+0x24)
#define IOAPIC_REDTBL19
(IOAPIC_REDTBL+0x26)
#define IOAPIC_REDTBL20
(IOAPIC_REDTBL+0x28)
#define IOAPIC_REDTBL21
(IOAPIC_REDTBL+0x2a)
#define IOAPIC_REDTBL22
(IOAPIC_REDTBL+0x2c)
#define IOAPIC_REDTBL23
(IOAPIC_REDTBL+0x2e)
#define IOAPIC_ID
0x00
#define IOAPIC_VER
0x01
#define IOAPIC_ARB
0x02
#define IOAPIC_REDTBL
0x10
#define IOAPIC_REDTBL0
IOAPIC_REDTBL
#define IOAPIC_REDTBL1
(IOAPIC_REDTBL+0x02)
#define IOAPIC_REDTBL2
(IOAPIC_REDTBL+0x04)
#define IOAPIC_REDTBL3
(IOAPIC_REDTBL+0x06)
#define IOAPIC_REDTBL4
(IOAPIC_REDTBL+0x08)
#define IOAPIC_REDTBL5
(IOAPIC_REDTBL+0x0a)
#define IOAPIC_REDTBL6
(IOAPIC_REDTBL+0x0c)
#define IOAPIC_REDTBL7
(IOAPIC_REDTBL+0x0e)
#define IOAPIC_REDTBL8
(IOAPIC_REDTBL+0x10)
#define IOAPIC_REDTBL9
(IOAPIC_REDTBL+0x12)
#define IOAPIC_REDTBL10
(IOAPIC_REDTBL+0x14)
#define IOAPIC_REDTBL11
(IOAPIC_REDTBL+0x16)
#define IOAPIC_REDTBL12
(IOAPIC_REDTBL+0x18)
#define IOAPIC_REDTBL13
(IOAPIC_REDTBL+0x1a)
#define IOAPIC_REDTBL14
(IOAPIC_REDTBL+0x1c)
#define IOAPIC_REDTBL15
(IOAPIC_REDTBL+0x1e)
#define IOAPIC_REDTBL16
(IOAPIC_REDTBL+0x20)
#define IOAPIC_REDTBL17
(IOAPIC_REDTBL+0x22)
#define IOAPIC_REDTBL18
(IOAPIC_REDTBL+0x24)
#define IOAPIC_REDTBL19
(IOAPIC_REDTBL+0x26)
#define IOAPIC_REDTBL20
(IOAPIC_REDTBL+0x28)
#define IOAPIC_REDTBL21
(IOAPIC_REDTBL+0x2a)
#define IOAPIC_REDTBL22
(IOAPIC_REDTBL+0x2c)
#define IOAPIC_REDTBL23
(IOAPIC_REDTBL+0x2e)
/*
* fields in the IO APIC's redirection table entries
*/
#define IOART_DEST
APIC_ID_MASK
/* broadcast addr: all APICs */
#define IOART_DEST
APIC_ID_MASK
/* broadcast addr: all APICs */
#define IOART_RESV
0x00fe0000
/* reserved */
#define IOART_RESV
0x00fe0000
/* reserved */
#define IOART_INTMASK
0x00010000
/* R/W: INTerrupt mask */
#define IOART_INTMCLR
0x00000000
/* clear, allow INTs */
#define IOART_INTMSET
0x00010000
/* set, inhibit INTs */
#define IOART_INTMASK
0x00010000
/* R/W: INTerrupt mask */
#define IOART_INTMCLR
0x00000000
/* clear, allow INTs */
#define IOART_INTMSET
0x00010000
/* set, inhibit INTs */
#define IOART_TRGRMOD
0x00008000
/* R/W: trigger mode */
#define IOART_TRGREDG
0x00000000
/* edge */
#define IOART_TRGRLVL
0x00008000
/* level */
#define IOART_TRGRMOD
0x00008000
/* R/W: trigger mode */
#define IOART_TRGREDG
0x00000000
/* edge */
#define IOART_TRGRLVL
0x00008000
/* level */
#define IOART_REM_IRR
0x00004000
/* RO: remote IRR */
#define IOART_REM_IRR
0x00004000
/* RO: remote IRR */
#define IOART_INTPOL
0x00002000
/* R/W: INT input pin polarity */
#define IOART_INTAHI
0x00000000
/* active high */
#define IOART_INTALO
0x00002000
/* active low */
#define IOART_INTPOL
0x00002000
/* R/W: INT input pin polarity */
#define IOART_INTAHI
0x00000000
/* active high */
#define IOART_INTALO
0x00002000
/* active low */
#define IOART_DELIVS
0x00001000
/* RO: delivery status */
#define IOART_DELIVS
0x00001000
/* RO: delivery status */
#define IOART_DESTMOD
0x00000800
/* R/W: destination mode */
#define IOART_DESTPHY
0x00000000
/* physical */
#define IOART_DESTLOG
0x00000800
/* logical */
#define IOART_DESTMOD
0x00000800
/* R/W: destination mode */
#define IOART_DESTPHY
0x00000000
/* physical */
#define IOART_DESTLOG
0x00000800
/* logical */
#define IOART_DELMOD
0x00000700
/* R/W: delivery mode */
#define IOART_DELFIXED
0x00000000
/* fixed */
#define IOART_DELLOPRI
0x00000100
/* lowest priority */
#define IOART_DELSMI
0x00000200
/* System Management INT */
#define IOART_DELRSV1
0x00000300
/* reserved */
#define IOART_DELNMI
0x00000400
/* NMI signal */
#define IOART_DELINIT
0x00000500
/* INIT signal */
#define IOART_DELRSV2
0x00000600
/* reserved */
#define IOART_DELEXINT
0x00000700
/* External INTerrupt */
#define IOART_DELMOD
0x00000700
/* R/W: delivery mode */
#define IOART_DELFIXED
0x00000000
/* fixed */
#define IOART_DELLOPRI
0x00000100
/* lowest priority */
#define IOART_DELSMI
0x00000200
/* System Management INT */
#define IOART_DELRSV1
0x00000300
/* reserved */
#define IOART_DELNMI
0x00000400
/* NMI signal */
#define IOART_DELINIT
0x00000500
/* INIT signal */
#define IOART_DELRSV2
0x00000600
/* reserved */
#define IOART_DELEXINT
0x00000700
/* External INTerrupt */
#define IOART_INTVEC
0x000000ff
/* R/W: INTerrupt vector field */
#define IOART_INTVEC
0x000000ff
/* R/W: INTerrupt vector field */
/* fields in VER */
#define IOART_VER_VERSION
0x000000ff
#define IOART_VER_MAXREDIR
0x00ff0000
#define MAXREDIRSHIFT
16
#define IOART_VER_VERSION
0x000000ff
#define IOART_VER_MAXREDIR
0x00ff0000
#define MAXREDIRSHIFT
16
ls.c
浏览文件 @
a650c606
...
...
@@ -59,17 +59,17 @@ main(int argc, char *argv[])
sz
=
st
.
st_size
;
for
(
off
=
0
;
off
<
sz
;
off
+=
sizeof
(
struct
dirent
))
{
if
(
read
(
fd
,
&
dirent
,
sizeof
(
struct
dirent
))
!=
sizeof
(
struct
dirent
))
{
printf
(
1
,
"ls: read error
\n
"
);
break
;
printf
(
1
,
"ls: read error
\n
"
);
break
;
}
if
(
dirent
.
inum
!=
0
)
{
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
if
(
stat
(
dirent
.
name
,
&
st
)
<
0
)
{
printf
(
1
,
"stat: failed %s
\n
"
,
dirent
.
name
);
continue
;
}
pname
(
dirent
.
name
);
printf
(
1
,
"%d %d %d
\n
"
,
st
.
st_type
,
dirent
.
inum
,
st
.
st_size
);
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
if
(
stat
(
dirent
.
name
,
&
st
)
<
0
)
{
printf
(
1
,
"stat: failed %s
\n
"
,
dirent
.
name
);
continue
;
}
pname
(
dirent
.
name
);
printf
(
1
,
"%d %d %d
\n
"
,
st
.
st_type
,
dirent
.
inum
,
st
.
st_size
);
}
}
break
;
...
...
main.c
浏览文件 @
a650c606
...
...
@@ -97,7 +97,7 @@ mpmain(void)
// make sure there's a TSS
setupsegs
(
0
);
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
cpus
[
cpu
()].
booted
=
1
;
// Enable interrupts on this processor.
...
...
mkfs.c
浏览文件 @
a650c606
...
...
@@ -81,8 +81,8 @@ main(int argc, char *argv[])
usedblocks
=
ninodes
/
IPB
+
3
+
bitblocks
;
freeblock
=
usedblocks
;
printf
(
"used %d (bit %d ninode %d) free %d total %d
\n
"
,
usedblocks
,
bitblocks
,
ninodes
/
IPB
+
1
,
freeblock
,
nblocks
+
usedblocks
);
printf
(
"used %d (bit %d ninode %d) free %d total %d
\n
"
,
usedblocks
,
bitblocks
,
ninodes
/
IPB
+
1
,
freeblock
,
nblocks
+
usedblocks
);
assert
(
nblocks
+
usedblocks
==
size
);
...
...
@@ -246,22 +246,22 @@ iappend(uint inum, void *xp, int n)
assert
(
fbn
<
MAXFILE
);
if
(
fbn
<
NDIRECT
)
{
if
(
xint
(
din
.
addrs
[
fbn
])
==
0
)
{
din
.
addrs
[
fbn
]
=
xint
(
freeblock
++
);
usedblocks
++
;
din
.
addrs
[
fbn
]
=
xint
(
freeblock
++
);
usedblocks
++
;
}
x
=
xint
(
din
.
addrs
[
fbn
]);
}
else
{
if
(
xint
(
din
.
addrs
[
INDIRECT
])
==
0
)
{
printf
(
"allocate indirect block
\n
"
);
din
.
addrs
[
INDIRECT
]
=
xint
(
freeblock
++
);
usedblocks
++
;
printf
(
"allocate indirect block
\n
"
);
din
.
addrs
[
INDIRECT
]
=
xint
(
freeblock
++
);
usedblocks
++
;
}
printf
(
"read indirect block
\n
"
);
rsect
(
xint
(
din
.
addrs
[
INDIRECT
]),
(
char
*
)
indirect
);
if
(
indirect
[
fbn
-
NDIRECT
]
==
0
)
{
indirect
[
fbn
-
NDIRECT
]
=
xint
(
freeblock
++
);
usedblocks
++
;
wsect
(
xint
(
din
.
addrs
[
INDIRECT
]),
(
char
*
)
indirect
);
indirect
[
fbn
-
NDIRECT
]
=
xint
(
freeblock
++
);
usedblocks
++
;
wsect
(
xint
(
din
.
addrs
[
INDIRECT
]),
(
char
*
)
indirect
);
}
x
=
xint
(
indirect
[
fbn
-
NDIRECT
]);
}
...
...
mmu.h
浏览文件 @
a650c606
差异被折叠。
点击展开。
mp.c
浏览文件 @
a650c606
...
...
@@ -8,25 +8,25 @@
#include "proc.h"
static
char
*
buses
[]
=
{
"CBUSI "
,
"CBUSII"
,
"EISA "
,
"FUTURE"
,
"INTERN"
,
"ISA "
,
"MBI "
,
"MBII "
,
"MCA "
,
"MPI "
,
"MPSA "
,
"NUBUS "
,
"PCI "
,
"PCMCIA"
,
"TC "
,
"VL "
,
"VME "
,
"XPRESS"
,
0
,
"CBUSI "
,
"CBUSII"
,
"EISA "
,
"FUTURE"
,
"INTERN"
,
"ISA "
,
"MBI "
,
"MBII "
,
"MCA "
,
"MPI "
,
"MPSA "
,
"NUBUS "
,
"PCI "
,
"PCMCIA"
,
"TC "
,
"VL "
,
"VME "
,
"XPRESS"
,
0
,
};
struct
cpu
cpus
[
NCPU
];
...
...
@@ -146,7 +146,7 @@ mp_init(void)
proc
=
(
struct
mppe
*
)
p
;
cpus
[
ncpu
].
apicid
=
proc
->
apicid
;
if
(
proc
->
flags
&
MPBP
)
{
bcpu
=
&
cpus
[
ncpu
];
bcpu
=
&
cpus
[
ncpu
];
}
ncpu
++
;
p
+=
sizeof
(
struct
mppe
);
...
...
@@ -154,8 +154,8 @@ mp_init(void)
case
MPBUS
:
bus
=
(
struct
mpbe
*
)
p
;
for
(
i
=
0
;
buses
[
i
];
i
++
){
if
(
strncmp
(
buses
[
i
],
bus
->
string
,
sizeof
(
bus
->
string
))
==
0
)
break
;
if
(
strncmp
(
buses
[
i
],
bus
->
string
,
sizeof
(
bus
->
string
))
==
0
)
break
;
}
p
+=
sizeof
(
struct
mpbe
);
continue
;
...
...
@@ -171,18 +171,18 @@ mp_init(void)
default:
cprintf
(
"mpinit: unknown PCMP type 0x%x (e-p 0x%x)
\n
"
,
*
p
,
e
-
p
);
while
(
p
<
e
){
cprintf
(
"%uX "
,
*
p
);
p
++
;
cprintf
(
"%uX "
,
*
p
);
p
++
;
}
break
;
}
}
if
(
mp
->
imcrp
)
{
// it appears that bochs doesn't support IMCR, and code won't run
outb
(
0x22
,
0x70
);
/* select IMCR */
byte
=
inb
(
0x23
);
/* current contents */
byte
|=
0x01
;
/* mask external INTR */
outb
(
0x23
,
byte
);
/* disconnect 8259s/NMI */
outb
(
0x22
,
0x70
);
/* select IMCR */
byte
=
inb
(
0x23
);
/* current contents */
byte
|=
0x01
;
/* mask external INTR */
outb
(
0x23
,
byte
);
/* disconnect 8259s/NMI */
}
}
...
...
@@ -205,7 +205,7 @@ mp_startthem(void)
int
c
;
memmove
((
void
*
)
APBOOTCODE
,
_binary_bootother_start
,
(
uint
)
_binary_bootother_size
);
(
uint
)
_binary_bootother_size
);
for
(
c
=
0
;
c
<
ncpu
;
c
++
){
if
(
c
==
cpu
())
continue
;
...
...
mp.h
浏览文件 @
a650c606
...
...
@@ -3,121 +3,121 @@
*
*/
struct
mp
{
/* floating pointer */
uchar
signature
[
4
];
/* "_MP_" */
void
*
physaddr
;
/* physical address of MP configuration table */
uchar
length
;
/* 1 */
uchar
specrev
;
/* [14] */
uchar
checksum
;
/* all bytes must add up to 0 */
uchar
type
;
/* MP system configuration type */
struct
mp
{
/* floating pointer */
uchar
signature
[
4
];
/* "_MP_" */
void
*
physaddr
;
/* physical address of MP configuration table */
uchar
length
;
/* 1 */
uchar
specrev
;
/* [14] */
uchar
checksum
;
/* all bytes must add up to 0 */
uchar
type
;
/* MP system configuration type */
uchar
imcrp
;
uchar
reserved
[
3
];
};
struct
mpctb
{
/* configuration table header */
uchar
signature
[
4
];
/* "PCMP" */
ushort
length
;
/* total table length */
uchar
version
;
/* [14] */
uchar
checksum
;
/* all bytes must add up to 0 */
uchar
product
[
20
];
/* product id */
uint
*
oemtable
;
/* OEM table pointer */
ushort
oemlength
;
/* OEM table length */
ushort
entry
;
/* entry count */
uint
*
lapicaddr
;
/* address of local APIC */
ushort
xlength
;
/* extended table length */
uchar
xchecksum
;
/* extended table checksum */
struct
mpctb
{
/* configuration table header */
uchar
signature
[
4
];
/* "PCMP" */
ushort
length
;
/* total table length */
uchar
version
;
/* [14] */
uchar
checksum
;
/* all bytes must add up to 0 */
uchar
product
[
20
];
/* product id */
uint
*
oemtable
;
/* OEM table pointer */
ushort
oemlength
;
/* OEM table length */
ushort
entry
;
/* entry count */
uint
*
lapicaddr
;
/* address of local APIC */
ushort
xlength
;
/* extended table length */
uchar
xchecksum
;
/* extended table checksum */
uchar
reserved
;
};
struct
mppe
{
/* processor table entry */
uchar
type
;
/* entry type (0) */
uchar
apicid
;
/* local APIC id */
uchar
version
;
/* local APIC verison */
uchar
flags
;
/* CPU flags */
uchar
signature
[
4
];
/* CPU signature */
uint
feature
;
/* feature flags from CPUID instruction */
struct
mppe
{
/* processor table entry */
uchar
type
;
/* entry type (0) */
uchar
apicid
;
/* local APIC id */
uchar
version
;
/* local APIC verison */
uchar
flags
;
/* CPU flags */
uchar
signature
[
4
];
/* CPU signature */
uint
feature
;
/* feature flags from CPUID instruction */
uchar
reserved
[
8
];
};
struct
mpbe
{
/* bus table entry */
uchar
type
;
/* entry type (1) */
uchar
busno
;
/* bus id */
char
string
[
6
];
/* bus type string */
struct
mpbe
{
/* bus table entry */
uchar
type
;
/* entry type (1) */
uchar
busno
;
/* bus id */
char
string
[
6
];
/* bus type string */
};
struct
mpioapic
{
/* I/O APIC table entry */
uchar
type
;
/* entry type (2) */
uchar
apicno
;
/* I/O APIC id */
uchar
version
;
/* I/O APIC version */
uchar
flags
;
/* I/O APIC flags */
uint
*
addr
;
/* I/O APIC address */
struct
mpioapic
{
/* I/O APIC table entry */
uchar
type
;
/* entry type (2) */
uchar
apicno
;
/* I/O APIC id */
uchar
version
;
/* I/O APIC version */
uchar
flags
;
/* I/O APIC flags */
uint
*
addr
;
/* I/O APIC address */
};
struct
mpie
{
/* interrupt table entry */
uchar
type
;
/* entry type ([34]) */
uchar
intr
;
/* interrupt type */
ushort
flags
;
/* interrupt flag */
uchar
busno
;
/* source bus id */
uchar
irq
;
/* source bus irq */
uchar
apicno
;
/* destination APIC id */
uchar
intin
;
/* destination APIC [L]INTIN# */
struct
mpie
{
/* interrupt table entry */
uchar
type
;
/* entry type ([34]) */
uchar
intr
;
/* interrupt type */
ushort
flags
;
/* interrupt flag */
uchar
busno
;
/* source bus id */
uchar
irq
;
/* source bus irq */
uchar
apicno
;
/* destination APIC id */
uchar
intin
;
/* destination APIC [L]INTIN# */
};
enum
{
/* table entry types */
MPPROCESSOR
=
0x00
,
/* one entry per processor */
MPBUS
=
0x01
,
/* one entry per bus */
MPIOAPIC
=
0x02
,
/* one entry per I/O APIC */
MPIOINTR
=
0x03
,
/* one entry per bus interrupt source */
MPLINTR
=
0x04
,
/* one entry per system interrupt source */
enum
{
/* table entry types */
MPPROCESSOR
=
0x00
,
/* one entry per processor */
MPBUS
=
0x01
,
/* one entry per bus */
MPIOAPIC
=
0x02
,
/* one entry per I/O APIC */
MPIOINTR
=
0x03
,
/* one entry per bus interrupt source */
MPLINTR
=
0x04
,
/* one entry per system interrupt source */
MPSASM
=
0x80
,
MPHIERARCHY
=
0x81
,
MPHIERARCHY
=
0x81
,
MPCBASM
=
0x82
,
/* PCMPprocessor and PCMPioapic flags */
MPEN
=
0x01
,
/* enabled */
MPBP
=
0x02
,
/* bootstrap processor */
MPEN
=
0x01
,
/* enabled */
MPBP
=
0x02
,
/* bootstrap processor */
/* PCMPiointr and PCMPlintr flags */
MPPOMASK
=
0x03
,
/* polarity conforms to specifications of bus */
MPHIGH
=
0x01
,
/* active high */
MPLOW
=
0x03
,
/* active low */
MPELMASK
=
0x0C
,
/* trigger mode of APIC input signals */
MPEDGE
=
0x04
,
/* edge-triggered */
MPLEVEL
=
0x0C
,
/* level-triggered */
/* PCMPiointr and PCMPlintr flags */
MPPOMASK
=
0x03
,
/* polarity conforms to specifications of bus */
MPHIGH
=
0x01
,
/* active high */
MPLOW
=
0x03
,
/* active low */
MPELMASK
=
0x0C
,
/* trigger mode of APIC input signals */
MPEDGE
=
0x04
,
/* edge-triggered */
MPLEVEL
=
0x0C
,
/* level-triggered */
/* PCMPiointr and PCMPlintr interrupt type */
MPINT
=
0x00
,
/* vectored interrupt from APIC Rdt */
MPNMI
=
0x01
,
/* non-maskable interrupt */
MPSMI
=
0x02
,
/* system management interrupt */
MPExtINT
=
0x03
,
/* vectored interrupt from external PIC */
MPINT
=
0x00
,
/* vectored interrupt from APIC Rdt */
MPNMI
=
0x01
,
/* non-maskable interrupt */
MPSMI
=
0x02
,
/* system management interrupt */
MPExtINT
=
0x03
,
/* vectored interrupt from external PIC */
};
/*
* Common bits for
*
I/O APIC Redirection Table Entry;
*
Local APIC Local Interrupt Vector Table;
*
Local APIC Inter-Processor Interrupt;
*
Local APIC Timer Vector Table.
*
I/O APIC Redirection Table Entry;
*
Local APIC Local Interrupt Vector Table;
*
Local APIC Inter-Processor Interrupt;
*
Local APIC Timer Vector Table.
*/
enum
{
APIC_FIXED
=
0x00000000
,
/* [10:8] Delivery Mode */
APIC_LOWEST
=
0x00000100
,
/* Lowest priority */
APIC_SMI
=
0x00000200
,
/* System Management Interrupt */
APIC_RR
=
0x00000300
,
/* Remote Read */
APIC_NMI
=
0x00000400
,
APIC_INIT
=
0x00000500
,
/* INIT/RESET */
APIC_STARTUP
=
0x00000600
,
/* Startup IPI */
APIC_EXTINT
=
0x00000700
,
APIC_FIXED
=
0x00000000
,
/* [10:8] Delivery Mode */
APIC_LOWEST
=
0x00000100
,
/* Lowest priority */
APIC_SMI
=
0x00000200
,
/* System Management Interrupt */
APIC_RR
=
0x00000300
,
/* Remote Read */
APIC_NMI
=
0x00000400
,
APIC_INIT
=
0x00000500
,
/* INIT/RESET */
APIC_STARTUP
=
0x00000600
,
/* Startup IPI */
APIC_EXTINT
=
0x00000700
,
APIC_PHYSICAL
=
0x00000000
,
/* [11] Destination Mode (RW) */
APIC_LOGICAL
=
0x00000800
,
APIC_PHYSICAL
=
0x00000000
,
/* [11] Destination Mode (RW) */
APIC_LOGICAL
=
0x00000800
,
APIC_DELIVS
=
0x00001000
,
/* [12] Delivery Status (RO) */
APIC_HIGH
=
0x00000000
,
/* [13] Interrupt Input Pin Polarity (RW) */
APIC_LOW
=
0x00002000
,
APIC_REMOTEIRR
=
0x00004000
,
/* [14] Remote IRR (RO) */
APIC_EDGE
=
0x00000000
,
/* [15] Trigger Mode (RW) */
APIC_LEVEL
=
0x00008000
,
APIC_IMASK
=
0x00010000
,
/* [16] Interrupt Mask */
APIC_DELIVS
=
0x00001000
,
/* [12] Delivery Status (RO) */
APIC_HIGH
=
0x00000000
,
/* [13] Interrupt Input Pin Polarity (RW) */
APIC_LOW
=
0x00002000
,
APIC_REMOTEIRR
=
0x00004000
,
/* [14] Remote IRR (RO) */
APIC_EDGE
=
0x00000000
,
/* [15] Trigger Mode (RW) */
APIC_LEVEL
=
0x00008000
,
APIC_IMASK
=
0x00010000
,
/* [16] Interrupt Mask */
};
picirq.c
浏览文件 @
a650c606
...
...
@@ -4,10 +4,10 @@
#include "defs.h"
// I/O Addresses of the two 8259A programmable interrupt controllers
#define IO_PIC1
0x20
// Master (IRQs 0-7)
#define IO_PIC2
0xA0
// Slave (IRQs 8-15)
#define IO_PIC1
0x20
// Master (IRQs 0-7)
#define IO_PIC2
0xA0
// Slave (IRQs 8-15)
#define IRQ_SLAVE 2
// IRQ at which slave connects to master
#define IRQ_SLAVE 2
// IRQ at which slave connects to master
// Current IRQ mask.
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
...
...
@@ -49,19 +49,19 @@ pic_init(void)
// n: 1 = special fully nested mode
// b: 1 = buffered mode
// m: 0 = slave PIC, 1 = master PIC
//
(ignored when b is 0, as the master/slave role
//
can be hardwired).
//
(ignored when b is 0, as the master/slave role
//
can be hardwired).
// a: 1 = Automatic EOI mode
// p: 0 = MCS-80/85 mode, 1 = intel x86 mode
outb
(
IO_PIC1
+
1
,
0x3
);
// Set up slave (8259A-2)
outb
(
IO_PIC2
,
0x11
);
// ICW1
outb
(
IO_PIC2
+
1
,
IRQ_OFFSET
+
8
);
// ICW2
outb
(
IO_PIC2
+
1
,
IRQ_SLAVE
);
// ICW3
outb
(
IO_PIC2
,
0x11
);
// ICW1
outb
(
IO_PIC2
+
1
,
IRQ_OFFSET
+
8
);
// ICW2
outb
(
IO_PIC2
+
1
,
IRQ_SLAVE
);
// ICW3
// NB Automatic EOI mode doesn't tend to work on the slave.
// Linux source code says it's "to be investigated".
outb
(
IO_PIC2
+
1
,
0x3
);
// ICW4
outb
(
IO_PIC2
+
1
,
0x3
);
// ICW4
// OCW3: 0ef01prs
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
...
...
printf.c
浏览文件 @
a650c606
...
...
@@ -65,8 +65,8 @@ printf(int fd, char *fmt, ...)
s
++
;
}
}
else
if
(
c
==
'c'
){
putc
(
fd
,
*
ap
);
ap
++
;
putc
(
fd
,
*
ap
);
ap
++
;
}
else
if
(
c
==
'%'
){
putc
(
fd
,
c
);
}
else
{
...
...
setjmp.S
浏览文件 @
a650c606
.globl setjmp
setjmp:
movl 4(%esp), %eax
movl %ebx, 0(%eax)
movl %ecx, 4(%eax)
movl %edx, 8(%eax)
movl %esi, 12(%eax)
movl %edi, 16(%eax)
movl %esp, 20(%eax)
movl %ebp, 24(%eax)
pushl 0(%esp)
/* %eip */
popl 28(%eax)
movl $0, %eax
/* return value */
ret
movl 4(%esp), %eax
movl %ebx, 0(%eax)
movl %ecx, 4(%eax)
movl %edx, 8(%eax)
movl %esi, 12(%eax)
movl %edi, 16(%eax)
movl %esp, 20(%eax)
movl %ebp, 24(%eax)
pushl 0(%esp)
/* %eip */
popl 28(%eax)
movl $0, %eax
/* return value */
ret
.globl longjmp
longjmp:
movl 4(%esp), %eax
movl 0(%eax), %ebx
movl 4(%eax), %ecx
movl 8(%eax), %edx
movl 12(%eax), %esi
movl 16(%eax), %edi
movl 20(%eax), %esp
movl 24(%eax), %ebp
movl 4(%esp), %eax
movl 0(%eax), %ebx
movl 4(%eax), %ecx
movl 8(%eax), %edx
movl 12(%eax), %esi
movl 16(%eax), %edi
movl 20(%eax), %esp
movl 24(%eax), %ebp
addl $4, %esp
/* pop %eip into thin air */
pushl 28(%eax)
/* push new %eip */
movl $1, %eax
/* return value (appears to come from setjmp!) */
ret
addl $4, %esp
/* pop %eip into thin air */
pushl 28(%eax)
/* push new %eip */
movl $1, %eax
/* return value (appears to come from setjmp!) */
ret
sh.c
浏览文件 @
a650c606
...
...
@@ -68,28 +68,28 @@ parse(char *s)
while
(
1
)
{
switch
((
c
=
gettoken
(
0
,
&
t
)))
{
case
'w'
:
// Add an argument
case
'w'
:
// Add an argument
if
(
cmdlist
[
nextcmd
].
argc
>=
MAXARGS
)
{
printf
(
2
,
"too many arguments
\n
"
);
return
-
1
;
printf
(
2
,
"too many arguments
\n
"
);
return
-
1
;
}
cmdlist
[
nextcmd
].
argv
[
cmdlist
[
nextcmd
].
argc
++
]
=
t
;
break
;
case
'<'
:
// Input redirection
case
'<'
:
// Input redirection
// Grab the filename from the argument list
if
(
gettoken
(
0
,
&
t
)
!=
'w'
)
{
printf
(
2
,
"syntax error: < not followed by word
\n
"
);
return
-
1
;
printf
(
2
,
"syntax error: < not followed by word
\n
"
);
return
-
1
;
}
addio
(
'<'
,
t
);
break
;
case
'>'
:
// Output redirection
case
'>'
:
// Output redirection
// Grab the filename from the argument list
if
(
gettoken
(
0
,
&
t
)
!=
'w'
)
{
printf
(
2
,
"syntax error: > not followed by word
\n
"
);
return
-
1
;
printf
(
2
,
"syntax error: > not followed by word
\n
"
);
return
-
1
;
}
addio
(
'>'
,
t
);
break
;
...
...
@@ -100,13 +100,13 @@ parse(char *s)
nextcmd
++
;
break
;
case
0
:
// String is complete
case
0
:
// String is complete
return
0
;
default:
printf
(
2
,
"syntax error: bad return %d from gettoken"
,
c
);
return
-
1
;
}
}
}
...
...
@@ -136,14 +136,14 @@ runcmd(void)
cmdlist
[
c
].
argv
[
0
]
=
cmdlist
[
c
].
argv0buf
;
}
cmdlist
[
c
].
argv
[
cmdlist
[
c
].
argc
]
=
0
;
// Print the command.
if
(
debug
)
{
printf
(
2
,
"[%d] SPAWN:"
,
getpid
());
for
(
i
=
0
;
cmdlist
[
c
].
argv
[
i
];
i
++
)
printf
(
2
,
" %s"
,
cmdlist
[
c
].
argv
[
i
]);
printf
(
2
,
" %s"
,
cmdlist
[
c
].
argv
[
i
]);
for
(
i
=
0
;
i
<
nextio
;
i
++
)
{
printf
(
2
,
"%c %s"
,
iolist
[
i
].
token
,
iolist
[
i
].
s
);
printf
(
2
,
"%c %s"
,
iolist
[
i
].
token
,
iolist
[
i
].
s
);
}
printf
(
2
,
"
\n
"
);
}
...
...
@@ -156,55 +156,55 @@ runcmd(void)
if
(
cmdlist
[
c
].
token
==
'|'
)
if
(
pipe
(
fdarray
)
<
0
)
printf
(
2
,
"cmd %d pipe failed
\n
"
,
c
);
printf
(
2
,
"cmd %d pipe failed
\n
"
,
c
);
pid
=
fork
();
if
(
pid
==
0
)
{
if
(
cmdlist
[
c
].
token
==
'|'
)
{
if
(
close
(
1
)
<
0
)
printf
(
2
,
"close 1 failed
\n
"
);
if
((
tfd
=
dup
(
fdarray
[
1
]))
<
0
)
printf
(
2
,
"dup failed
\n
"
);
if
(
close
(
fdarray
[
0
])
<
0
)
printf
(
2
,
"close fdarray[0] failed
\n
"
);
if
(
close
(
fdarray
[
1
])
<
0
)
printf
(
2
,
"close fdarray[1] failed
\n
"
);
if
(
close
(
1
)
<
0
)
printf
(
2
,
"close 1 failed
\n
"
);
if
((
tfd
=
dup
(
fdarray
[
1
]))
<
0
)
printf
(
2
,
"dup failed
\n
"
);
if
(
close
(
fdarray
[
0
])
<
0
)
printf
(
2
,
"close fdarray[0] failed
\n
"
);
if
(
close
(
fdarray
[
1
])
<
0
)
printf
(
2
,
"close fdarray[1] failed
\n
"
);
}
if
(
c
>
0
&&
cmdlist
[
c
-
1
].
token
==
'|'
)
{
if
(
close
(
0
)
<
0
)
printf
(
2
,
"close 0 failed
\n
"
);
if
((
tfd
=
dup
(
fdarray
[
0
]))
<
0
)
printf
(
2
,
"dup failed
\n
"
);
if
(
close
(
fdarray
[
0
])
<
0
)
printf
(
2
,
"close fdarray[0] failed
\n
"
);
if
(
close
(
fdarray
[
1
])
<
0
)
printf
(
2
,
"close fdarray[1] failed
\n
"
);
if
(
close
(
0
)
<
0
)
printf
(
2
,
"close 0 failed
\n
"
);
if
((
tfd
=
dup
(
fdarray
[
0
]))
<
0
)
printf
(
2
,
"dup failed
\n
"
);
if
(
close
(
fdarray
[
0
])
<
0
)
printf
(
2
,
"close fdarray[0] failed
\n
"
);
if
(
close
(
fdarray
[
1
])
<
0
)
printf
(
2
,
"close fdarray[1] failed
\n
"
);
}
if
(
ioredirection
()
<
0
)
exit
();
exit
();
if
((
r
=
exec
(
cmdlist
[
c
].
argv0buf
,
(
char
**
)
cmdlist
[
c
].
argv
))
<
0
)
{
printf
(
2
,
"exec %s: %d
\n
"
,
cmdlist
[
c
].
argv
[
0
],
r
);
exit
();
printf
(
2
,
"exec %s: %d
\n
"
,
cmdlist
[
c
].
argv
[
0
],
r
);
exit
();
}
}
else
if
(
pid
>
0
)
{
int
p
;
if
(
debug
)
printf
(
2
,
"[%d] FORKED child %d
\n
"
,
getpid
(),
pid
);
printf
(
2
,
"[%d] FORKED child %d
\n
"
,
getpid
(),
pid
);
if
(
c
>
0
&&
cmdlist
[
c
-
1
].
token
==
'|'
)
{
close
(
fdarray
[
0
]);
close
(
fdarray
[
1
]);
close
(
fdarray
[
0
]);
close
(
fdarray
[
1
]);
}
if
(
cmdlist
[
c
].
token
!=
'|'
)
{
if
(
debug
)
printf
(
2
,
"[%d] WAIT for children
\n
"
,
getpid
());
do
{
p
=
wait
();
if
(
debug
)
printf
(
2
,
"[%d] WAIT child %d finished
\n
"
,
getpid
(),
p
);
}
while
(
p
>
0
);
if
(
debug
)
printf
(
2
,
"[%d] wait finished
\n
"
,
getpid
());
if
(
debug
)
printf
(
2
,
"[%d] WAIT for children
\n
"
,
getpid
());
do
{
p
=
wait
();
if
(
debug
)
printf
(
2
,
"[%d] WAIT child %d finished
\n
"
,
getpid
(),
p
);
}
while
(
p
>
0
);
if
(
debug
)
printf
(
2
,
"[%d] wait finished
\n
"
,
getpid
());
}
}
}
...
...
@@ -219,23 +219,23 @@ ioredirection(void)
switch
(
iolist
[
i
].
token
)
{
case
'<'
:
if
(
close
(
0
)
<
0
)
printf
(
2
,
"close 0 failed
\n
"
);
printf
(
2
,
"close 0 failed
\n
"
);
if
((
fd
=
open
(
iolist
[
i
].
s
,
O_RDONLY
))
<
0
)
{
printf
(
2
,
"failed to open %s for read: %d"
,
iolist
[
i
].
s
,
fd
);
return
-
1
;
printf
(
2
,
"failed to open %s for read: %d"
,
iolist
[
i
].
s
,
fd
);
return
-
1
;
}
if
(
debug
)
printf
(
2
,
"redirect 0 from %s
\n
"
,
iolist
[
i
].
s
);
printf
(
2
,
"redirect 0 from %s
\n
"
,
iolist
[
i
].
s
);
break
;
case
'>'
:
if
(
close
(
1
)
<
0
)
printf
(
2
,
"close 1 failed
\n
"
);
printf
(
2
,
"close 1 failed
\n
"
);
if
((
fd
=
open
(
iolist
[
i
].
s
,
O_WRONLY
|
O_CREATE
))
<
0
)
{
printf
(
2
,
"failed to open %s for write: %d"
,
iolist
[
i
].
s
,
fd
);
exit
();
printf
(
2
,
"failed to open %s for write: %d"
,
iolist
[
i
].
s
,
fd
);
exit
();
}
if
(
debug
)
printf
(
2
,
"redirect 1 to %s
\n
"
,
iolist
[
i
].
s
);
printf
(
2
,
"redirect 1 to %s
\n
"
,
iolist
[
i
].
s
);
break
;
}
}
...
...
@@ -283,11 +283,11 @@ gettoken(char *s, char **p1)
// Get the next token from string s.
// Set *p1 to the beginning of the token and *p2 just past the token.
// Returns
//
0 for end-of-string;
//
< for <;
//
> for >;
//
| for |;
//
w for a word.
//
0 for end-of-string;
//
< for <;
//
> for >;
//
| for |;
//
w for a word.
//
// Eventually (once we parse the space where the \0 will go),
// words get nul-terminated.
...
...
sign.pl
浏览文件 @
a650c606
...
...
@@ -5,8 +5,8 @@ open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!";
$n
=
sysread
(
SIG
,
$buf
,
1000
);
if
(
$n
>
510
){
print
STDERR
"boot block too large: $n bytes (max 510)\n"
;
exit
1
;
print
STDERR
"boot block too large: $n bytes (max 510)\n"
;
exit
1
;
}
print
STDERR
"boot block is $n bytes (max 510)\n"
;
...
...
spinlock.c
浏览文件 @
a650c606
...
...
@@ -40,7 +40,7 @@ acquire(struct spinlock * lock)
while
(
cmpxchg
(
0
,
1
,
&
lock
->
locked
)
==
1
)
;
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
getcallerpcs
(
&
lock
,
lock
->
pcs
);
lock
->
cpu
=
cpu
()
+
10
;
}
...
...
@@ -54,7 +54,7 @@ release(struct spinlock * lock)
lock
->
pcs
[
0
]
=
0
;
lock
->
cpu
=
0xffffffff
;
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
lock
->
locked
=
0
;
if
(
--
cpus
[
cpu
()].
nlock
==
0
)
sti
();
...
...
string.c
浏览文件 @
a650c606
...
...
@@ -32,7 +32,7 @@ memmove(void *dst, const void *src, uint n)
{
const
char
*
s
;
char
*
d
;
s
=
src
;
d
=
dst
;
if
(
s
<
d
&&
s
+
n
>
d
)
{
...
...
@@ -50,10 +50,10 @@ memmove(void *dst, const void *src, uint n)
int
strncmp
(
const
char
*
p
,
const
char
*
q
,
uint
n
)
{
while
(
n
>
0
&&
*
p
&&
*
p
==
*
q
)
n
--
,
p
++
,
q
++
;
if
(
n
==
0
)
return
0
;
else
return
(
int
)
((
uchar
)
*
p
-
(
uchar
)
*
q
);
while
(
n
>
0
&&
*
p
&&
*
p
==
*
q
)
n
--
,
p
++
,
q
++
;
if
(
n
==
0
)
return
0
;
else
return
(
int
)
((
uchar
)
*
p
-
(
uchar
)
*
q
);
}
trap.c
浏览文件 @
a650c606
...
...
@@ -86,7 +86,7 @@ trap(struct trapframe *tf)
if
(
curproc
[
cpu
()])
{
cprintf
(
"pid %d: unhandled trap %d on cpu %d eip %x---terminate process
\n
"
,
curproc
[
cpu
()]
->
pid
,
v
,
cpu
(),
tf
->
eip
);
curproc
[
cpu
()]
->
pid
,
v
,
cpu
(),
tf
->
eip
);
proc_exit
();
}
cprintf
(
"unexpected trap %d from cpu %d eip %x
\n
"
,
v
,
cpu
(),
tf
->
eip
);
...
...
trapasm.S
浏览文件 @
a650c606
.text
.text
.globl trap
.globl trapret1
.globl alltraps
alltraps:
/* vectors.S sends all traps here */
pushl %ds
# build
pushl %es
# trap
pushal
# frame
movl $16,%eax # SEG_KDATA << 3
movw %ax,%ds
# kernel
movw %ax,%es
# segments
pushl %esp
# pass pointer to this trapframe
call trap
# and call trap()
addl $4, %esp
# return falls through to trapret...
/*
* a forked process RETs here
* expects ESP to point to a Trapframe
*/
/* vectors.S sends all traps here */
pushl %ds
# build
pushl %es
# trap
pushal
# frame
movl $16,%eax # SEG_KDATA << 3
movw %ax,%ds
# kernel
movw %ax,%es
# segments
pushl %esp
# pass pointer to this trapframe
call trap
# and call trap()
addl $4, %esp
# return falls through to trapret...
/*
* a forked process RETs here
* expects ESP to point to a Trapframe
*/
.globl trapret
trapret:
popal
popl %es
popl %ds
addl $0x8, %esp /* trapno and errcode */
iret
popal
popl %es
popl %ds
addl $0x8, %esp /* trapno and errcode */
iret
.globl forkret1
forkret1:
movl 4(%esp), %esp
jmp trapret
.globl
acpu
movl 4(%esp), %esp
jmp trapret
.globl
acpu
acpu:
.long 0
.long 0
traps.h
浏览文件 @
a650c606
// system defined:
#define T_DIVIDE
0
// divide error
#define T_DEBUG
1
// debug exception
#define T_NMI
2
// non-maskable interrupt
#define T_BRKPT
3
// breakpoint
#define T_OFLOW
4
// overflow
#define T_BOUND
5
// bounds check
#define T_ILLOP
6
// illegal opcode
#define T_DEVICE
7
// device not available
#define T_DBLFLT
8
// double fault
/* #define T_COPROC
9 */
// reserved (not generated by recent processors)
#define T_TSS
10
// invalid task switch segment
#define T_SEGNP
11
// segment not present
#define T_STACK
12
// stack exception
#define T_GPFLT
13
// genernal protection fault
#define T_PGFLT
14
// page fault
/* #define T_RES
15 */
// reserved
#define T_FPERR
16
// floating point error
#define T_ALIGN
17
// aligment check
#define T_MCHK
18
// machine check
#define T_SIMDERR
19
// SIMD floating point error
#define T_DIVIDE
0
// divide error
#define T_DEBUG
1
// debug exception
#define T_NMI
2
// non-maskable interrupt
#define T_BRKPT
3
// breakpoint
#define T_OFLOW
4
// overflow
#define T_BOUND
5
// bounds check
#define T_ILLOP
6
// illegal opcode
#define T_DEVICE
7
// device not available
#define T_DBLFLT
8
// double fault
/* #define T_COPROC
9 */
// reserved (not generated by recent processors)
#define T_TSS
10
// invalid task switch segment
#define T_SEGNP
11
// segment not present
#define T_STACK
12
// stack exception
#define T_GPFLT
13
// genernal protection fault
#define T_PGFLT
14
// page fault
/* #define T_RES
15 */
// reserved
#define T_FPERR
16
// floating point error
#define T_ALIGN
17
// aligment check
#define T_MCHK
18
// machine check
#define T_SIMDERR
19
// SIMD floating point error
// These are arbitrarily chosen, but with care not to overlap
// processor defined exceptions or interrupt vectors.
#define T_SYSCALL
48
// system call
#define T_DEFAULT
500
// catchall
#define T_SYSCALL
48
// system call
#define T_DEFAULT
500
// catchall
#define IRQ_OFFSET 32
// IRQ 0 corresponds to int IRQ_OFFSET
#define IRQ_OFFSET 32
// IRQ 0 corresponds to int IRQ_OFFSET
#define IRQ_KBD 1
#define IRQ_KBD
1
#define IRQ_IDE 14
#define IRQ_TIMER 18
#define IRQ_ERROR 19
...
...
ulib.c
浏览文件 @
a650c606
...
...
@@ -12,20 +12,20 @@ puts(char *s)
char
*
strcpy
(
char
*
s
,
char
*
t
)
{
char
*
os
;
os
=
s
;
while
((
*
s
++
=
*
t
++
)
!=
0
)
;
return
os
;
char
*
os
;
os
=
s
;
while
((
*
s
++
=
*
t
++
)
!=
0
)
;
return
os
;
}
int
strcmp
(
const
char
*
p
,
const
char
*
q
)
{
while
(
*
p
&&
*
p
==
*
q
)
p
++
,
q
++
;
return
(
int
)
((
unsigned
char
)
*
p
-
(
unsigned
char
)
*
q
);
while
(
*
p
&&
*
p
==
*
q
)
p
++
,
q
++
;
return
(
int
)
((
unsigned
char
)
*
p
-
(
unsigned
char
)
*
q
);
}
unsigned
int
...
...
@@ -37,7 +37,7 @@ strlen(char *s)
return
n
;
}
void
*
void
*
memset
(
void
*
dst
,
int
c
,
unsigned
int
n
)
{
char
*
d
=
(
char
*
)
dst
;
...
...
@@ -48,16 +48,16 @@ memset(void *dst, int c, unsigned int n)
return
dst
;
}
char
*
char
*
strchr
(
const
char
*
s
,
char
c
)
{
for
(;
*
s
;
s
++
)
if
(
*
s
==
c
)
return
(
char
*
)
s
;
return
0
;
for
(;
*
s
;
s
++
)
if
(
*
s
==
c
)
return
(
char
*
)
s
;
return
0
;
}
char
*
char
*
gets
(
char
*
buf
,
int
max
)
{
int
i
=
0
,
cc
;
...
...
umalloc.c
浏览文件 @
a650c606
...
...
@@ -74,17 +74,17 @@ malloc(uint nbytes)
for
(
p
=
prevp
->
s
.
ptr
;
;
prevp
=
p
,
p
=
p
->
s
.
ptr
)
{
if
(
p
->
s
.
size
>=
nunits
)
{
if
(
p
->
s
.
size
==
nunits
)
prevp
->
s
.
ptr
=
p
->
s
.
ptr
;
prevp
->
s
.
ptr
=
p
->
s
.
ptr
;
else
{
p
->
s
.
size
-=
nunits
;
p
+=
p
->
s
.
size
;
p
->
s
.
size
=
nunits
;
p
->
s
.
size
-=
nunits
;
p
+=
p
->
s
.
size
;
p
->
s
.
size
=
nunits
;
}
freep
=
prevp
;
return
(
void
*
)
(
p
+
1
);
}
if
(
p
==
freep
)
if
((
p
=
morecore
(
nunits
))
==
0
)
return
0
;
return
0
;
}
}
userfs.c
浏览文件 @
a650c606
...
...
@@ -115,8 +115,8 @@ writetest1(void)
i
=
read
(
fd
,
buf
,
512
);
if
(
i
==
0
)
{
if
(
n
==
MAXFILE
-
1
)
{
printf
(
stdout
,
"read only %d blocks from big"
,
n
);
exit
();
printf
(
stdout
,
"read only %d blocks from big"
,
n
);
exit
();
}
break
;
}
else
if
(
i
!=
512
)
{
...
...
usys.S
浏览文件 @
a650c606
...
...
@@ -2,11 +2,11 @@
#include "traps.h"
#define STUB(name) \
.globl name; \
name: \
movl $SYS_ ## name, %eax; \
int $T_SYSCALL; \
ret
.globl name; \
name: \
movl $SYS_ ## name, %eax; \
int $T_SYSCALL; \
ret
STUB(fork)
STUB(exit)
...
...
vectors.pl
浏览文件 @
a650c606
...
...
@@ -13,10 +13,10 @@ for(my $i = 0; $i < 256; $i++){
print
".globl vector$i\n"
;
print
"vector$i:\n"
;
if
((
$i
<
8
||
$i
>
14
)
&&
$i
!=
17
){
print
"
\t
pushl \$0\n"
;
print
"
pushl \$0\n"
;
}
print
"
\t
pushl \$$i\n"
;
print
"
\t
jmp alltraps\n"
;
print
"
pushl \$$i\n"
;
print
"
jmp alltraps\n"
;
}
print
"\n/* vector table */\n"
;
...
...
@@ -24,5 +24,5 @@ print ".data\n";
print
".globl vectors\n"
;
print
"vectors:\n"
;
for
(
my
$i
=
0
;
$i
<
256
;
$i
++
){
print
"
\t
.long vector$i\n"
;
print
"
.long vector$i\n"
;
}
x86.h
浏览文件 @
a650c606
static
__inline
uchar
inb
(
int
port
)
{
uchar
data
;
__asm
__volatile
(
"inb %w1,%0"
:
"=a"
(
data
)
:
"d"
(
port
));
return
data
;
uchar
data
;
__asm
__volatile
(
"inb %w1,%0"
:
"=a"
(
data
)
:
"d"
(
port
));
return
data
;
}
static
__inline
void
insl
(
int
port
,
void
*
addr
,
int
cnt
)
{
__asm
__volatile
(
"cld
\n\t
repne
\n\t
insl"
:
"=D"
(
addr
),
"=c"
(
cnt
)
:
"d"
(
port
),
"0"
(
addr
),
"1"
(
cnt
)
:
"memory"
,
"cc"
);
__asm
__volatile
(
"cld
\n\t
repne
\n\t
insl"
:
"=D"
(
addr
),
"=c"
(
cnt
)
:
"d"
(
port
),
"0"
(
addr
),
"1"
(
cnt
)
:
"memory"
,
"cc"
);
}
static
__inline
void
outb
(
int
port
,
uchar
data
)
{
__asm
__volatile
(
"outb %0,%w1"
:
:
"a"
(
data
),
"d"
(
port
));
__asm
__volatile
(
"outb %0,%w1"
:
:
"a"
(
data
),
"d"
(
port
));
}
static
__inline
void
outw
(
int
port
,
ushort
data
)
{
__asm
__volatile
(
"outw %0,%w1"
:
:
"a"
(
data
),
"d"
(
port
));
__asm
__volatile
(
"outw %0,%w1"
:
:
"a"
(
data
),
"d"
(
port
));
}
static
__inline
void
outsl
(
int
port
,
const
void
*
addr
,
int
cnt
)
{
__asm
__volatile
(
"cld
\n\t
repne
\n\t
outsl"
:
"=S"
(
addr
),
"=c"
(
cnt
)
:
"d"
(
port
),
"0"
(
addr
),
"1"
(
cnt
)
:
"cc"
);
__asm
__volatile
(
"cld
\n\t
repne
\n\t
outsl"
:
"=S"
(
addr
),
"=c"
(
cnt
)
:
"d"
(
port
),
"0"
(
addr
),
"1"
(
cnt
)
:
"cc"
);
}
struct
segdesc
;
...
...
@@ -41,13 +41,13 @@ struct segdesc;
static
__inline
void
lgdt
(
struct
segdesc
*
p
,
int
size
)
{
volatile
ushort
pd
[
3
];
volatile
ushort
pd
[
3
];
pd
[
0
]
=
size
-
1
;
pd
[
1
]
=
(
uint
)
p
;
pd
[
2
]
=
(
uint
)
p
>>
16
;
pd
[
0
]
=
size
-
1
;
pd
[
1
]
=
(
uint
)
p
;
pd
[
2
]
=
(
uint
)
p
>>
16
;
asm
volatile
(
"lgdt (%0)"
:
:
"g"
(
pd
));
asm
volatile
(
"lgdt (%0)"
:
:
"g"
(
pd
));
}
struct
gatedesc
;
...
...
@@ -55,99 +55,99 @@ struct gatedesc;
static
__inline
void
lidt
(
struct
gatedesc
*
p
,
int
size
)
{
volatile
ushort
pd
[
3
];
volatile
ushort
pd
[
3
];
pd
[
0
]
=
size
-
1
;
pd
[
1
]
=
(
uint
)
p
;
pd
[
2
]
=
(
uint
)
p
>>
16
;
pd
[
0
]
=
size
-
1
;
pd
[
1
]
=
(
uint
)
p
;
pd
[
2
]
=
(
uint
)
p
>>
16
;
asm
volatile
(
"lidt (%0)"
:
:
"g"
(
pd
));
asm
volatile
(
"lidt (%0)"
:
:
"g"
(
pd
));
}
static
__inline
void
ltr
(
ushort
sel
)
{
__asm
__volatile
(
"ltr %0"
:
:
"r"
(
sel
));
__asm
__volatile
(
"ltr %0"
:
:
"r"
(
sel
));
}
static
__inline
uint
read_eflags
(
void
)
{
uint
eflags
;
__asm
__volatile
(
"pushfl; popl %0"
:
"=r"
(
eflags
));
return
eflags
;
uint
eflags
;
__asm
__volatile
(
"pushfl; popl %0"
:
"=r"
(
eflags
));
return
eflags
;
}
static
__inline
void
write_eflags
(
uint
eflags
)
{
__asm
__volatile
(
"pushl %0; popfl"
:
:
"r"
(
eflags
));
__asm
__volatile
(
"pushl %0; popfl"
:
:
"r"
(
eflags
));
}
static
__inline
void
cpuid
(
uint
info
,
uint
*
eaxp
,
uint
*
ebxp
,
uint
*
ecxp
,
uint
*
edxp
)
{
uint
eax
,
ebx
,
ecx
,
edx
;
asm
volatile
(
"cpuid"
:
"=a"
(
eax
),
"=b"
(
ebx
),
"=c"
(
ecx
),
"=d"
(
edx
)
:
"a"
(
info
));
if
(
eaxp
)
*
eaxp
=
eax
;
if
(
ebxp
)
*
ebxp
=
ebx
;
if
(
ecxp
)
*
ecxp
=
ecx
;
if
(
edxp
)
*
edxp
=
edx
;
uint
eax
,
ebx
,
ecx
,
edx
;
asm
volatile
(
"cpuid"
:
"=a"
(
eax
),
"=b"
(
ebx
),
"=c"
(
ecx
),
"=d"
(
edx
)
:
"a"
(
info
));
if
(
eaxp
)
*
eaxp
=
eax
;
if
(
ebxp
)
*
ebxp
=
ebx
;
if
(
ecxp
)
*
ecxp
=
ecx
;
if
(
edxp
)
*
edxp
=
edx
;
}
static
__inline
uint
cmpxchg
(
uint
oldval
,
uint
newval
,
volatile
uint
*
lock_addr
)
{
uint
result
;
__asm__
__volatile__
(
"lock; cmpxchgl %2, %0"
:
"+m"
(
*
lock_addr
),
"=a"
(
result
)
:
"r"
(
newval
),
"1"
(
oldval
)
:
"cc"
);
__asm__
__volatile__
(
"lock; cmpxchgl %2, %0"
:
"+m"
(
*
lock_addr
),
"=a"
(
result
)
:
"r"
(
newval
),
"1"
(
oldval
)
:
"cc"
);
return
result
;
}
static
__inline
void
cli
(
void
)
{
__asm__
volatile
(
"cli"
);
__asm__
volatile
(
"cli"
);
}
static
__inline
void
sti
(
void
)
{
__asm__
volatile
(
"sti"
);
__asm__
volatile
(
"sti"
);
}
struct
trapframe
{
/* registers as pushed by pusha */
uint
edi
;
uint
esi
;
uint
ebp
;
uint
oesp
;
/* Useless */
uint
ebx
;
uint
edx
;
uint
ecx
;
uint
eax
;
/* rest of trap frame */
ushort
es
;
ushort
padding1
;
ushort
ds
;
ushort
padding2
;
uint
trapno
;
/* below here defined by x86 hardware */
uint
err
;
uint
eip
;
ushort
cs
;
ushort
padding3
;
uint
eflags
;
/* below here only when crossing rings, such as from user to kernel */
uint
esp
;
ushort
ss
;
ushort
padding4
;
/* registers as pushed by pusha */
uint
edi
;
uint
esi
;
uint
ebp
;
uint
oesp
;
/* Useless */
uint
ebx
;
uint
edx
;
uint
ecx
;
uint
eax
;
/* rest of trap frame */
ushort
es
;
ushort
padding1
;
ushort
ds
;
ushort
padding2
;
uint
trapno
;
/* below here defined by x86 hardware */
uint
err
;
uint
eip
;
ushort
cs
;
ushort
padding3
;
uint
eflags
;
/* below here only when crossing rings, such as from user to kernel */
uint
esp
;
ushort
ss
;
ushort
padding4
;
};
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论