- 去掉不再需要的 import t, c - class → struct(纯数据聚合) - t.CArray[T, N] → [N]T - static 修饰符移到类型前 - @__attribute(packed) → @__attribute__(packed) - UHCI 中断回调参数改用 callable[[], int] - 同步 CPUID 注释中的旧类型名
153 lines
5.4 KiB
Plaintext
153 lines
5.4 KiB
Plaintext
@__attribute__(packed)
|
||
struct gdt_entry:
|
||
limit_low: uint16
|
||
base_low: uint16
|
||
base_middle: uint8
|
||
access: uint8
|
||
granularity: uint8
|
||
base_high: uint8
|
||
|
||
@__attribute__(packed)
|
||
struct gdt_entry64:
|
||
limit_low: uint16
|
||
base_low: uint16
|
||
base_middle: uint8
|
||
access: uint8
|
||
granularity: uint8
|
||
base_high: uint8
|
||
base_upper: uint32
|
||
reserved: uint32
|
||
|
||
@__attribute__(packed)
|
||
struct gdt_ptr:
|
||
limit: uint16
|
||
base: uint64
|
||
|
||
export gdt: [8]gdt_entry = []
|
||
export gp: [10]uint8 = []
|
||
# TSS buffer: 104 bytes, raw byte array to avoid packed struct issues
|
||
# x86_64 TSS layout: reserved0(4) rsp0(8) rsp1(8) rsp2(8) reserved1(8) ist1-ist7(56) reserved2(8) reserved3(2) iomap_base(2)
|
||
export tss_buf: [104]uint8
|
||
|
||
# 选择子布局(**必须与 SYSRET 的硬性要求一致**:SYSRET 加载 CS = STAR[63:48]+16、SS = +8,
|
||
# 且 cs_sel 必须正好是 ss_sel 上面 8 字节;STAR[63:48] 在 syscall.vp 里是 0x1B):
|
||
# 0x08 内核代码 0x10 内核数据
|
||
# 0x20 用户数据(USER_DATA_SEG) 0x28 用户代码(USER_CODE_SEG) ← 0x28 = 0x1B+16 ✓ / 0x20 = 0x1B+8 ✓
|
||
# 0x30 TSS(16 字节描述符,占 GDT 第 6/7 项)
|
||
# 注:gdt[3](0x18)保留一份同样的用户代码描述符作兼容镜像 —— 早期路径曾用 0x1B iretq 进用户态。
|
||
define CODE_SEG: uint16 = 0x08
|
||
define DATA_SEG: uint16 = 0x10
|
||
define USER_CODE_SEG: uint16 = 0x28
|
||
define USER_DATA_SEG: uint16 = 0x20
|
||
define TSS_SEG: uint16 = 0x30
|
||
|
||
|
||
def init():
|
||
global gp, gdt, tss_buf
|
||
gdt[0].limit_low = 0
|
||
gdt[0].base_low = 0
|
||
gdt[0].base_middle = 0
|
||
gdt[0].access = 0
|
||
gdt[0].granularity = 0
|
||
gdt[0].base_high = 0
|
||
gdt[1].limit_low = 0
|
||
gdt[1].base_low = 0
|
||
gdt[1].base_middle = 0
|
||
gdt[1].access = 0x9A
|
||
gdt[1].granularity = 0x20
|
||
gdt[1].base_high = 0
|
||
gdt[2].limit_low = 0
|
||
gdt[2].base_low = 0
|
||
gdt[2].base_middle = 0
|
||
gdt[2].access = 0x92
|
||
gdt[2].granularity = 0xCF
|
||
gdt[2].base_high = 0
|
||
gdt[3].limit_low = 0
|
||
gdt[3].base_low = 0
|
||
gdt[3].base_middle = 0
|
||
gdt[3].access = 0xFA
|
||
gdt[3].granularity = 0x20
|
||
gdt[3].base_high = 0
|
||
gdt[4].limit_low = 0
|
||
gdt[4].base_low = 0
|
||
gdt[4].base_middle = 0
|
||
gdt[4].access = 0xF2
|
||
gdt[4].granularity = 0xCF
|
||
gdt[4].base_high = 0
|
||
# 用户代码段必须落在第 5 项(选择子 0x28):sysretq 返回用户态时硬件按 STAR[63:48]+16 算 CS=0x2B,
|
||
# SS=0x23(第 4 项用户数据)—— 若第 5 项不是代码段,严格实现会在 SYSRET 处 #GP(QEMU 不校验才长期没暴露)。
|
||
gdt[5].limit_low = 0
|
||
gdt[5].base_low = 0
|
||
gdt[5].base_middle = 0
|
||
gdt[5].access = 0xFA
|
||
gdt[5].granularity = 0x20
|
||
gdt[5].base_high = 0
|
||
# Set up TSS descriptor in GDT entries 6-7 (selector 0x30)
|
||
setTSS64(6, uint64(&tss_buf), 103)
|
||
__asm__("""lea rax, [rip + gdt]
|
||
lea rcx, [rip + gp]
|
||
mov word ptr [rcx], 0x3F
|
||
mov qword ptr [rcx+2], rax""",
|
||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RAX, ASM_DESCR.CLOBBER_RCX])
|
||
__asm__("sfence; mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
|
||
flush()
|
||
# Initialize TSS: set iomap_base = 104 (0x68) at offset 102
|
||
tss_buf[102] = 0x68
|
||
tss_buf[103] = 0x00
|
||
# Load Task Register with TSS selector 0x30 (GDT entries 6-7)
|
||
__asm__("""mov ax, 0x30
|
||
ltr ax""",
|
||
op=[ASM_DESCR.CLOBBER_RAX])
|
||
|
||
@__attribute__(naked)
|
||
def flush():
|
||
__asm__("""lea rax, [rip + gp]
|
||
lgdt [rax]
|
||
push 0x08
|
||
lea rax, [rip+2f]
|
||
push rax
|
||
.byte 0x48, 0xcb
|
||
2:
|
||
mov eax, 0x10
|
||
mov ds, eax
|
||
mov es, eax
|
||
mov fs, eax
|
||
mov gs, eax
|
||
mov ss, eax
|
||
ret""", op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RAX])
|
||
|
||
def set_tss_rsp0(rsp0: uint64):
|
||
global tss_buf
|
||
# TSS RSP0 is at offset 4 (8 bytes) in x86_64 TSS layout
|
||
tss_buf[4] = uint8(rsp0 & 0xFF)
|
||
tss_buf[5] = uint8((rsp0 >> 8) & 0xFF)
|
||
tss_buf[6] = uint8((rsp0 >> 16) & 0xFF)
|
||
tss_buf[7] = uint8((rsp0 >> 24) & 0xFF)
|
||
tss_buf[8] = uint8((rsp0 >> 32) & 0xFF)
|
||
tss_buf[9] = uint8((rsp0 >> 40) & 0xFF)
|
||
tss_buf[10] = uint8((rsp0 >> 48) & 0xFF)
|
||
tss_buf[11] = uint8((rsp0 >> 56) & 0xFF)
|
||
|
||
def setGate(num: int, base: uint64, limit: uint32, access: uint8, gran: uint8):
|
||
global gdt
|
||
gdt[num].limit_low = uint16(limit & 0xFFFF)
|
||
gdt[num].base_low = uint16(base & 0xFFFF)
|
||
gdt[num].base_middle = uint8((base >> 16) & 0xFF)
|
||
gdt[num].base_high = uint8((base >> 24) & 0xFF)
|
||
gdt[num].granularity = uint8((limit >> 16) & 0x0F) | (gran & 0xF0)
|
||
gdt[num].access = uint8(access)
|
||
|
||
def setTSS64(num: int, base: uint64, limit: uint32):
|
||
global gdt
|
||
# 64 位 TSS 描述符占 16 字节(GDT 两项),复用同一地址按 gdt_entry64 整体写入:
|
||
# 前 8 字节为常规描述符字段,后 8 字节为 base[63:32] + 保留 0
|
||
e: gdt_entry64* = gdt_entry64*(&gdt[num])
|
||
e.limit_low = uint16(limit & 0xFFFF)
|
||
e.base_low = uint16(base & 0xFFFF)
|
||
e.base_middle = uint8((base >> 16) & 0xFF)
|
||
e.access = 0x89
|
||
e.granularity = uint8((limit >> 16) & 0x0F)
|
||
e.base_high = uint8((base >> 24) & 0xFF)
|
||
e.base_upper = uint32(base >> 32)
|
||
e.reserved = 0
|