gdt idt init

This commit is contained in:
icexin committed 2021-07-23 00:33:39 +08:00
1 parent b60e68db79
commit 77bb25440a
11 files changed
+3335 -2

No files matched your search

+1
View File
@@ -3,6 +3,7 @@
#file mutiboot.elf
#set architecture i386:x86-64
#target remote :1234
display/i $pc
define xbt
set $tid=$arg0
+2 -1
View File
@@ -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}",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"go.toolsEnvVars": {
"GOOS": "linux",
"GOARCH": "386",
"GOARCH": "amd64",
},
}
+36
View File
@@ -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
+65
View File
@@ -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()
}
+7
View File
@@ -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 {
+89
View File
@@ -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)))
}
+23
View File
@@ -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")
}
+45
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+2037
View File
File diff suppressed because it is too large. Load diff