diff --git a/VKernel/Kernel/drivers/core/cpu/cpu.vp b/VKernel/Kernel/drivers/core/cpu/cpu.vp index f4e07f6..72cb861 100644 --- a/VKernel/Kernel/drivers/core/cpu/cpu.vp +++ b/VKernel/Kernel/drivers/core/cpu/cpu.vp @@ -215,7 +215,7 @@ class _CPUObject: string.memset(&self.tss, 0, self.tss.__sizeof__()) self.tss.io_map_base = self.tss.__sizeof__() string.memset(&_per_cpu, 0, per_cpu_data.__sizeof__()) - gdt.setTSS64(5, uint64(&self.tss), self.tss.__sizeof__() - 1) + gdt.setTSS64(5, uint64(&self.tss), int(self.tss.__sizeof__() - 1)) gdt.flush() # IA32_KERNEL_GS_BASE holds the per_cpu address for swapgs. # When entering from Ring 3, swapgs swaps IA32_GS_BASE (0) with @@ -245,7 +245,7 @@ class _CPUObject: # 下标按字节偏移且被截断为 i8(只写低字节、偏移不乘 4)。 brand_addr: uint64 = uint64(uint32*(info.brand_string)) for i in range(3): - cpuid(0x80000002 + i, &res) + cpuid(int(0x80000002 + i), &res) off_b: uint64 = uint64(i) * 16 *(uint32*(brand_addr + off_b + 0)) = res.eax *(uint32*(brand_addr + off_b + 4)) = res.ebx diff --git a/VKernel/Kernel/drivers/devfs/devfs.vp b/VKernel/Kernel/drivers/devfs/devfs.vp index 62787fa..4c96c43 100644 --- a/VKernel/Kernel/drivers/devfs/devfs.vp +++ b/VKernel/Kernel/drivers/devfs/devfs.vp @@ -62,7 +62,7 @@ class devfs_directory: for d in range(directory_count): dirp: devfs_directory = &directories[d] if dirp.parent == dir_ptr: - name_len: int = string.strlen(dirp.name) + name_len: int = int(string.strlen(dirp.name)) if pos + name_len + 1 > size: break string.strcpy(buffer + pos, dirp.name) @@ -90,7 +90,7 @@ virtual class devfs_file: for f in range(file_count): filep: devfs_file* = &files[f] if filep.parent_dir == dir_ptr: - name_len: int = string.strlen(filep.name) + name_len: int = int(string.strlen(filep.name)) if pos + name_len + 1 > size: break string.strcpy(buffer + pos, filep.name) @@ -115,8 +115,8 @@ class _DevFSObject: directory_count = 0 file_count = 0 string.memset(&directories, 0, devfs_directory.__sizeof__() * MAX_DIRECTORIES) - string.memset(&files, 0, devfs_file.__sizeof__() * MAX_DEVICE_FILES) - string.memset(&fd_table, 0, _fd_table.__sizeof__() * MAX_FILE_DESCRIPTORS) + string.memset(&files, 0, devfs_file.__sizeof__() * MAX_DEVICE_FILES) + string.memset(&fd_table, 0, _fd_table.__sizeof__() * MAX_FILE_DESCRIPTORS) def create_single_dir(self, parent: devfs_directory*, dir_name: const str) -> devfs_directory*: global directory_count @@ -283,14 +283,12 @@ class _DevFSObject: return pos -DevFSObject: _DevFSObject* -_DevFSObject_instance: _DevFSObject +DevFSObject: _DevFSObject* = _DevFSObject() def devfs_init() -> int: - global DevFSObject, _DevFSObject_instance - DevFSObject = &_DevFSObject_instance - _DevFSObject_instance = _DevFSObject() + global DevFSObject + DevFSObject.__init__() DevFSObject.init() return 0 @@ -318,7 +316,7 @@ def devfs_ioctl(fd: int, cmd: uint32, arg: rawptr) -> int: def devfs_list_directory(path: const str, buffer: str, size: uint32) -> int: return DevFSObject.list_directory(path, buffer, size) -serial0_file: devfs_file +serial0_file: devfs_file* = devfs_file() def serial0_open(self: rawptr, path: const str, flags: int) -> int: serial.puts("[serial0] open: ") @@ -342,7 +340,7 @@ def serial0_write(self: rawptr, fd: int, buffer: const rawptr, size: uint32) -> def devfs_register_serial0() -> int: global serial0_file - serial0_file = devfs_file() + serial0_file.__init__() serial0_file.open = serial0_open serial0_file.close = serial0_close serial0_file.read = serial0_read @@ -371,11 +369,11 @@ virtual class serial1_device(devfs_file): serial.puts("\n") return size -serial1_file: serial1_device +serial1_file: serial1_device* = serial1_device() def devfs_register_serial1() -> int: global serial1_file - serial1_file = serial1_device() + serial1_file.__init__() return devfs_create_file("/dev/serial1", serial1_file, None) import drivers.input.keyboard.keyboard as keyboard @@ -405,11 +403,11 @@ virtual class keyboard_device(devfs_file): def ioctl(self, fd: int, request: int, arg: rawptr) -> int: return 0 -kbd_file: keyboard_device +kbd_file: keyboard_device* = keyboard_device() def devfs_register_keyboard() -> int: global kbd_file - kbd_file = keyboard_device() + kbd_file.__init__() keyboard.init() return devfs_create_file("/dev/input/keyboard", kbd_file, None) @@ -441,10 +439,10 @@ virtual class mouse_device(devfs_file): def ioctl(self, fd: int, request: int, arg: rawptr) -> int: return 0 -mse_file: mouse_device +mse_file: mouse_device* = mouse_device() def devfs_register_mouse() -> int: global mse_file - mse_file = mouse_device() + mse_file.__init__() mouse.init() return devfs_create_file("/dev/input/mouse", mse_file, None) diff --git a/VKernel/Kernel/drivers/fs/fat32/fat32_time.vp b/VKernel/Kernel/drivers/fs/fat32/fat32_time.vp index ebdb0ce..c66dcef 100644 --- a/VKernel/Kernel/drivers/fs/fat32/fat32_time.vp +++ b/VKernel/Kernel/drivers/fs/fat32/fat32_time.vp @@ -10,7 +10,7 @@ def cmos_read(reg: uint8) -> uint8: return asm.inb(rtc_cmos_data) def bcd_to_bin(bcd: uint8) -> uint8: - return (bcd >> 4) * 10 + (bcd & 0x0F) + return uint8((bcd >> 4) * 10 + (bcd & 0x0F)) def get_rtc_time() -> uint32: while cmos_read(0x0A) & 0x80: pass @@ -28,17 +28,17 @@ def get_rtc_time() -> uint32: day = bcd_to_bin(day) mon = bcd_to_bin(mon) year = bcd_to_bin(year) - fat_year: uint16 = uint16(year) + 2000 - 1980 + fat_year: uint16 = uint16(uint16(year) + 2000 - 1980) if fat_year > 127: fat_year = 127 - fat_date: uint16 = (fat_year << 9) | (uint16(mon) << 5) | uint16(day) - fat_time: uint16 = (uint16(hour) << 11) | (uint16(min_) << 5) | (uint16(sec) / 2) + fat_date: uint16 = uint16((fat_year << 9) | (uint16(mon) << 5) | uint16(day)) + fat_time: uint16 = uint16((uint16(hour) << 11) | (uint16(min_) << 5) | (uint16(sec) / 2)) return (uint32(fat_date) << 16) | uint32(fat_time) def get_fattime() -> uint32: return get_rtc_time() def to_year(ft: uint32) -> uint16: - return uint16((ft >> 25) & 0x7F) + 1980 + return uint16(uint16((ft >> 25) & 0x7F) + 1980) def to_month(ft: uint32) -> uint8: return uint8((ft >> 21) & 0x0F) @@ -56,8 +56,8 @@ def to_second(ft: uint32) -> uint8: return uint8((ft & 0x1F) * 2) def make(year: uint16, month: uint8, day: uint8, hour: uint8, minute: uint8, second: uint8) -> uint32: - fat_year: uint16 = year - 1980 + fat_year: uint16 = uint16(year - 1980) if fat_year > 127: fat_year = 127 - fat_date: uint16 = (fat_year << 9) | (uint16(month) << 5) | uint16(day) - fat_time: uint16 = (uint16(hour) << 11) | (uint16(minute) << 5) | (uint16(second) / 2) + fat_date: uint16 = uint16((fat_year << 9) | (uint16(month) << 5) | uint16(day)) + fat_time: uint16 = uint16((uint16(hour) << 11) | (uint16(minute) << 5) | (uint16(second) / 2)) return (uint32(fat_date) << 16) | uint32(fat_time) diff --git a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp index b1c552d..a338348 100644 --- a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp +++ b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp @@ -168,7 +168,7 @@ class lfn_entry: def sfn_checksum(name: const str) -> uint8: sum: uint8 = 0 for i in range(11): - sum = ((sum & 1) << 7) + (sum >> 1) + name[i] + sum = uint8(((sum & 1) << 7) + (sum >> 1) + name[i]) return sum def uni2oem_placeholder(uni: uint16, cp: uint16) -> uint16: @@ -233,7 +233,7 @@ def sfn_from_lfn(lfn: const str, sfn: str): if ch == '.': dot_pos = si; si += 1; ext_i = 0; continue uc: char - if ch >= 'a' and ch <= 'z': uc = ch - 32 + if ch >= 'a' and ch <= 'z': uc = char(ch - 32) elif ch == ' ': uc = '_' elif ch == '+' or ch == ',' or ch == ';' or ch == '=' or ch == '[' or ch == ']': uc = '_' else: uc = ch @@ -722,8 +722,8 @@ class volinfo: for i in range(11): a: char = self.win[entry_offset_in_sector + i] b: char = sfn[i] - if a >= 'a' and a <= 'z': a = a - 32 - if b >= 'a' and b <= 'z': b = b - 32 + if a >= 'a' and a <= 'z': a = char(a - 32) + if b >= 'a' and b <= 'z': b = char(b - 32) if a != b: match_found = 0 break @@ -732,11 +732,11 @@ class volinfo: lfn_matched: int = 1 li: int = 0 for name_ch in name: - lfn_ch: uint16 = *(uint16*(uint64(lfn_buf) + li * 2)) - lfn_low: uint16 = lfn_ch - if lfn_low >= 65 and lfn_low <= 90: lfn_low = lfn_low + 32 + lfn_ch: uint16 = *(uint16*(uint64(lfn_buf) + li * 2)) + lfn_low: uint16 = uint16(lfn_ch) + if lfn_low >= 65 and lfn_low <= 90: lfn_low = uint16(lfn_low + 32) n_low: uint16 = uint16(name_ch) - if n_low >= 65 and n_low <= 90: n_low = n_low + 32 + if n_low >= 65 and n_low <= 90: n_low = uint16(n_low + 32) if lfn_low != n_low: lfn_matched = 0 break diff --git a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp index 80f9674..20ad593 100644 --- a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp +++ b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp @@ -88,7 +88,7 @@ def read_scancode() -> uint8: return code def scancode_to_ascii(scancode: uint8) -> char: - code: uint8 = scancode & ~uint8(KEY_RELEASED) + code: uint8 = uint8(scancode & ~uint8(KEY_RELEASED)) if code >= 128: return '\0' shifted: bool = (shift_l or shift_r) != 0 if caps_lock and code >= 0x10 and code <= 0x32: diff --git a/VKernel/Kernel/drivers/storage/ide/ide.vp b/VKernel/Kernel/drivers/storage/ide/ide.vp index 34c480b..613e0cc 100644 --- a/VKernel/Kernel/drivers/storage/ide/ide.vp +++ b/VKernel/Kernel/drivers/storage/ide/ide.vp @@ -64,7 +64,7 @@ def init() -> int: _ide_initialized = 1 return IDError.IDE_ERR_NONE -def readSector(lba: uint32, buffer: t.CPtr) -> int: +def readSector(lba: uint32, buffer: rawptr) -> int: if buffer is None: return IDError.IDE_ERR_BUFFER_NULL err: IDError = waitReady(IDE_baseport_PRIMARY) if err != IDError.IDE_ERR_NONE: @@ -84,8 +84,8 @@ def readSector(lba: uint32, buffer: t.CPtr) -> int: buf: uint16* = uint16*(buffer) for j in range(256): *buf = asm.inw(0x1F0) - # buf 为字节指针(uint16|t.CPtr → i8*),每次按 u16 读写须前进 2 字节 - buf = buf + 2 + # buf 是 i16*(uint16*):+1 表示前进 1 个元素 = 2 字节,256 次恰好填满 512B + buf = buf + 1 first_byte: uint8 = *(uint8*(buffer)) # viperlib.snprintf(c.Addr(dbg), 120, "[readSector] lba=%lu status=0x%02x first=%02x\n", lba, uint32(st2), uint32(first_byte)) # serial.puts(dbg) @@ -108,14 +108,9 @@ def writeSector(lba: uint32, buffer: const rawptr) -> int: for j in range(256): val: uint16 = *buf asm.outw(0x1F0, val) - # [待复核·指针缩放] 下面这行注释声称 "uint16|t.CPtr → i8*(字节指针),每次前进 2 字节", - # 但 `X | t.CPtr` 的联合类型当前解析为 Ptr(X)(见联合类型解析与 includes/memhub.vp 中 - # `t.CUInt64T(x, t.CPtr)` 的既有用法)——若 `buf` 实际是 u16*,则 `buf + 2` 前进的是 - # 4 字节(GEP 按元素缩放),本循环 256 次会读满 1KB 而不是 512B,且越界读到缓冲区之后。 - # 结论待定(需一次 IR 取证:看 `buf + 2` 生成的是 getelementptr i16 还是 i8)。 - # 与按整数加法推进地址、不依赖指针元素类型的写法(同仓另有此类)对齐后再改; - # `| t.CPtr` → `rawptr[T]` 迁移时一并复核,见 Debugger/rawptr-migration-and-fastfail.md。 - buf = buf + 2 + # buf 是 i16*(uint16*):+1 表示前进 1 个元素 = 2 字节,256 次恰好读完 512B + # (IR 取证:`buf + 2` 生成 getelementptr ..., i16,按元素缩放 → +4 字节,越界) + buf = buf + 1 asm.outb(0x1F7, 0xE7) waitReady(IDE_baseport_PRIMARY) return IDError.IDE_ERR_NONE diff --git a/VKernel/Kernel/drivers/video/vesafb/gfx.vp b/VKernel/Kernel/drivers/video/vesafb/gfx.vp index 424ccb0..ce30b64 100644 --- a/VKernel/Kernel/drivers/video/vesafb/gfx.vp +++ b/VKernel/Kernel/drivers/video/vesafb/gfx.vp @@ -20,13 +20,13 @@ class Vec3: self.x = x self.y = y self.z = z - def Sub(self, b: Vec3) -> Vec3*: + def Sub(self, b: Vec3) -> Vec3: return Vec3(self.x - b.x, self.y - b.y, self.z - b.z) - def Cross(self, b: Vec3) -> Vec3*: + def Cross(self, b: Vec3) -> Vec3: return Vec3(self.y * b.z - self.z * b.y, self.z * b.x - self.x * b.z, self.x * b.y - self.y * b.x) def Dot(self, b: Vec3) -> float: return self.x * b.x + self.y * b.y + self.z * b.z - def Norm(self) -> Vec3*: + def Norm(self) -> Vec3: l = math.sqrtf(self.Dot(self)) return Vec3(self.x / l, self.y / l, self.z / l) @@ -39,7 +39,7 @@ def Mat4_Identity() -> Mat4*: m.m[0][0] = 1; m.m[1][1] = 1; m.m[2][2] = 1; m.m[3][3] = 1 return m -def Mat4_Mul(a: Mat4, b: Mat4) -> Mat4*: +def Mat4_Mul(a: Mat4*, b: Mat4*) -> Mat4*: res: Mat4 = Mat4() string.memset(&res, 0, Mat4.__sizeof__()) for i in range(4): @@ -48,7 +48,7 @@ def Mat4_Mul(a: Mat4, b: Mat4) -> Mat4*: res.m[i][j] += a.m[i][k] * b.m[k][j] return res -def Mat4_MulVec(m: Mat4, v: Vec3) -> Vec3*: +def Mat4_MulVec(m: Mat4*, v: Vec3*) -> Vec3: x: float = m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z + m.m[0][3] y: float = m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z + m.m[1][3] z: float = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z + m.m[2][3] @@ -65,7 +65,7 @@ def Mat4_Perspective(fov: float, aspect: float, zn: float, zf: float) -> Mat4*: m.m[2][2] = zf / (zn - zf); m.m[2][3] = (zf * zn) / (zn - zf); m.m[3][2] = -1 return m -def Mat4_LookAt(eye: Vec3, target: Vec3, up: Vec3) -> Mat4*: +def Mat4_LookAt(eye: Vec3, target: Vec3, up: Vec3) -> Mat4: zaxis: Vec3 = eye.Sub(target).Norm() xaxis: Vec3 = up.Cross(zaxis).Norm() yaxis: Vec3 = zaxis.Cross(xaxis) @@ -76,7 +76,7 @@ def Mat4_LookAt(eye: Vec3, target: Vec3, up: Vec3) -> Mat4*: m.m[3][3] = 1 return m -def Mat4_Translate(x: float, y: float, z: float) -> Mat4*: +def Mat4_Translate(x: float, y: float, z: float) -> Mat4: m: Mat4 = Mat4_Identity() m.m[0][3] = x; m.m[1][3] = y; m.m[2][3] = z return m @@ -132,7 +132,7 @@ class Renderer: if e2 > -dy: err -= dy; x0 += sx if e2 < dx: err += dx; y0 += sy - def DrawTriangle(self, v0: Vec3, v1: Vec3, v2: Vec3, col: uint32): + def DrawTriangle(self, v0: Vec3*, v1: Vec3*, v2: Vec3*, col: uint32): if v0.z < float(0.0) or v1.z < float(0.0) or v2.z < float(0.0): return if (v0.x > float(10.0) or v0.x < float(-10.0) or v0.y > float(10.0) or v0.y < float(-10.0) or v1.x > float(10.0) or v1.x < float(-10.0) or v1.y > float(10.0) or v1.y < float(-10.0) or @@ -259,7 +259,7 @@ class Scene3D: Vec3(-1, -1, -1), Vec3(-1, -1, 1), Vec3(-1, 1, -1), Vec3(-1, 1, 1), Vec3( 1, -1, -1), Vec3( 1, -1, 1), Vec3( 1, 1, -1), Vec3( 1, 1, 1) ] - for i in range(8): v[i] = *Mat4_MulVec(mvp, &v[i]) + for i in range(8): v[i] = Mat4_MulVec(mvp, &v[i]) faces: t.CArray[t.CArray[int, 3], 12] = [ [0, 2, 1], [1, 2, 3], [4, 1, 5], [4, 0, 1], [6, 3, 2], [6, 7, 3], [4, 6, 0], [0, 6, 2], [5, 7, 4], [4, 7, 6], [1, 3, 5], [5, 3, 7] @@ -277,7 +277,7 @@ class Scene3D: v[1] = Vec3(center.x+radius*math.sinf(theta1)*math.cosf(phi2), center.y+radius*math.cosf(theta1), center.z+radius*math.sinf(theta1)*math.sinf(phi2)) v[2] = Vec3(center.x+radius*math.sinf(theta2)*math.cosf(phi1), center.y+radius*math.cosf(theta2), center.z+radius*math.sinf(theta2)*math.sinf(phi1)) v[3] = Vec3(center.x+radius*math.sinf(theta2)*math.cosf(phi2), center.y+radius*math.cosf(theta2), center.z+radius*math.sinf(theta2)*math.sinf(phi2)) - for k in range(4): v[k] = *Mat4_MulVec(mvp, &v[k]) + for k in range(4): v[k] = Mat4_MulVec(mvp, &v[k]) self.renderer.DrawTriangle(&v[0], &v[1], &v[2], col) self.renderer.DrawTriangle(&v[1], &v[3], &v[2], col) diff --git a/VKernel/Kernel/drivers/video/vesafb/vga.vp b/VKernel/Kernel/drivers/video/vesafb/vga.vp index 2e02c94..7f5206e 100644 --- a/VKernel/Kernel/drivers/video/vesafb/vga.vp +++ b/VKernel/Kernel/drivers/video/vesafb/vga.vp @@ -368,12 +368,12 @@ class _VGAScreenDriver: if x < 0 or x >= self.fw or y < 0 or y >= self.fh: return offset: int = y * self.fp + x * 4 # 解析RGBA分量 - r: uchar = (color >> 16) & 0xFF - g: uchar = (color >> 8) & 0xFF - b: uchar = color & 0xFF - a: uchar = (color >> 24) & 0xFF + r: uchar = uchar((color >> 16) & 0xFF) + g: uchar = uchar((color >> 8) & 0xFF) + b: uchar = uchar((color >> 0) & 0xFF) + a: uchar = uchar((color >> 24) & 0xFF) # 根据硬件格式写入像素 - match self.ColorFormat: + switch self.ColorFormat: case __ColorFormat.ColorFormat_BGRA: self.fb[offset + 0] = b fb[offset + 1] = g @@ -392,7 +392,7 @@ class _VGAScreenDriver: fb[offset + 0] = r fb[offset + 1] = g fb[offset + 2] = b - case _: + default: # 降级到BGRA fb[offset + 0] = b fb[offset + 1] = g @@ -407,10 +407,10 @@ class _VGAScreenDriver: PixelSize: int = 3 if self.ColorFormat == __ColorFormat.ColorFormat_BGR or self.ColorFormat == __ColorFormat.ColorFormat_RGB else 4 RowSize: int = self.fw * PixelSize # 解析清除颜色的RGBA分量 - r: uchar = (color >> 16) & 0xFF - g: uchar = (color >> 8 ) & 0xFF - b: uchar = (color) & 0xFF - a: uchar = (color >> 24) & 0xFF + r: uchar = uchar((color >> 16) & 0xFF) + g: uchar = uchar((color >> 8) & 0xFF) + b: uchar = uchar((color >> 0) & 0xFF) + a: uchar = uchar((color >> 24) & 0xFF) # 逐行填充,比逐像素调用SetPixel快得多 for y in range(self.fh): row_ptr: uchar* = fb + y * fp @@ -450,7 +450,7 @@ class _VGAScreenDriver: ch: uchar = uchar(cr) if ch >= 128: ch = DEFAULT_CHAR # 预解析背景色Alpha,避免内层循环重复计算 - bg_alpha: uint8 = (bgcolor >> 24) & 0xFF + bg_alpha: uint8 = uint8((bgcolor >> 24) & 0xFF) draw_bg: int = (bg_alpha != 0) # 背景是否需要绘制 # 渲染8x16点阵字符 for fy in range(FONT_HEIGHT): diff --git a/VKernel/Kernel/intr/gdt.vp b/VKernel/Kernel/intr/gdt.vp index 2bfade0..45eb87a 100644 --- a/VKernel/Kernel/intr/gdt.vp +++ b/VKernel/Kernel/intr/gdt.vp @@ -119,23 +119,23 @@ def set_tss_rsp0(rsp0: uint64): def setGate(num: int, base: uint64, limit: uint32, access: uint8, gran: uint8): global gdt - gdt[num].limit_low = (limit & 0xFFFF) - gdt[num].base_low = (base & 0xFFFF) - gdt[num].base_middle = (base >> 16) & 0xFF - gdt[num].base_high = (base >> 24) & 0xFF - gdt[num].granularity = ((limit >> 16) & 0x0F) | (gran & 0xF0) - gdt[num].access = access + 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 = limit & 0xFFFF - e.base_low = base & 0xFFFF - e.base_middle = (base >> 16) & 0xFF + e.limit_low = uint16(limit & 0xFFFF) + e.base_low = uint16(base & 0xFFFF) + e.base_middle = uint8((base >> 16) & 0xFF) e.access = 0x89 - e.granularity = (limit >> 16) & 0x0F - e.base_high = (base >> 24) & 0xFF + e.granularity = uint8((limit >> 16) & 0x0F) + e.base_high = uint8((base >> 24) & 0xFF) e.base_upper = uint32(base >> 32) e.reserved = 0 diff --git a/VKernel/Kernel/intr/idt.vp b/VKernel/Kernel/intr/idt.vp index 64c2911..d049fd8 100644 --- a/VKernel/Kernel/intr/idt.vp +++ b/VKernel/Kernel/intr/idt.vp @@ -76,12 +76,12 @@ extern def isr_default() def setGate(num: int, base: uint64, sel: uint16, flags: uint8): global idt - idt[num].base_low = (base & 0xFFFF) - idt[num].base_middle = (base >> 16) & 0xFFFF - idt[num].base_high = (base >> 32) & 0xFFFFFFFF - idt[num].selector = sel + idt[num].base_low = uint16(base & 0xFFFF) + idt[num].base_middle = uint16((base >> 16) & 0xFFFF) + idt[num].base_high = uint32((base >> 32) & 0xFFFFFFFF) + idt[num].selector = uint16(sel) idt[num].ist_attr = 0 - idt[num].type_attr = flags + idt[num].type_attr = uint8(flags) idt[num].reserved1 = 0 def isrCommonhandler(interrupt: int): diff --git a/VKernel/Kernel/main.vp b/VKernel/Kernel/main.vp index 03bffc9..38dbfb9 100644 --- a/VKernel/Kernel/main.vp +++ b/VKernel/Kernel/main.vp @@ -28,7 +28,6 @@ import services.mouse as mse_svc import services.desktop as desktop import intr.syscall as syscall import execrunner.elf as elf -import t, c import asm @@ -125,11 +124,11 @@ class ViperKernel: serial.puts("[main] kernel init done\n") fb: rawptr = rawptr(BootInfo.framebuffer_addr) - width: uint64 = BootInfo.framebuffer_width - height: uint64 = BootInfo.framebuffer_height - pitch: uint64 = BootInfo.framebuffer_pitch - fb_format: uint64 = BootInfo.framebuffer_format - fb_size: uint64 = BootInfo.framebuffer_size + width: int = int(BootInfo.framebuffer_width) + height: int = int(BootInfo.framebuffer_height) + pitch: int = int(BootInfo.framebuffer_pitch) + fb_format: int = int(BootInfo.framebuffer_format) + fb_size: uint64 = BootInfo.framebuffer_size # [DBG] 打印 BootInfo 指针与 memmap 原始字段,定位全 0 根因(用后移除) _dbbuf: [140]char viperlib.snprintf(&_dbbuf, 140, "[main] BootInfo=0x%lx mmap=0x%lx mmsz=%lu mmd=%lu fb=0x%lx\n", @@ -147,13 +146,19 @@ class ViperKernel: serial.puts(&_dbraw) serial.puts("\n[DB] dump end\n") + # 内核镜像末端(含 .bss;__bss_end 见 VKernel/linker.ld):传给 mm.init 使其在挑选 + # 堆 arena 时排除整块内核镜像 —— .bss 不占文件大小,bootloader 只按文件大小预留页, + # 否则 .bss 尾部(ticks/_perf_* 等全局量)会落在 memmap 空闲区里被堆占用。 + _kern_end: uint64 = 0 + __asm__(f"lea {asmout(_kern_end, ASM_DESCR.OUTPUT_REG)}, [rip + __bss_end]", + op=[ASM_DESCR.CLOBBER_MEMORY]) if BootInfo is not None: paging.init(BootInfo.MemmapAddr, BootInfo.MemmapSize) fb_pages: uint64 = (fb_size + uint64(0xFFF)) >> uint64(12) for fpi in range(fb_pages): fva: uint64 = uint64(fb) + fpi * uint64(0x1000) paging.MapPage(fva, fva, paging.PTE_WRITABLE | paging.PTE_PCD) - mm.init(BootInfo.MemmapAddr, BootInfo.MemmapSize, BootInfo.MemmapDescSize, BootInfo.framebuffer_addr, fb_size) + mm.init(BootInfo.MemmapAddr, BootInfo.MemmapSize, BootInfo.MemmapDescSize, BootInfo.framebuffer_addr, fb_size, BootInfo.kernel_PhysAddr, _kern_end) pt_pool_buf: rawptr = mm.malloc(uint64(513) * uint64(4096)) paging.init_pool(pt_pool_buf, uint64(513) * uint64(4096)) else: @@ -354,4 +359,3 @@ def _start() -> int: asm.hlt() sched.Scheduler._yield() return 0 - diff --git a/VKernel/Kernel/mm/mm.vp b/VKernel/Kernel/mm/mm.vp index e262f38..af1e217 100644 --- a/VKernel/Kernel/mm/mm.vp +++ b/VKernel/Kernel/mm/mm.vp @@ -117,7 +117,7 @@ class _BuddySystemObject: block: memory_block* = memory_block*(cur_addr) block.size = block_size block.state = BLOCK_FREE - block.order = order + block.order = uint8(order) block.next = None block.prev = None if order <= MAX_ORDER: @@ -139,12 +139,12 @@ class _BuddySystemObject: new_block: memory_block* = memory_block*(uint64(block) + new_block_size) new_block.size = new_block_size new_block.state = BLOCK_FREE - new_block.order = current_order + new_block.order = uint8(current_order) new_block.next = None new_block.prev = None # 更新原块大小和阶数 block.size = new_block_size - block.order = current_order + block.order = uint8(current_order) # 将新块添加到对应阶数的空闲链表 if current_order <= MAX_ORDER: new_block.next = self.buddy.free_lists[current_order] @@ -175,7 +175,7 @@ class _BuddySystemObject: # 合并块 merged_block: memory_block* = block if block < buddy else buddy merged_block.size = get_block_size(order + 1) - merged_block.order = order + 1 + merged_block.order = uint8(order + 1) block = merged_block order += 1 return block @@ -448,7 +448,7 @@ def free_memory_regions(): memory_regions = None # 初始化内存管理系统 -def init(MemmapAddr: uint64, MemmapSize: uint64, MemmapDescSize: uint64, FbAddr: uint64 = 0, FbSize: uint64 = 0): +def init(MemmapAddr: uint64, MemmapSize: uint64, MemmapDescSize: uint64, FbAddr: uint64 = 0, FbSize: uint64 = 0, KernelAddr: uint64 = 0, KernelEnd: uint64 = 0): global BuddySystemObject start_addr: rawptr = None size: uint64 = 0 @@ -476,6 +476,20 @@ def init(MemmapAddr: uint64, MemmapSize: uint64, MemmapDescSize: uint64, FbAddr: fb_end: uint64 = FbAddr + FbSize if start < fb_end and end > FbAddr: continue + # 排除内核镜像区([KernelAddr, KernelEnd),含 .bss):bootloader 只按 + # 文件大小预留页,.bss 不占文件 → 其尾部留在 memmap 的 EfiConventionalMemory + # 里。若不排除,堆 arena 会用这段内存写 memory_block 头/用户数据,与内核 + # 全局量(ticks/_perf_* 等)互相破坏,并进一步搞乱堆元数据。 + # 内核镜像位于常规内存低端,故把与该区间重叠的 region 起点抬到镜像末端, + # 而不是整段丢弃(整段丢弃会连带弃掉镜像之上的一大片可用内存)。 + if KernelEnd > KernelAddr: + if end <= KernelEnd: + continue + if start < KernelEnd: + start = KernelEnd + region_size = end - start + if end <= start: + continue if etype == MEMORY_TYPE_AVAILABLE: if region_size > best_avail_size: best_avail_size = region_size diff --git a/VKernel/Kernel/platform/pch/pic.vp b/VKernel/Kernel/platform/pch/pic.vp index 1336bb8..9d6949d 100644 --- a/VKernel/Kernel/platform/pch/pic.vp +++ b/VKernel/Kernel/platform/pch/pic.vp @@ -99,7 +99,7 @@ def setMask(irq: uint8): else: port = PIC2_DATA irq -= 8 - value = asm.inb(port) | (1 << irq) + value = uint8(asm.inb(port) | (1 << irq)) asm.outb(port, value) asm.io_wait() # 确保命令生效 @@ -114,6 +114,6 @@ def clearMask(irq: uint8): else: port = PIC2_DATA irq -= 8 - value = asm.inb(port) & ~(1 << irq) + value = uint8(asm.inb(port) & ~(1 << irq)) asm.outb(port, value) asm.io_wait() # 确保命令生效 diff --git a/VKernel/Kernel/platform/pch/pit.vp b/VKernel/Kernel/platform/pch/pit.vp index b0b1612..df33850 100644 --- a/VKernel/Kernel/platform/pch/pit.vp +++ b/VKernel/Kernel/platform/pch/pit.vp @@ -18,9 +18,9 @@ def pit_init(frequency: int): asm.io_wait() # 写入低字节 - asm.outb(PIT_CHANNEL0, divisor & 0xFF) + asm.outb(PIT_CHANNEL0, uint8(divisor & 0xFF)) asm.io_wait() # 写入高字节 - asm.outb(PIT_CHANNEL0, (divisor >> 8) & 0xFF) + asm.outb(PIT_CHANNEL0, uint8((divisor >> 8) & 0xFF)) asm.io_wait() diff --git a/VKernel/Kernel/services/keyboard.vp b/VKernel/Kernel/services/keyboard.vp index ba3b200..33c2e3c 100644 --- a/VKernel/Kernel/services/keyboard.vp +++ b/VKernel/Kernel/services/keyboard.vp @@ -2,7 +2,6 @@ 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 -import viperlib define SERVICE_KEYBOARD = 1 @@ -17,8 +16,6 @@ class KeyboardService: self.running = 0 self.usb_kbd_th = None -kbd_svc: KeyboardService - def kbd_thread(arg: rawptr) -> int: serial.puts("[kbd_svc] started\n") @@ -39,9 +36,12 @@ def usb_kbd_thread(arg: rawptr) -> int: sched.Scheduler._yield() return 0 + +kbd_svc: KeyboardService = KeyboardService() + def start() -> int: global kbd_svc - kbd_svc = KeyboardService() + kbd_svc.__init__() keyboard.init() serial.puts("[kbd_svc] PS/2 keyboard initialized, IRQ1 installed\n") usb_kbd.init() diff --git a/VKernel/linker.ld b/VKernel/linker.ld index d994a3a..296fdaa 100644 --- a/VKernel/linker.ld +++ b/VKernel/linker.ld @@ -26,6 +26,13 @@ SECTIONS { *(.bss) *(.bss.*) *(COMMON) + /* 强制本输出段为 PROGBITS 并占用文件空间:.bss 默认是 NOBITS(不占文件), + 于是 kernel.bin 的 FileSize 不包含 .bss。bootloader 只按文件大小预留物理页 + (PagesNeeded = KernelSize/4096),.bss 尾部(ticks/_perf_* 等全局量)便留在 + 未预留的 EfiConventionalMemory 里,被 mm 的堆 arena 覆盖 → 破坏内核全局量、 + 并反过来破坏堆元数据。加一条数据语句(LONG)即让整段 .bss 写入 kernel.bin。 */ + . = ALIGN(16); + LONG(0); __bss_end = .; } diff --git a/boot/boot.c b/boot/boot.c index 4d591ea..63e6d5e 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -464,6 +464,31 @@ EFI_STATUS ExitBootServicesAndJumpToKernel( Print(L"Final FB: 0x%lx | %lux%lu | pitch %lu | format %lu\r\n", framebuffer_addr, framebuffer_width, framebuffer_height, framebuffer_pitch, framebuffer_format); + // ========================== + // 预留内核栈区(BOOTLOADER_STACK_BOTTOM ~ BOOTLOADER_STACK_TOP) + // ========================== + // 跳转内核后此区是主线程栈,但它在 memmap 里默认仍是 EfiConventionalMemory。 + // 若不占位,内核 mm 堆可能把这段内存当空闲区分配 → 主线程栈被堆数据覆盖。 + // 必须在 GetMemoryMap 之前用 AllocatePages 显式占位(AllocateAddress + + // EfiLoaderData),使其在捕获的 memmap 中标记为已用。 + { + EFI_PHYSICAL_ADDRESS StackAddr = BOOTLOADER_STACK_BOTTOM; + UINTN StackPages = (UINTN)((BOOTLOADER_STACK_TOP - BOOTLOADER_STACK_BOTTOM) / 0x1000ULL); + EFI_STATUS StackStatus = SystemTable->BootServices->AllocatePages( + AllocateAddress, + EfiLoaderData, + StackPages, + &StackAddr + ); + if (EFI_ERROR(StackStatus)) { + Print(L"Warning: Reserve boot stack region (0x%lx-0x%lx) failed - %r\r\n", + BOOTLOADER_STACK_BOTTOM, BOOTLOADER_STACK_TOP, StackStatus); + } else { + Print(L"Boot stack region reserved: 0x%lx-0x%lx (%lu pages)\r\n", + BOOTLOADER_STACK_BOTTOM, BOOTLOADER_STACK_TOP, StackPages); + } + } + // ========================== // ExitBootServices 流程 // ==========================