根因:bootloader 只按 kernel 文件大小 AllocatePages(.bss 不占文件),于是 .bss 尾部(ticks/_perf_* 等全局量)与主线程栈区(0x60000~0x80000)在 memmap 里仍是 EfiConventionalMemory,被内核 mm 的堆 arena 当作空闲内存占用 → 内核全局量被写坏、 堆元数据被反向破坏,最终桌面线程栈上的 va_list 被改坏,vsnprintf 读 %d 变参时 #GP(rip=0x130d45, err=0x0)。 - linker.ld: .bss 末尾加 LONG(0) 强制 PROGBITS,使 kernel.bin 的 FileSize 涵盖 .bss,bootloader 的 PagesNeeded 得以预留整块内核镜像(含 .bss) - mm.init: 新增 KernelAddr/KernelEnd,挑 arena 时把与内核镜像 [kernel_PhysAddr, __bss_end) 重叠的 region 起点抬到镜像末端(不整段丢弃) - main.vp: 取 __bss_end 并传入 mm.init - boot.c: ExitBootServices 前用 AllocatePages(AllocateAddress, EfiLoaderData) 占位内核栈区 0x60000~0x80000,使其在 memmap 中标记已用 另含在途整理:多处补显式收窄转换(uint8()/uint16() 等)、kbd_svc 构造改为 kbd_svc.__init__() 等。
50 lines
1.2 KiB
Plaintext
50 lines
1.2 KiB
Plaintext
import drivers.input.keyboard.keyboard as keyboard
|
|
import drivers.usb.hid.usb_kbd as usb_kbd
|
|
import drivers.serial.uart.serial as serial
|
|
import sched.sched as sched
|
|
|
|
|
|
define SERVICE_KEYBOARD = 1
|
|
|
|
class KeyboardService:
|
|
th: sched.Thread*
|
|
running: int
|
|
usb_kbd_th: sched.Thread*
|
|
|
|
def __init__(self):
|
|
self.th = None
|
|
self.running = 0
|
|
self.usb_kbd_th = None
|
|
|
|
|
|
def kbd_thread(arg: rawptr) -> int:
|
|
serial.puts("[kbd_svc] started\n")
|
|
while True:
|
|
if keyboard.has_data():
|
|
sc: uint8 = keyboard.read_scancode()
|
|
else:
|
|
sched.Scheduler._yield()
|
|
return 0
|
|
|
|
def usb_kbd_thread(arg: rawptr) -> int:
|
|
serial.puts("[usb_kbd_svc] started\n")
|
|
evt: usb_kbd.usb_kbd_event
|
|
while True:
|
|
if usb_kbd.has_data():
|
|
usb_kbd.read_event(&evt)
|
|
else:
|
|
sched.Scheduler._yield()
|
|
return 0
|
|
|
|
|
|
kbd_svc: KeyboardService = KeyboardService()
|
|
|
|
def start() -> int:
|
|
global kbd_svc
|
|
kbd_svc.__init__()
|
|
keyboard.init()
|
|
serial.puts("[kbd_svc] PS/2 keyboard initialized, IRQ1 installed\n")
|
|
usb_kbd.init()
|
|
kbd_svc.running = 1
|
|
return 0
|