mirror of
https://github.com/bdnugget/eggos.git
synced 2026-11-07 04:17:27 +00:00
gdt idt init
This commit is contained in:
1 parent
b60e68db79
commit
77bb25440a
11 files changed
+3335
-2
No files matched your search
@@ -3,6 +3,7 @@
|
||||
#file mutiboot.elf
|
||||
#set architecture i386:x86-64
|
||||
#target remote :1234
|
||||
display/i $pc
|
||||
|
||||
define xbt
|
||||
set $tid=$arg0
|
||||
|
||||
Vendored
+2
-1
@@ -22,7 +22,8 @@
|
||||
"request": "attach",
|
||||
"name": "Attach to qemu",
|
||||
// "executable": "./multiboot.elf",
|
||||
"executable": "./boot64.elf",
|
||||
// "executable": "./boot64.elf",
|
||||
"executable": "./kernel.elf",
|
||||
"target": ":1234",
|
||||
"remote": true,
|
||||
"cwd": "${workspaceRoot}",
|
||||
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"go.toolsEnvVars": {
|
||||
"GOOS": "linux",
|
||||
"GOARCH": "386",
|
||||
"GOARCH": "amd64",
|
||||
},
|
||||
}
|
||||
@@ -12,3 +12,39 @@ TEXT ·rt0(SB), NOSPLIT, $0-0
|
||||
TEXT ·go_entry(SB), NOSPLIT, $0
|
||||
JMP _rt0_amd64_linux(SB)
|
||||
|
||||
TEXT ·sseInit(SB), NOSPLIT, $0
|
||||
MOVL CR0, AX
|
||||
ANDW $0xFFFB, AX
|
||||
ORW $0x2, AX
|
||||
MOVL AX, CR0
|
||||
MOVL CR4, AX
|
||||
ORW $3<<9, AX
|
||||
MOVL AX, CR4
|
||||
RET
|
||||
|
||||
TEXT ·lgdt(SB), NOSPLIT, $0-8
|
||||
MOVQ gdtptr+0(FP), AX
|
||||
LGDT (AX)
|
||||
RET
|
||||
|
||||
TEXT ·lidt(SB), NOSPLIT, $0-8
|
||||
MOVQ idtptr+0(FP), AX
|
||||
LIDT (AX)
|
||||
RET
|
||||
|
||||
TEXT ·reloadCS(SB), NOSPLIT, $0
|
||||
// save ip
|
||||
MOVQ 0(SP), AX
|
||||
// save sp
|
||||
MOVQ SP, BX
|
||||
ADDQ $8, BX
|
||||
|
||||
// rerange the stack, as in an interrupt stack
|
||||
PUSHQ $0x10 // SS
|
||||
PUSHQ BX
|
||||
PUSHFQ
|
||||
PUSHQ $8
|
||||
PUSHQ AX
|
||||
|
||||
// IRET
|
||||
IRETQ
|
||||
@@ -0,0 +1,65 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
)
|
||||
|
||||
func hasErrCode(idx int) bool {
|
||||
return idx == 8 || (idx >= 10 && idx <= 14) || idx == 17
|
||||
}
|
||||
|
||||
func genasm() {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.WriteString("// Code generated by genvector.go using 'go generate'. DO NOT EDIT.\n")
|
||||
buf.WriteString(`#include "textflag.h"`)
|
||||
buf.WriteString("\n\n")
|
||||
for i := 0; i < 256; i++ {
|
||||
fmt.Fprintf(buf, "TEXT ·trap%d(SB), NOSPLIT, $0-0\n", i)
|
||||
if !hasErrCode(i) {
|
||||
buf.WriteString(" PUSHQ $0\n")
|
||||
}
|
||||
fmt.Fprintf(buf, " PUSHQ $%d\n", i)
|
||||
buf.WriteString(" JMP alltraps(SB)\n")
|
||||
buf.WriteString(" POPQ AX\n")
|
||||
if !hasErrCode(i) {
|
||||
buf.WriteString(" POPQ AX\n")
|
||||
}
|
||||
buf.WriteString(" RET\n\n")
|
||||
}
|
||||
err := ioutil.WriteFile("vectors.s", buf.Bytes(), 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func gengo() {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.WriteString("// Code generated by genvector.go using 'go generate'. DO NOT EDIT.\n")
|
||||
buf.WriteString("package kernel64\n\n")
|
||||
for i := 0; i < 256; i++ {
|
||||
fmt.Fprintf(buf, "//go:nosplit\n")
|
||||
fmt.Fprintf(buf, "func trap%d()\n", i)
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
|
||||
buf.WriteString("var vectors = [...]func(){\n")
|
||||
for i := 0; i < 256; i++ {
|
||||
fmt.Fprintf(buf, "trap%d,\n", i)
|
||||
}
|
||||
buf.WriteString("}\n\n")
|
||||
|
||||
err := ioutil.WriteFile("vectors.go", buf.Bytes(), 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
genasm()
|
||||
gengo()
|
||||
}
|
||||
@@ -8,8 +8,15 @@ func rt0()
|
||||
//go:nosplit
|
||||
func go_entry()
|
||||
|
||||
//go:nosplit
|
||||
func sseInit()
|
||||
|
||||
//go:nosplit
|
||||
func preinit() {
|
||||
sseInit()
|
||||
gdtInit()
|
||||
idtInit()
|
||||
uart.PreInit()
|
||||
uart.WriteString("kernel64\n")
|
||||
go_entry()
|
||||
for {
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package kernel64
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/icexin/eggos/sys"
|
||||
)
|
||||
|
||||
const (
|
||||
segDplKernel = 0x00
|
||||
segDplUser = 0x60
|
||||
)
|
||||
|
||||
var (
|
||||
gdt [5]gdtSegDesc
|
||||
gdtptr [10]byte
|
||||
|
||||
idt [256]idtSetDesc
|
||||
idtptr [10]byte
|
||||
)
|
||||
|
||||
type gdtSegDesc [8]byte
|
||||
|
||||
type idtSetDesc struct {
|
||||
Addr1 uint16
|
||||
Selector uint16
|
||||
Attr uint16
|
||||
Addr2 uint16
|
||||
Addr3 uint32
|
||||
Reserved uint32
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func lgdt(gdtptr uintptr)
|
||||
|
||||
//go:nosplit
|
||||
func lidt(idtptr uintptr)
|
||||
|
||||
//go:nosplit
|
||||
func reloadCS()
|
||||
|
||||
//go:nosplit
|
||||
func setGdtCodeDesc(desc *gdtSegDesc, dpl uint8) {
|
||||
desc[5] |= dpl | 0x98 // P=1 C=0
|
||||
desc[6] |= 0x20 // D=0 L=1
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func setGdtDataDesc(desc *gdtSegDesc, dpl uint8) {
|
||||
desc[5] |= dpl | 0x92 // P=1 W=1
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func gdtInit() {
|
||||
// leave gdt[0] untouch
|
||||
setGdtCodeDesc(&gdt[1], segDplKernel)
|
||||
setGdtDataDesc(&gdt[2], segDplKernel)
|
||||
setGdtCodeDesc(&gdt[3], segDplUser)
|
||||
setGdtDataDesc(&gdt[4], segDplUser)
|
||||
|
||||
limit := (*uint16)(unsafe.Pointer(&gdtptr[0]))
|
||||
base := (*uint64)(unsafe.Pointer(&gdtptr[2]))
|
||||
*limit = uint16(unsafe.Sizeof(gdt) - 1)
|
||||
*base = uint64(uintptr(unsafe.Pointer(&gdt[0])))
|
||||
lgdt(uintptr(unsafe.Pointer(&gdtptr[0])))
|
||||
reloadCS()
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func setIdtDesc(desc *idtSetDesc, addr uintptr) {
|
||||
desc.Addr1 = uint16(addr & 0xffff)
|
||||
desc.Selector = 8
|
||||
desc.Attr = 0x8e00 // P=1 TYPE=e interrupt gate
|
||||
desc.Addr2 = uint16(addr >> 16 & 0xffff)
|
||||
desc.Addr3 = uint32(addr>>32) & 0xffffffff
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func idtInit() {
|
||||
for i := 0; i < 256; i++ {
|
||||
setIdtDesc(&idt[i], sys.FuncPC(vectors[i]))
|
||||
}
|
||||
|
||||
limit := (*uint16)(unsafe.Pointer(&idtptr[0]))
|
||||
base := (*uint64)(unsafe.Pointer(&idtptr[2]))
|
||||
*limit = uint16(unsafe.Sizeof(idt) - 1)
|
||||
*base = uint64(uintptr(unsafe.Pointer(&idt[0])))
|
||||
lidt(uintptr(unsafe.Pointer(&idtptr)))
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package kernel64
|
||||
|
||||
import "github.com/icexin/eggos/uart"
|
||||
|
||||
type trapFrame struct {
|
||||
AX, BX, CX, DX uintptr
|
||||
BP, SI, DI, R8 uintptr
|
||||
R9, R10, R11, R12 uintptr
|
||||
R13, R14, R15 uintptr
|
||||
|
||||
Trapno, Err uintptr
|
||||
|
||||
// pushed by hardward
|
||||
IP, CS, FLAGS, SP, SS uintptr
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func trapret()
|
||||
|
||||
//go:nosplit
|
||||
func dotrap(tf *trapFrame) {
|
||||
uart.WriteString("trap\n")
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT alltraps(SB), NOSPLIT, $0
|
||||
PUSHQ R15
|
||||
PUSHQ R14
|
||||
PUSHQ R13
|
||||
PUSHQ R12
|
||||
PUSHQ R11
|
||||
PUSHQ R10
|
||||
PUSHQ R9
|
||||
PUSHQ R8
|
||||
PUSHQ DI
|
||||
PUSHQ SI
|
||||
PUSHQ BP
|
||||
PUSHQ DX
|
||||
PUSHQ CX
|
||||
PUSHQ BX
|
||||
PUSHQ AX
|
||||
|
||||
PUSHQ SP
|
||||
CALL ·dotrap(SB)
|
||||
ADDQ $8, SP
|
||||
JMP ·trapret(SB)
|
||||
|
||||
TEXT ·trapret(SB), NOSPLIT, $0
|
||||
POPQ AX
|
||||
POPQ BX
|
||||
POPQ CX
|
||||
POPQ DX
|
||||
POPQ BP
|
||||
POPQ SI
|
||||
POPQ DI
|
||||
POPQ R8
|
||||
POPQ R9
|
||||
POPQ R10
|
||||
POPQ R11
|
||||
POPQ R12
|
||||
POPQ R13
|
||||
POPQ R14
|
||||
POPQ R15
|
||||
|
||||
ADDL $16, SP // skip trapno and errcode
|
||||
|
||||
IRETQ
|
||||
|
||||
+1029
File diff suppressed because it is too large.
Load diff
+2037
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user