基于 Free Pascal 从零编写裸机操作系统(一)
前言绝大多数入门操作系统教程都会选用 C 语言很少有人尝试用 Pascal 开发裸内核。OSDev 官网提供了一套完整的 Free Pascal Bare Bones 最小操作系统示例无需依赖 DOS、Linux、Windows 标准库完全运行在 32 位保护模式下兼容 Multiboot 引导规范能直接被 GRUB、QEMU 加载。本文仅拆解全部源码汇编入口、控制台驱动、内核主程序、Multiboot 规范定义编译、链接、镜像制作、QEMU 运行脚本不在本文介绍范围。 参考原文https://wiki.osdev.org/Pascal_Bare_Bones前置说明编译器Free PascalFPC嵌入式裸机编译目标架构x86 32 位保护模式显示VGA 文本缓冲区0xB8000引导Multiboot v1 标准兼容 GRUB无标准库不能使用WriteLn、MemAlloc等系统相关函数所有 IO、内存读写手动实现一、汇编入口文件stub.asm作用声明 Multiboot 头部让 GRUB 识别这是合法内核镜像切换 32 位保护模式环境设置栈导出符号供 Pascal 调用跳转至 Pascal 内核主函数MainKernelnasm;///////////////////////////////////////////////////////// ;// // ;// Freepascal barebone OS // ;// stub.asm // ;// // ;///////////////////////////////////////////////////////// ;// ;// By: De Deyn Kim kimdedeynskynet.be ;// License: Public domain ;// ; ; Kernel stub ; ; ; We are in 32bits protected mode ; [bits 32] ; ; Export entrypoint ; [global kstart] ; ; Import kernel entrypoint ; [extern kmain] ; ; Posible multiboot header flags ; MULTIBOOT_MODULE_ALIGN equ 10 MULTIBOOT_MEMORY_MAP equ 11 MULTIBOOT_GRAPHICS_FIELDS equ 12 MULTIBOOT_ADDRESS_FIELDS equ 116 ; ; Multiboot header defines ; MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_MODULE_ALIGN | MULTIBOOT_MEMORY_MAP MULTIBOOT_HEADER_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC MULTIBOOT_HEADER_FLAGS) ; ; Kernel stack size ; KERNEL_STACKSIZE equ 0x4000 section .text ; ; Multiboot header ; align 4 dd MULTIBOOT_HEADER_MAGIC dd MULTIBOOT_HEADER_FLAGS dd MULTIBOOT_HEADER_CHECKSUM ; ; Entrypoint ; kstart: mov esp, KERNEL_STACKKERNEL_STACKSIZE ;Create kernel stack push eax ;Multiboot magic number push ebx ;Multiboot info call kmain ;Call kernel entrypoint cli ;Clear interrupts hlt ;Halt machine section .bss ; ; Kernel stack location ; align 32 KERNEL_STACK: resb KERNEL_STACKSIZE源码关键点解读Multiboot 头三行 magic/flags/checksum 是 GRUB 识别内核的核心位置不能偏移.bss段预留 16KB 静态栈裸机无动态内存分配栈必须静态声明GRUB 会把内存、磁盘等硬件信息结构体地址存入ebx入栈传递给 Pascal 内核内核执行完毕后死循环停机防止指令越界。二、VGA 控制台驱动单元console.pas作用封装底层 VGA 文本缓冲区操作实现清屏、打印字符、字符串、数字、十六进制是内核唯一输出接口对外导出可被汇编 / 内核主程序调用的过程。pascal{ ///////////////////////////////////////////////////////// // // // Freepascal barebone OS // // console.pas // // // ///////////////////////////////////////////////////////// // // By: De Deyn Kim kimdedeynskynet.be // License: Public domain // } unit console; interface var xpos: Integer 0; ypos: Integer 0; procedure kclearscreen(); procedure kwritechr(c: Char); procedure kwritestr(s: PChar); procedure kwriteint(i: Integer); procedure kwritedword(i: DWORD); implementation var vidmem: PChar PChar($b8000); procedure kclearscreen(); [public, alias: kclearscreen]; var i: Integer; begin for i : 0 to 3999 do vidmem[i] : #0; end; procedure kwritechr(c: Char); [public, alias: kwritechr]; var offset: Integer; begin if (ypos 24) then ypos : 0; if (xpos 79) then xpos : 0; offset : (xpos shl 1) (ypos * 160); vidmem[offset] : c; offset 1; vidmem[offset] : #7; offset 1; xpos : (offset mod 160); ypos : (offset - xpos) div 160; xpos : xpos shr 1; end; procedure kwritestr(s: PChar); [public, alias: kwritestr]; var offset, i: Integer; begin if (ypos 24) then ypos : 0; if (xpos 79) then xpos : 0; offset : (xpos shl 1) (ypos * 160); i : 0; while (s[i] Char($0)) do begin vidmem[offset] : s[i]; offset 1; vidmem[offset] : #7; offset 1; i 1; end; xpos : (offset mod 160); ypos : (offset - xpos) div 160; xpos : xpos shr 1; end; procedure kwriteint(i: Integer); [public, alias: kwriteint]; var buffer: array [0..11] of Char; str: PChar; digit: DWORD; minus: Boolean; begin str : buffer[11]; str^ : #0; if (i 0) then begin digit : -i; minus : True; end else begin digit : i; minus : False; end; repeat Dec(str); str^ : Char((digit mod 10) Byte(0)); digit : digit div 10; until (digit 0); if (minus) then begin Dec(str); str^ : -; end; kwritestr(str); end; procedure kwritedword(i: DWORD); [public, alias: kwritedword]; var buffer: array [0..11] of Char; str: PChar; digit: DWORD; begin for digit : 0 to 10 do buffer[digit] : 0; str : buffer[11]; str^ : #0; digit : i; repeat Dec(str); str^ : Char((digit mod 10) Byte(0)); digit : digit div 10; until (digit 0); kwritestr(str); end; end.源码关键点解读VGA_BUFFER_ADDR $B8000是 x86 实模式 / 保护模式通用文本显存地址无需 BIOS 中断每个字符占用 2 字节低字节 ASCII高字节颜色属性内置自动滚动逻辑打印超出 25 行时整体上移一行清空底部PChar兼容 C 字符串0 终止符方便和汇编交互数字打印不依赖标准库SysUtils手动实现进制转换缓冲区。三、Multiboot 规范常量定义multiboot.pas作用定义 Multiboot v1 标准的内存信息结构体、魔数、标志位内核主程序读取 GRUB 传入的硬件信息时使用。pascalunit multiboot; interface const KERNEL_STACKSIZE $4000; MULTIBOOT_BOOTLOADER_MAGIC $2BADB002; type Pelf_section_header_table_t ^elf_section_header_table_t; elf_section_header_table_t packed record num: DWORD; size: DWORD; addr: DWORD; shndx: DWORD; end; Pmultiboot_info_t ^multiboot_info_t; multiboot_info_t packed record flags: DWORD; mem_lower: DWORD; { Amount of memory available below 1mb } mem_upper: DWORD; { Amount of memory available above 1mb } boot_device: DWORD; cmdline: DWORD; mods_count: DWORD; mods_addr: DWORD; elf_sec: elf_section_header_table_t; mmap_length: DWORD; mmap_addr: DWORD; end; Pmodule_t ^module_t; module_t packed record mod_start: DWORD; mod_end: DWORD; name: DWORD; reserved: DWORD; end; Pmemory_map_t ^memory_map_t; memory_map_t packed record size: DWORD; { You can declare these two as a single qword if your compiler supports it } base_addr_low: DWORD; base_addr_high: DWORD; { And again, these can be made into one qword variable. } length_low: DWORD; length_high: DWORD; mtype: DWORD; end; implementation end.源码关键点解读packed record禁用内存对齐严格匹配 Multiboot 二进制布局mem_lower/mem_upper是本示例核心用于计算整机物理内存大小结构体指针由汇编kernel_entry.asm中ebx传入内核主程序。四、内核主程序kernel.pas作用程序入口MainKernel整合控制台、Multiboot 模块完成初始化、硬件信息打印、停机逻辑是整个操作系统顶层业务代码。pascal{ ///////////////////////////////////////////////////////// // // // Freepascal barebone OS // // kernel.pas // // // ///////////////////////////////////////////////////////// // // By: De Deyn Kim kimdedeynskynet.be // License: Public domain // } unit kernel; interface uses multiboot, console; procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: DWORD); stdcall; implementation procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: DWORD); stdcall; [public, alias: kmain]; begin kclearscreen(); kwritestr(Freepascal barebone OS booted!); xpos : 0; ypos 1; if (mbmagic MULTIBOOT_BOOTLOADER_MAGIC) then begin kwritestr(Halting system, a multiboot-compliant boot loader needed!); asm cli hlt end; end else begin kwritestr(Booted by a multiboot-compliant boot loader!); xpos : 0; ypos 2; kwritestr(Multiboot information:); xpos : 0; ypos 2; kwritestr( Lower memory ); kwriteint(mbinfo^.mem_lower); kwritestr(KB); xpos : 0; ypos 1; kwritestr( Higher memory ); kwriteint(mbinfo^.mem_upper); kwritestr(KB); xpos : 0; ypos 1; kwritestr( Total memory ); kwriteint(((mbinfo^.mem_upper 1000) div 1024) 1); kwritestr(MB); end; asm loop: jmp loop end; end; end.源码关键点解读MainKernel带[public]导出汇编call MainKernel可直接调用入参PMultibootInfo接收 GRUB 传入的硬件信息指针先校验 Multiboot 魔数防止非 GRUB 引导导致内存读取崩溃纯汇编内嵌clihlt关闭中断停机裸机无操作系统异常处理末尾默认begin..end是 FPC 标准程序占位裸机环境不会触发执行。五、整体源码结构梳理plaintextPascal-BareBones/ ├─ kernel_entry.asm 汇编引导入口Multiboot头 ├─ multiboot.pas Multiboot硬件信息结构体定义 ├─ console.pas VGA控制台底层驱动单元 └─ kernel.pas 内核主程序系统业务逻辑六、源码运行逻辑完整流程GRUB 加载镜像识别.multiboot头部把硬件信息存入 EBX执行kernel_entry.asm初始化栈压入 EBX 指针调用MainKernelPascal 内核执行清屏 → 校验 Multiboot 合法性 → 打印内存硬件信息 → 死循环停机所有屏幕输出均调用console.pas封装的 VGA 显存操作无任何 BIOS/DOS 系统调用。七、拓展改造方向基于现有源码完善 VGA 颜色属性实现彩色文字输出增加键盘中断 IRQ1 驱动实现字符输入新增简单堆内存管理器替代静态变量扩展 Multiboot 模块读取磁盘、模块加载信息增加简单多任务调度框架基于 Pascal 过程实现线程切换。结尾这套源码完整实现了最小可用 Pascal 裸内核全程不依赖任何操作系统标准库所有硬件交互代码自主可控。相比 C 语言 OS 教程Pascal 强类型、单元模块化的特性让底层硬件结构体、驱动代码可读性更高。下一篇博文我会讲解编译脚本、链接脚本、GRUB 镜像制作与 QEMU 运行完整流程。

