Commit Graph
300 Commits
Author SHA1 Message Date
TermiNexus 807c4207c0 chore: raise QEMU memory and extend the FontDemo sample
Give the guest 512 MiB so the full Noto Sans SC face and the fonttools
buffers fit, and render a mixed Chinese/Latin string in FontDemo.
2026-10-27 22:44:19 +08:00
TermiNexus 5d9df61de0 fix(fonttools): keep natural glyph proportions in the ASCII atlas
build_ascii_atlas() used to scale every glyph to fill its cw x ch cell,
so uppercase and lowercase had the same height and narrow shapes such as
i/l/o became solid blobs.

Use one uniform scale ((ch - 2) / units_per_em) for the whole font, keep
the real cap/x-height/descender ratios, and only squeeze glyphs whose ink
is wider than cw - 1. Center by ink width and place the baseline at ch - 4.
2026-10-27 22:21:41 +08:00
TermiNexus 9bfdaecc6b feat(vpui): support direct and Explorer-managed TTF text
vpui.set_text_mode selects:
- TEXT_MODE_DIRECT: vpui imports fonttools, loads /FONTS/FONT.TTF and
  builds the 8x16 atlas in-process.
- TEXT_MODE_MANAGED (default): text is queued per frame and drawn by
  Explorer through the new DESK_REQ_TEXT request; Explorer uses the same
  fonttools atlas.

Remove the fixed VPUI.ATL asset and its loader.
2026-10-27 22:08:16 +08:00
TermiNexus 5040149db8 feat(vpui): use a Noto Sans SC 8x16 atlas for UI text
Load /FONTS/VPUI.ATL once per process and alpha-blend its glyphs; keep the built-in 8x16 bitmap as fallback when the atlas is missing or the codepoint is non-ASCII.
2026-10-27 21:52:02 +08:00
TermiNexus 28a011ca9e fix(fonttools): stop the contour walk at the closing point
When an off-curve run ended on first_on, the walk set cur=first_on and
wrapped past it, repeating the contour and overflowing the edge table.
Break immediately after drawing the closing quadratic.
2026-10-27 21:42:19 +08:00
TermiNexus 6eba51701a fix(fonttools): record the TrueType on-curve flag per point
_pon was never written, so every point was treated as off-curve and all
straight edges/corners were flattened through the quadratic path. Set
_pon from bit 0 of each parsed glyph flag, including repeated flags.
2026-10-27 21:38:34 +08:00
TermiNexus 3145e38211 fix(fonttools): keep the second off-curve point as the next control
When two consecutive off-curve points were flattened via their midpoint,
the code advanced past the second point, so the following segment was a
line instead of a quadratic through that control. This rounded corners
and deformed glyphs. Advance only to the first control point.
2026-10-27 21:07:05 +08:00
TermiNexus 6a65d0a7f2 fix(fonttools): scale Bezier subdivision to the pixel error
Flatten each quadratic with a segment count derived from
|p0 - 2*p1 + p2| in pixel space, targeting < 0.5 px error. The count
grows with the rendered font size. All-off-curve contours now use
midpoint quadratics instead of polygon edges.
2026-10-27 21:00:07 +08:00
TermiNexus faab22c40e feat(font): use the full Noto Sans SC font and enlarge the disk
- FontDemo points at /FONTS/FONT.TTF
- build.py installs NotoSansSC-6.ttf as disk/fonts/font.ttf
- grow disk.img from 64 MiB to 256 MiB
2026-10-27 20:45:27 +08:00
TermiNexus e6e5763ded chore(build): allow QEMU to reboot on guest reset
Keep -no-reboot disabled so the reboot command restarts the VM.
2026-10-27 20:41:07 +08:00
TermiNexus 585d3a8215 feat(font): add Brotli/WOFF2 and TrueType text rendering
- vpsdk/brotli: Brotli decoder with the static dictionary
- vpsdk/fonttools: TTF/WOFF2 loading, cmap, glyf/composite glyphs and
  anti-aliased rasterization
