_shadow_alpha() measured the distance to the window's bounding rectangle, so WIN11/WIN7/WINXP shadows still had square corners: the rounded corner notch stayed unshadowed and the outer iso-alpha lines met at a right angle. Measure against the rectangle inset by the window radius instead. The corner arcs now shape both the notch and the outer falloff, while the straight edges keep the previous values. Square styles pass r = 0 and are unchanged.
ViperOS
A bare-metal 64-bit operating system written in the Viper language. Boots via UEFI, ships a self-implemented FAT32 driver, runs ELF-format user applications, and includes a complete user-space SDK.
用 Viper 语言编写的裸机 64 位操作系统。UEFI 启动、自研 FAT32 驱动、运行 ELF 格式用户程序,配套完整的用户态 SDK。
中文
这是什么
ViperOS 是 Viper 语言的旗舰演示项目:一个完整可启动的操作系统。和"Linux 发行版"或"教学用 mini-OS"不同,ViperOS 用 Viper 写一切——内核、设备驱动、用户程序、库、SDK 都用同一种语言(Viper 的 Python 语法 + LLVM 后端)。
主要组成:
- VKernel —— 64 位微内核(x86_64-none-elf 目标)
- UEFI 引导器 ——
boot/boot.c(GNU-EFI 编译为disk/EFI/BOOT/bootx64.efi) - FAT32 驱动 —— 自研实现,支持挂载、目录、文件操作
- 4 个用户应用 —— HelloWorld / Terminal / Gargantua / Scene3D
- 1 个动态库 —— SerialLogger
- ViperPOS SDK —— 用户态开发库(系统调用、窗口、文件系统、进程)
目录结构
ViperOS/
├── .gitignore # 忽略所有 output/、temp/、构建产物
├── build.py # 顶层构建入口:构建→打包→启动 QEMU
├── linker.ld # 顶层链接脚本
├── boot/ # UEFI 引导器
│ ├── Makefile
│ └── boot.c
├── VKernel/ # 内核
│ ├── project.json # 内核构建配置
│ ├── linker.ld
│ └── Kernel/
│ ├── main.py # 内核入口
│ ├── bootinfo.py
│ ├── drivers/ # 驱动
│ │ ├── core/cpu/ # APIC、CPU、FPU
│ │ ├── devfs/ # 设备文件系统
│ │ ├── fs/fat32/ # FAT32 驱动(自研)
│ │ ├── input/ # 键盘、鼠标
│ │ ├── serial/ # 8250 UART
│ │ ├── storage/ # IDE
│ │ ├── usb/ # USB HID / UHCI
│ │ └── video/ # VESA Framebuffer + UI
│ ├── execrunner/ # ELF 加载器
│ ├── intr/ # 中断子系统(GDT/IDT/ISR/Syscall)
│ ├── mm/ # 内存管理
│ ├── paging/ # 分页
│ ├── sched/ # 协程、进程、调度
│ ├── services/ # 内核服务
│ └── platform/ # 平台相关(PIC/PIT/RTC/Timer)
├── Apps/ # 用户应用(每个子目录一个独立 ELF)
│ ├── HelloWorld/
│ ├── Terminal/
│ ├── Gargantua/
│ └── Scene3D/
├── Libs/ # 动态库(每个子目录一个 .so)
│ └── SerialLogger/
├── vpsdk/ # ViperPOS SDK(应用开发用)
│ ├── __init__.py
│ ├── stdlib.py
│ ├── syscall.py
│ ├── window.py
│ ├── vpui.py
│ ├── fs.py
│ ├── process.py
│ ├── dynlib.py
│ └── wiki/ # SDK 自带 wiki
├── Scripts/
│ ├── check_disk.py
│ ├── disk.ps1 # ImDisk 打包 FAT32 镜像
│ └── disk.sh # Linux 等价脚本
└── disk/ # 被打包进 disk.img 的文件
├── EFI/BOOT/bootx64.efi
├── app/helloworld.asm
├── apps/ # .elf 拷贝目标(构建时填充)
├── libs/ # .so 拷贝目标(构建时填充)
└── sys/kernel/x86_64/kernel.bin
前提条件
| 工具 | 说明 |
|---|---|
python ≥ 3.10 |
运行 TransPyC 编译器 |
llc |
LLVM 静态编译器 |
ld.lld |
LLD 链接器(裸机版本) |
qemu-system-x86_64 |
QEMU 模拟器 |
imdisk |
Windows 下创建/挂载磁盘镜像的驱动;Linux 平台用 disk.sh 替代 |
gnu-efi 工具链 |
编译 UEFI 引导器(boot/boot.c) |
| TransPyC | 编译器,必须克隆在与 ViperOS 同级的目录 |
目录布局要求:
D:\Users\TermiNexus\Desktop\TransPyC\
├── TransPyC\ # 编译器仓库
├── ViperOS\ # 本仓库
└── ViperTemplateProject\
快速开始
# 1. 在 ViperOS 目录下直接运行
cd D:\Users\TermiNexus\Desktop\TransPyC\ViperOS
# 2. 完整构建并启动 QEMU
python build.py
# 3. 串口日志写入 serial.log
build.py 会自动完成:
- 调用
Projectrans.py编译 VKernel →VKernel/output/kernel.bin - 编译 1 个动态库(SerialLogger)
- 编译 4 个应用(HelloWorld、Terminal、Gargantua、Scene3D)
- 拷贝所有产物到
disk/apps/、disk/libs/、disk/sys/kernel/x86_64/ - 调用
Scripts/disk.ps1创建 64MB FAT32 镜像disk.img - 启动 QEMU(TCG 加速、
-no-reboot防止三重错误后重启)
退出 QEMU 后查看 serial.log 可看到内核启动日志。
常用构建参数
python build.py --noclean # 不清缓存,保留 temp/ 加速二次构建
python build.py --kernel-only # 只重编译内核,跳过应用和库
⚠ 不支持 --noqemu(build.py 第 76 行注释明确"不准使用 --noqemu")。
添加新应用
- 在
Apps/下新建目录,例如Apps/MyApp/ - 创建
App/MyApp/main.py(参考Apps/HelloWorld/main.py) - 创建
App/MyApp/project.json(参考Apps/HelloWorld/project.json,注意triple = "x86_64-none-elf"、linker用ld.lld输出.elf) - 在
build.py中追加构建 + 拷贝命令 - 在
disk/apps/MyApp/目录放应用需要的资源(运行时通过 vpsdk 访问)
添加新驱动
在 VKernel/Kernel/drivers/<子系统>/<设备>/ 下添加 <设备>.py,参考 fs/fat32/fat32.py(最大的驱动,自研 FAT32 完整实现)。在 VKernel/Kernel/main.py 中注册驱动初始化。
平台说明
| 平台 | 状态 |
|---|---|
| Windows 10/11 + mingw + QEMU | ✅ 主平台,CI 测试覆盖 |
| Linux x86_64 + clang + QEMU | ⚠ 理论可用,需把 build.py 改用 disk.sh,ld.lld 用系统 lld |
| macOS | ❌ 未测试 |
| 真实硬件 | ❌ 暂未支持(仅 UEFI x86_64) |
调试
- QEMU 串口日志:
build.py启动时把-serial file:serial.log,所有printf写到该文件 - GDB:
qemu-system-x86_64加-s -S然后用gdb连localhost:1234 - 崩溃排查:
build.py默认带-no-reboot,避免三重错误后无限重启
进一步阅读
English
What is this
ViperOS is the flagship demo of the Viper language: a complete bootable operating system written in Viper. Unlike a Linux distro or a teaching mini-OS, ViperOS uses one language for everything — kernel, device drivers, user programs, libraries, SDK all use Viper (Python syntax + LLVM backend).
Main components:
- VKernel — 64-bit microkernel (target
x86_64-none-elf) - UEFI bootloader —
boot/boot.c(compiled by GNU-EFI todisk/EFI/BOOT/bootx64.efi) - FAT32 driver — self-implemented, supports mount/dir/file operations
- 4 user applications — HelloWorld / Terminal / Gargantua / Scene3D
- 1 dynamic library — SerialLogger
- ViperPOS SDK — user-space development kit (syscall, window, fs, process)
Directory layout
ViperOS/
├── .gitignore # ignores all output/, temp/, build artifacts
├── build.py # top-level build entry: build -> pack -> QEMU
├── linker.ld # top-level linker script
├── boot/ # UEFI bootloader
│ ├── Makefile
│ └── boot.c
├── VKernel/ # kernel
│ ├── project.json # kernel build config
│ ├── linker.ld
│ └── Kernel/
│ ├── main.py # kernel entry
│ ├── bootinfo.py
│ ├── drivers/ # device drivers
│ │ ├── core/cpu/ # APIC, CPU, FPU
│ │ ├── devfs/ # device filesystem
│ │ ├── fs/fat32/ # self-implemented FAT32 driver
│ │ ├── input/ # keyboard, mouse
│ │ ├── serial/ # 8250 UART
│ │ ├── storage/ # IDE
│ │ ├── usb/ # USB HID / UHCI
│ │ └── video/ # VESA framebuffer + UI
│ ├── execrunner/ # ELF loader
│ ├── intr/ # GDT/IDT/ISR/syscall
│ ├── mm/ # memory management
│ ├── paging/ # paging
│ ├── sched/ # coroutine, process, scheduler
│ ├── services/ # kernel services
│ └── platform/ # platform glue (PIC/PIT/RTC/Timer)
├── Apps/ # user apps (each subdir = one ELF)
│ ├── HelloWorld/
│ ├── Terminal/
│ ├── Gargantua/
│ └── Scene3D/
├── Libs/ # shared libraries (each subdir = one .so)
│ └── SerialLogger/
├── vpsdk/ # ViperPOS SDK (for user apps)
│ ├── __init__.py
│ ├── stdlib.py
│ ├── syscall.py
│ ├── window.py
│ ├── vpui.py
│ ├── fs.py
│ ├── process.py
│ ├── dynlib.py
│ └── wiki/ # SDK wiki
├── Scripts/
│ ├── check_disk.py
│ ├── disk.ps1 # ImDisk-based FAT32 image builder
│ └── disk.sh # Linux-equivalent
└── disk/ # files packed into disk.img
├── EFI/BOOT/bootx64.efi
├── app/helloworld.asm
├── apps/ # .elf destination (filled at build time)
├── libs/ # .so destination (filled at build time)
└── sys/kernel/x86_64/kernel.bin
Prerequisites
| Tool | Notes |
|---|---|
python ≥ 3.10 |
runs TransPyC |
llc |
LLVM static compiler |
ld.lld |
LLD linker (bare-metal) |
qemu-system-x86_64 |
QEMU emulator |
imdisk |
Windows disk-image mount utility; on Linux use disk.sh instead |
gnu-efi toolchain |
builds the UEFI bootloader (boot/boot.c) |
| TransPyC | compiler; must be cloned as a sibling of ViperOS |
Required layout:
D:\Users\TermiNexus\Desktop\TransPyC\
├── TransPyC\ # compiler repo
├── ViperOS\ # this repo
└── ViperTemplateProject\
Quick start
# 1. From the ViperOS directory
cd D:\Users\TermiNexus\Desktop\TransPyC\ViperOS
# 2. Full build and launch QEMU
python build.py
# 3. Serial log is written to serial.log
build.py automatically:
- Calls
Projectrans.pyto build VKernel ->VKernel/output/kernel.bin - Builds 1 shared library (SerialLogger)
- Builds 4 applications (HelloWorld, Terminal, Gargantua, Scene3D)
- Copies all artifacts into
disk/apps/,disk/libs/,disk/sys/kernel/x86_64/ - Calls
Scripts/disk.ps1to create a 64MB FAT32 imagedisk.img - Launches QEMU (TCG accel,
-no-rebootto prevent reboot on triple fault)
After quitting QEMU, inspect serial.log for kernel boot messages.
Common build flags
python build.py --noclean # keep temp/ to speed up subsequent builds
python build.py --kernel-only # only rebuild the kernel, skip apps/libs
--noqemu is NOT supported (see comment at line 76 of build.py).
Adding a new application
- Create a directory under
Apps/, e.g.Apps/MyApp/ - Add
App/MyApp/main.py(seeApps/HelloWorld/main.pyfor reference) - Add
App/MyApp/project.json(seeApps/HelloWorld/project.json; settriple = "x86_64-none-elf", link withld.lldto produce.elf) - Add build + copy commands in
build.py - Put any runtime resources in
disk/apps/MyApp/(read at runtime via vpsdk)
Adding a new driver
Add <device>.py under VKernel/Kernel/drivers/<subsystem>/<device>/. See fs/fat32/fat32.py (largest, full FAT32 implementation). Register the init in VKernel/Kernel/main.py.
Platform support
| Platform | Status |
|---|---|
| Windows 10/11 + mingw + QEMU | ✅ primary, CI-tested |
| Linux x86_64 + clang + QEMU | ⚠ theoretically works, requires modifying build.py to use disk.sh and system lld |
| macOS | ❌ untested |
| Real hardware | ❌ not yet (UEFI x86_64 only) |
Debugging
- QEMU serial log:
build.pypasses-serial file:serial.log; allprintfoutput goes there - GDB: add
-s -Stoqemu-system-x86_64and attachgdbtolocalhost:1234 - Crash triage:
build.pyalways uses-no-reboot, avoiding reboot loops after triple faults