相关新闻

【方达炬治学】方达炬:在地球表面设置22°气温生命环境线,作为生命宜居带,确立生命活动周期同太阳活动相适应、及应对太阳工程日光威胁。

【方达炬治学】方达炬:在地球表面设置22°气温生命环境线,作为生命宜居带,确立生命活动周期同太阳活动相适应、及应对太阳工程日光威胁。

【方达炬治学】方达炬:在地球表面设置22气温生命环境线,作为生命宜居带,确立生命活动周期同太阳活动相适应、及应对太阳工程日光威胁。

2026/8/1 3:41:09 阅读更多 →
应届生注意:别浪费在校时间,AI能力将成为求职分水岭

应届生注意:别浪费在校时间,AI能力将成为求职分水岭

2026届全国普通高校毕业生规模达1270万人,同比增加48万,再创历史新高。 几乎同一时间,国家发改委在2026世界人工智能大会上公布:重点行业人工智能整体渗透率突破80%,今年相关产业增速预计超30%;工信部同步披…

2026/8/1 3:41:09 阅读更多 →
从“对话“到“执行“:MCP协议如何统一AI Agent与真实世界的连接方式?

从“对话“到“执行“:MCP协议如何统一AI Agent与真实世界的连接方式?

从"对话"到"执行":MCP协议如何统一AI Agent与真实世界的连接方式?当AI Agent只会"纸上谈兵"的时代终结,MCP协议正在成为连接认知与行动的统一桥梁。本文深入解析MCP的核心架构、无状态化演进,以及它…