- Apps/FontDemo: render 你好,世界 from a fixed font path
- autostart FontDemo and copy the Brotli dictionary into disk/libs
- build with the fixed ViperC compiler that zero-extends unsigned types
2026-10-27 20:26:05 +08:00
TermiNexus 93a4f5bdcb chore(explorer): remove [explorer] debug output
Drop startup/input/frame tracing from the desktop shell and window
server, including the one-shot diagnostic counters.
2026-10-27 17:54:06 +08:00
TermiNexus 976b8307f9 chore(scene3d): remove [s3d] debug output
Drop the serial tracing from startup, the render thread and the
pre-render loop.
2026-10-27 17:52:32 +08:00
TermiNexus 28d1a23677 chore(vpui): remove [vpui] debug output
Drop the first-redraw/first-flush/canvas-draw debug tracing and the
related counters.
2026-10-27 17:51:46 +08:00
TermiNexus 4abb0ef3f6 chore(devfs): remove [serial0] debug output
Keep the data written to /dev/serial0, drop the open/close/read/write
debug tags.
2026-10-27 17:50:41 +08:00
TermiNexus cec0647708 fix(acpi): read S5 sleep types from the DSDT _S5 object
The FADT signature constant was byte-swapped ("FCAP"), so FADT lookup
always failed. Correct it to "FACP".

SLP_TYP is platform-defined and must come from the DSDT _S5 package.
QEMU/OVMF defines _S5 as 0, so the previous hardcoded value 5 never
triggered S5. Parse _S5 and use its SLP_TYPa/SLP_TYPb for PM1a/PM1b.
2026-10-27 17:36:35 +08:00
TermiNexus b33fbb75dc fix(boot): read the ACPI RSDP before taking the memory-map key
ExitBootServices failed with EFI_INVALID_PARAMETER because Print ran
after GetMemoryMap, so the console output could change the memory map
and invalidate MapKey. Locate the RSDP and print it before GetMemoryMap.
2026-10-27 17:14:51 +08:00
TermiNexus 7e0aa5c7af feat(acpi): power off via the ACPI FADT
Pass the firmware ACPI RSDP through boot_info so the kernel can locate
the FADT. Shutdown now writes the S5 sleep type to the PM1a/PM1b control
blocks advertised by the FADT instead of fixed QEMU/Bochs/VirtualBox
ports.

- boot: capture the ACPI 2.0/1.0 RSDP from the UEFI configuration table
- kernel: add platform/acpi; walk RSDP -> RSDT/XSDT -> FADT
- syscall: power_shutdown calls acpi.poweroff()
2026-10-27 17:05:05 +08:00
TermiNexus 925e0ffaea feat(power): add reboot and shutdown syscalls and terminal commands
- REBOOT (0x1008): 8042 reset with PCI 0xCF9 fallback
- SHUTDOWN (0x1009): ACPI S5 writes to the common QEMU/Bochs/VBox
  PM1a control ports, then halt
- vpsdk.process.reboot()/shutdown()
- Terminal commands: reboot, shutdown (help updated)
2026-10-27 16:56:26 +08:00
TermiNexus f9cf26e59a fix(paging): validate non-leaf page-table entries before dereference
_set_page_writable / MakePTWritable derived table pointers with
entry & ~0xFFF, which keeps reserved bits 52..62 and NX. An invalid
entry (P=1, PS=0, reserved bits set) produced 0xfffffffffffff000 and
a boot-time #PF in _set_page_writable.

Add _table_phys: keep address bits 12..51 and require reserved bits
52..62 to be zero. Use it at every non-leaf level in both walkers.
2026-10-27 16:35:06 +08:00
TermiNexus da4b0e47b7 fix(input): 修正 PS/2 滚轮方向
IntelliMouse 第 4 字节的 Z 符号与“向上 = 正值”的事件约定相反,
在驱动层统一翻符号;下游按正值表示滚轮向上处理,Terminal 的
scroll_offset -= w * 3 无需改动。
2026-10-27 16:19:37 +08:00
TermiNexus 395e5eefab feat(terminal): 去掉提示符/光标/输入文字的颜色
Text 默认的 prompt/cursor 由绿色改为与普通文本一致的 0xCCCCCC,
输入文字也不再硬编码白色;终端整体保持单色。
2026-10-27 14:54:00 +08:00
TermiNexus c379cadc38 feat(terminal): 日志与输入行之间留空行
- Text._exec_input 在本命令确实产生输出时追加一个空行,
  提示符与最后一条日志之间保持一个空行;无输出的命令不补
- 用实际 line_count 判断,clear 后不会被误补空行
- Terminal 启动时的介绍日志后也插入一个空行
2026-10-27 14:52:09 +08:00
TermiNexus 99c8cea8ee feat(window): 滚轮事件下传与 Terminal 滚动
- desk 协议新增 DESK_MOUSE_WHEEL;window 新增 EVENT_TYPE_WHEEL
- Explorer 汇总一批鼠标包的 wheel 增量,投给光标下的窗口
  (窗口内坐标;任务栏区域不投递)
- InputEvent.button 承载滚轮有符号增量(uint8 编码,消费方按 int8 解码)
- vpui.Text 处理 WHEEL:每次滚动 3 行,按“输出行 + 输入行”总行数钳制,
  并同步滚动条;输入行仍保持在可视区内
2026-10-27 14:50:04 +08:00
TermiNexus 5405a34a24 feat(input): PS/2 鼠标启用 IntelliMouse 滚轮
- init 发送 200/100/80 魔数并读取设备 ID;ID=3/4 时切到 4 字节包
- IRQ 的 4 字节模式解析第 4 字节低 4 位为有符号 Z 增量;
  标准 3 字节模式 wheel 恒 0
- mouse_packet 增加 wheel:int8
- /dev/input/mouse 布局扩展:[9] = wheel(int8),read 返回 10;
  调用方缓冲不足 10 字节时仍返回旧的 9 字节布局
2026-10-27 14:50:03 +08:00
TermiNexus 5e2598a992 feat(terminal): 输入行跟随输出并显示当前路径
- Text 不再把输入行固定在控件底部:输入行紧跟在最后一条输出之后,
  输出增加时随之下移;超出可视区时 scroll_offset 保持输入行可见
- Text 增加 prompt 字段 / set_prompt;点击定位、光标、_exec_input、
  滚动条计算都按实际 prompt 长度和总行数(输出行 + 输入行)计算
- Terminal 的提示符改为“归一化路径 + /> ”:
  根目录是 "/> ",/apps 是 "/apps/> "
- cd 成功后更新提示符;裸 cd 仍打印当前路径
2026-10-27 14:41:35 +08:00
TermiNexus ab18afd26e feat(window): WIN7 关闭按钮红底改为圆形
WIN7 样式的关闭按钮仍保留 28×20 的命中区,但红色背景改为
区域内居中的 20×20 圆,圆心与 X 图标中心重合;
hover / 按下时的颜色变化规则不变。
2026-10-27 14:40:48 +08:00
TermiNexus b94de46ce5 feat(window): 任务栏层级提升到窗口之上
- render_range 顺序改为:背景 → 窗口 → 任务栏 → 光标,
  窗口拖到任务栏区域时会被任务栏盖住
- hit_test 在任务栏高度内直接返回 -1,避免窗口视觉上被任务栏
  盖住后还能点到下面的窗口;任务栏图标仍由 _taskbar_icon_hit 处理
2026-10-27 14:35:38 +08:00
TermiNexus b6ea47277c fix(kernel): 用户异常终止不再提前 swapgs,避免拖垮整机
用户态 #PF 的终止路径直接从 ISR 调用 _yield,不经过 ISR 出口。
原实现在 _yield 前把 GS_BASE swap 回 0;但下一个被调度的线程如果是
从用户态 timer IRQ 或 syscall 挂起的,它的恢复路径会自己 swapgs 回 0。
提前 swap 会让它 swap 反,下一次系统调用用 gs:[8] 取内核栈时读到
线性地址 8,进而三重故障/整机卡死。

- 删除终止路径的 swapgs 块,保持 ISR 入口后的 GS 视图,与其他
  timer/syscall 让出路径一致
- 先置 THREAD_DONE 再 free_user_thread,与
  Scheduler.exit_current_thread 的次序一致,避免“资源已释放但
  state 仍是 RUNNING”的再调度窗口
2026-10-27 14:30:16 +08:00
TermiNexus f9e91a9d6e fix(gargantua): 调整窗口大小时不再改画布源尺寸
现象:计算过程中拖动/缩放 Gargantua 窗口,tid=2 以
[0E] rip=0x413f2f cr2=0x46c000 退出。

原因:RESIZE 处理器把 FBCanvas 的源尺寸用
set_fb(fb, new_w, new_h) 改成窗口内容尺寸,但 _fb_mem 仍是固定的
160×90。窗口变大后 FBCanvas.draw 会按新的 _cw 逐行读取
self._fb[py*_cw+px],越过 _fb_mem 末尾(0x46c000)触发用户态缺页。

修复:RESIZE 时不再改画布源尺寸,只调用 root.redraw() 按新窗口
尺寸重绘;超过源尺寸的部分由 FBCanvas 现有的 min(_cw,self.w)
裁剪逻辑处理。
2026-10-27 14:23:35 +08:00
TermiNexus 845633773b fix(window): 标题栏按钮保持方角,仅按窗口圆角裁剪
上一版把 WIN11 关闭按钮红底做了内收 + 按钮圆角,不符合预期:
窗口是全圆角,但按钮本身应当是方角,唯一需要丢弃的是与窗口
右上圆角重合的那部分像素。

- WIN11 关闭按钮红底恢复整块矩形,仅用 _window_round_keep 丢弃窗口圆角外像素
- WIN7/WINXP 按钮底色同样改为方角(r=0),仍做窗口轮廓裁剪
- 按钮命中区域保持不变(仍是完整方角矩形)
2026-10-27 13:25:41 +08:00
TermiNexus 8dc806e7e2 fix(window): WIN11 关闭按钮 hover 红底按圆角裁剪
WIN11 窗口是圆角样式,关闭按钮又紧贴右上角;此前 hover/按下直接
row_fill 整块矩形,红色会盖住窗口圆角外的区域。

- 新增 _window_round_keep:按窗口自身的圆角轮廓判断像素是否可画
- 新增 _close_fill_row:同时按“按钮圆角 + 窗口圆角”双重裁剪
- WIN11 关闭按钮红底向内收 2px、圆角 3px;WIN7/WINXP 也走窗口轮廓裁剪
- 移除不再使用的 _round_fill_row
2026-10-27 13:21:34 +08:00
TermiNexus b9efc30d71 feat(window): 标题栏 hover、最大化图标、边缘缩放与控件光标
1) 标题栏按钮 hover:min/max 背景按 alpha 压暗,close 变红、图标变白;
   按下态更深。新增 hover_btn_win/kind,仅在变化时重画标题栏。
2) 最大化图标改为单线方框(上边框不再两行加厚);最大化后显示
   两个错位重叠方框作为“还原”。
3) 窗口边缘 5px 热区支持拖拽缩放:左/右 ↔、上/下 ↕、四角斜向;
   缩放中实时更新几何与内容缓冲(按 1.5 倍扩容,避免 arena 抖动),
   并向 app 发 RESIZE。
4) 新增 DESK_REQ_CURSOR / window.set_cursor_type 真正下发光标类型;
   explorer 按窗口 cursor + 边缘热区选择箭头 / I 形 / 手指 / 缩放光标。
5) vpui.Tk 在 HOVER 时按最上层控件设置光标:Entry/Text → I 形,
   Button → 手指;Entry 自己的光标请求移除,避免与集中逻辑冲突。
2026-10-27 13:14:42 +08:00
TermiNexus 6ecd891f64 fix(desk): 清空共享区槽表并按版本拒绝旧 app
现场:所有窗口消失、任务栏多出若干图标,点击后 explorer 以
[0E] rip=0x4061e8 cr2=0x1207e8fff 缺页退出。

原因:desk_format 只清 DeskHeader,没有清 0x100 起的 WinSlot 表。
DESK_SHM_SIZE 从 8MB 提到 32MB 后,mm.malloc 拿到的内存不再恰好全零
(混入 bootloader/固件遗留数据),随机 used/active 被当成窗口,
合成时按垃圾 fb_off 越界读像素。

- desk_format 先 memset 整个控制区(0x000000 ~ 0x200000)
- 分配槽位时整槽清零,避免复用残留
- DESK_VERSION 1 → 2,desk_ready 校验版本:
  旧 app 按旧 WinSlot 偏移读写会写坏共享区,现在直接拒绝挂载
- render_window_rows 校验 fb_off 范围,坏槽位只跳过,不再拖崩合成器
2026-10-27 12:52:23 +08:00
TermiNexus 8e94458fc2 fix(window): 最大化窗口不绘制阴影
最大化后窗口底边正好贴住任务栏,阴影(下沿 14px)会盖在任务栏上。
最大化状态跳过阴影绘制。
2026-10-27 12:44:54 +08:00
TermiNexus 03a5738702 perf(window): 最小化窗口的 FLUSH 不再置脏
应用最小化后仍会继续绘制并发送 FLUSH;此前每条 FLUSH 都标脏窗口区域,
合成器于是每帧重画背景。最小化时直接忽略置脏即可。
2026-10-27 12:43:53 +08:00
TermiNexus 97ca7bbbdb chore(build): viperc 路径集中为 VIPERC 常量并切换 vpcbuild3
- BuildKernel / BuildLibs / BuildApps 共用 VIPERC,去掉三处硬编码
- 指向 ViperC/__vpcbuild3__/output/viperc.exe
2026-10-27 12:43:19 +08:00
TermiNexus 632bc877df feat(window): 鼠标捕获与窗口最小化/最大化
鼠标:
- 内容区按下后记录 capture_win,按住期间的移动仍投 HOVER、松开投 RELEASE
  (即使光标移出窗口)。此前 btn_down != 0 时完全不发 HOVER,滚动条
  拖动拿不到位置更新。
- 标题栏按钮按下态改为通用 btn_win/btn_kind,支持关闭/最小化/最大化。

窗口:
- WinSlot 新增 maximized、restore_*、fb_cap 字段
- 最小化:隐藏窗口并把焦点交给最高可见窗口;任务栏点击恢复,
  再点一次已聚焦窗口则最小化
- 最大化:保存还原几何,铺满工作区(不含任务栏)并发送 RESIZE 事件;
  再次点击还原;拖动最大化窗口会先还原
- 像素缓冲按 fb_cap 复用,仅在容量不足时从 arena 扩容,避免反复
  最大化/还原耗尽 bump arena
- 1920x1080 最大化需要约 7.3MB 内容缓冲:DESK_SHM_SIZE 8MB → 32MB
2026-10-27 12:43:19 +08:00
TermiNexus 859197e5e9 feat(kbd): USB 键盘按住自动重复
USB HID 键盘只在状态变化时上报;a3c1d22 为避免 Enter 洪流加入整份报告去重后,
按住不放不再产生任何字符。

- 记录当前按住的非 CapsLock 键与下一次补发时刻
- 同一份报告重复到达(按键仍按住)时,按 500ms 首次延迟、33ms 间隔
  重新走 _decode_press,注入与按下沿相同的 ASCII/ANSI 字节
- 松开或换键时更新/清除重复目标;CapsLock 本身不重复
2026-10-27 12:43:19 +08:00
TermiNexus b8ca4826a9 chore(kernel): 移除帧缓冲参数的影子副本校验
fb/width/height/pitch 偶发被写坏的根因(页表/1GB 大页拆分时写坏内存)已修复,
不再需要 fail-fast 影子防御:

- 删除 _ShadowFb/_ShadowW/_ShadowH/_ShadowPitch 与 _SetFrameShadow、_CheckFrameLocals
- 删除 after_usb / after_vga / pre_devfs_fb0 / pre_explorer 四处校验调用
- devfs_register_fb0 恢复直接使用 __init__ 里的局部几何
  (原先为规避局部量被写坏,改为从 BootInfo 重取)
2026-10-27 11:54:41 +08:00
TermiNexus f43951c1f8 fix(fat32): 以 . / .. 结尾的路径会误开第一个子目录
dir_open_path 在 follow_path 返回后仍按“父目录中的最后一项”回读目录项。
当路径以 “.” 或 “..” 结尾时,follow_path 已经把 dp 打开成目标目录,
这段回读会把目标目录的第一个子项当成最终项再打开:

  根目录 cd .. → full=/.. → follow_path 打开根 → 回读根的第一项 APP
  → 实际进入 /APP,于是 ls 显示的是 app 里的 helloworld.asm。

现在检测末尾的 “.” / “..”,与根路径一样直接返回已打开的 dp。
2026-10-26 23:10:38 +08:00
TermiNexus 329a60b123 feat(terminal): 裸 cd 显示当前路径并归一化 cwd
- 只输入 cd 时不再重置到根目录,改为打印当前路径(pwd 语义)
- 新增 _normalize_path:折叠重复分隔符、去掉 .、处理 ..,
  根目录下 cd .. 仍为 /
- _cwd 保存归一化后的路径,pwd/ls 不再出现 /app/../.. 这类串,
  也避免路径越 cd 越长
2026-10-26 23:09:19 +08:00
TermiNexus 338472e304 fix(vpui): Label 自然尺寸与 pack 交叉轴居中
Input Demo 的两个显示问题:

- Label 没有显式 w/h,构造后 w/h 恒为 0:pack 时按 0 尺寸计算,
  PACK_BOTTOM 的标签被贴到内容区底边之外(字模被裁),且不占纵向空间,
  后面的按钮与 Name: 标签重叠。新增 _fit_natural() 按文本最长行/行数
  计算自然尺寸,__init__ 与 config() 时更新。
- pack 在未 fill 时原先一律贴左上,导致 Submit 按钮紧贴左边缘。
  改为与 tkinter 默认 anchor=center 一致:TOP/BOTTOM 横向居中、
  LEFT/RIGHT 纵向居中,沿 pack 方向仍保留 padx/pady。
- redraw 先刷新窗口尺寸再 _do_layout(),避免 resize 后布局滞后一帧。
2026-10-26 23:04:25 +08:00
TermiNexus ad6f0f68a2 chore(boot): GOP 显示模式改用 22
同时精简 GOP 初始化处的冗余注释。bootx64.efi 为编译产物,已停止跟踪,
需要时用 build.py --bootloader 重编。
2026-10-26 22:41:52 +08:00
TermiNexus ca448eee98 chore(build): 移除 VPUI64 动态库并调整构建入口
- 删除 Libs/VPUI64(linker.ld / project.vpj / vpui64.vp),同步 README
- viperc 路径改到 ViperC/__vpcbuild__/output
- 新增 --nokernel(显式 --kernel 优先,且与 --kernel-only 互斥)
- 未编内核时的提示改为「跳过内核编译」
2026-10-26 22:41:47 +08:00
TermiNexus fa1a92b568 chore(terminal): 链接不再 --strip-all,保留符号
便于崩溃现场按地址反查函数,与内核保留符号的做法一致。
2026-10-26 22:41:39 +08:00
TermiNexus bc089a0c69 feat(diag): 用户态窗口渲染链路临时打点
沿 Scene3D → FBCanvas → vpui.redraw → window.flush → explorer 合成器逐段打点,
用于定位窗口内容不上屏停在哪一环:

- Explorer:fb 哨兵像素回读、建窗槽位回读、首个 FLUSH、首帧 back/fb/任务栏像素、
  每 240 帧统计槽位/最上层窗口矩形/中心像素/共享缓冲首像素
- vpui:首次 redraw(缓冲地址尺寸)、st1~st4 分段(malloc/铺底/控件/拷回)、
  首次 flush、FBCanvas 首绘的源缓冲与像素
- Scene3D:主线程预渲染 3 帧(非清屏像素计数、三角形命中/调用数)、渲染线程
  入口与每 60 轮采样;渲染线程参数类型改为 rawptr

以上均为临时诊断,定位完成后应移除。
2026-10-26 22:41:32 +08:00
TermiNexus 0c47d81767 feat(diag): 异常现场完整转储(裸串口通路 + 无错误码向量)
- isr.s:ISR_NOERR 也保存 RIP/CS/RFLAGS/RSP,_fault_err 用 -1 表示无错误码;
  两类宏都补存 rbx/rbp/r12(用户态 #PF 时 r12 常为出错 store 的目标对象基址)
- idt.vp:新增不经驱动/缓冲的裸串口输出(asm.outb),打印 rip/rsp/cs/flags、
  u 位、callee-saved、错误码;#UD 附带出错指令字节,#PF 附带 cr2
- 前 32 条异常打印完整现场,之后每次只补 '*',避免异常风暴刷爆串口
2026-10-26 22:41:14 +08:00
TermiNexus 8c31645c0f fix(gfx): floorf/ceilf 参数显式收窄为 float
min/max 是 double 内建,结果直接传给 floorf/ceilf 时编译器禁止隐式
double->float,实际会把 f64 的低 32 位当 f32 传参,使三角形包围盒取值全错。
内核 vesafb 与 Scene3D 两处光栅化同步修正。
2026-10-26 22:41:09 +08:00
TermiNexus 624554df01 fix(sched): 通过 rdi 传递用户线程入口参数
用户线程入口的第一个形参在 rdi,但 drop_to_user_mode 这条路径从未设置过 rdi,
thread_create(fn, arg) 的 arg 在用户侧一直是垃圾值。iretq 只恢复
RIP/CS/RFLAGS/RSP/SS,因此在 iretq 前显式 mov rdi 即可。
2026-10-26 22:40:10 +08:00