2026/8/1 3:41:09 阅读更多 →

最新新闻

红外避障模块原理、电路拆解与Arduino实战应用指南

红外避障模块原理、电路拆解与Arduino实战应用指南

1. 项目概述:从“看见”到“避开”的智能感知在机器人、智能小车或者自动化设备的世界里,让机器“看见”并主动避开障碍物,是实现自主移动最基础、也最关键的一步。这听起来像是科幻电影里的场景,但其实实现它的核心元件&#xff…

2026/8/1 4:21:25 阅读更多 →
从零构建数字钟:嵌入式系统设计实战与工程思维训练

从零构建数字钟:嵌入式系统设计实战与工程思维训练

1. 项目概述:从零到一,亲手打造一个会“思考”的数字钟数字钟,听起来是个老掉牙的电子实验项目,对吧?不就是几个数码管,一个单片机,显示个时间而已。但如果你真这么想,可能就错过了这…

2026/8/1 4:21:25 阅读更多 →
Linux命令行进度条实现原理:从ANSI控制码到Python库实战

Linux命令行进度条实现原理:从ANSI控制码到Python库实战

1. 项目概述:为什么我们需要一个命令行进度条?在Linux世界里,我们每天都在和命令行打交道。无论是编译一个大型项目、复制海量文件,还是执行一个需要长时间运行的数据处理脚本,终端窗口里那个沉默的、不断闪烁的光标&a…

2026/8/1 4:21:25 阅读更多 →
从困惑度到BLEU:深入理解NLP模型评估指标的核心原理与实战权衡

从困惑度到BLEU:深入理解NLP模型评估指标的核心原理与实战权衡

1. 从“模型说人话”到“模型说好话”:评价指标的双重使命在自然语言处理(NLP)领域,尤其是大语言模型(LLM)如火如荼的今天,我们常常会听到两个词:“perplexity”和“BLEU”。前者&am…

2026/8/1 4:21:25 阅读更多 →
MEMD信号分解技术:原理、实现与工业应用

MEMD信号分解技术:原理、实现与工业应用

1. 多元经验模式分解的核心概念与应用场景多元经验模式分解(Multivariate Empirical Mode Decomposition, MEMD)是一种处理非平稳、非线性信号的有效方法。我第一次接触这个技术是在分析工业设备振动数据时,当时传统傅里叶变换对非平稳信号的…

2026/8/1 4:21:25 阅读更多 →
MoPaaS:面向现代化应用的云原生PaaS平台核心能力与选型指南

MoPaaS:面向现代化应用的云原生PaaS平台核心能力与选型指南

1. 从“云原生”到“应用平台”:为什么我们需要MoPaaS?如果你是一名开发者,或者负责过应用上云的项目,大概率对IaaS(基础设施即服务)和PaaS(平台即服务)这两个词不陌生。IaaS解决了服…

2026/8/1 4:20:25 阅读更多 →

日新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →