首页 Home.
-
自制操作系统(15):虚拟文件系统 在上一节我们实现了用户态程序的封装编译和加载,完善了系统调用和libc库、crt0,还把shell迁移到了用户空间。今天,我们要干点更激动人心的事情:实现一个基于ustar的文件系统! 不过,我们先来解决一些遗留问题… 一些遗留问题的解决 我们先来做一些收尾操作,之前有些todo的事项放了太久了,后面就积重难返了,所以我们现在集中解决下。 低地址资源重映射和清理 我们的mbi和pmm初始化时遗留的一些数据一直占据着低地址区域,我们是时候考虑它们的去向了。 mbi的数据只会在内核启动初期用到,所以我们可以直接把它清掉,但是记录pmm就需要重新做映 […]
2026年3月22日 3 次浏览 -
自制操作系统(14):独立用户态程序封装、编译与加载 上一节,我们终于把我们的一小段函数搬到了用户态,但是这个函数居然连调用libc的函数都做不到!看来,是时候把我们从用户态给分离出去了。 独立的用户态程序——简单示例 我们的征程当然不能止步于Hello world,接下来我们要独立编译出用户态的二进制程序,结合Grub Module加载程序到内存,我们再从Kernel_main读取内存内容创建进程。我们先写一个极简的程序来完成分离编译,后面再逐步完善。 独立编译准备 是时候在我们的根目录新建一个user目录来存放我们的用户态程序源文件了。我们先在底下创建一个Makefile: # 编译器设置 […]
2026年3月14日 4 次浏览 -
自制操作系统(13):用户态进程 上一篇,我们把内核态进程给收了下尾,完善了很多进程相关的特性,但是我们现在还是处于内核态。 而从这一节开始,我们终于要走出内核态,步入用户态的世界了。 用户态vs内核态 …但是我们为什么需要用户态进程呢? 你可能会想,用户态更安全,因为它只能够执行一些非特权指令,以及调用我们给它准备好的系统调用,而且即使用户态的进程崩溃了,也不会导致整个操作系统的崩溃,用户态的进程也有自己的虚拟地址空间,不会污染到内核空间。是的!这就是我们之前做内核进程时回避掉的一点:隔离!而今天我们就要来实现它。 用户态进程创建的基础设施 要创建用户态的进程,得思考下面两个问 […]
2026年3月10日 5 次浏览 -
自制操作系统(12):进程创建、调度与切换(下) 上一篇,我们在自制的操作系统中实现了一个初步的多进程实现,之所以说是初步实现,是因为现在多进程的调度器调度算法还不公平,而且调度时,不应该排除0号进程,而且我们能接受的入口点函数不应该排除带入参的情况。 分离shell 我们先做点简单的事,把shell从我们的0号进程分离开,作为1号进程,其实就是提取成一个函数,再在kernel_main用create_process去启动。 extern "C" void kernel_main(multiboot_info_t* mbi) { pmm_prepare(mbi); ... […]
2026年3月7日 4 次浏览 -
自制操作系统(11):进程创建、调度与切换(上) 在上几章,我们成功地在我们的操作系统实现了内存管理模块,我们可以申请任意的堆空间了。那么接下来,我们进行勇敢的迈进——来看看怎么实现多进程。 多进程的本质 要聊多进程就得先聊聊进程,通俗地讲,进程就是运行中的程序,程序在我们的硬盘上,只是一个简单的文件,我们按它的规则把它读到内存里面,再把我们”下一条要执行的指令“指向这个程序的入口点,下面就能让这个程序的指令协同其数据在CPU上运行,这才是一个进程。我们现在的内核进程就是这样的。 多进程的本质是时分复用。一个CPU同时只能执行一条指令,但是通过在不同进程之前的快速切换,看起来就会像是同时在运行 […]
2026年3月4日 3 次浏览 -
自制操作系统(10):内核堆分配器 在上一节,我们成功地实现了虚拟内存管理器,并把显存的映射进行了重新调整,但是现在我们能申请的内存粒度过大,如果有这么一种经常出现情况:我们只需要申请若干个字节的内存,余下的内存就是一种浪费,造成过多的内部碎片。因此我们需要为内核开发实现一个粒度更小的可用空间管理器,也就是内核堆分配器。有了这样的分配器,我们就能像使用用户态的malloc和free一样,用kmalloc和free申请堆内存了。 接口 老规矩,我们先通过外部的接口来判断它能为我们带来什么。 void kheap_init(); void* kmalloc(uint32_t size); void […]
2026年3月1日 4 次浏览 -
自制操作系统(9):虚拟内存管理 在上一节,咱们实现了用Multiboot协议拿到空闲物理内存的分布,以及用自己实现的物理内存管理器(PMM)对这些空闲内存进行管理。但是现在还有一个问题,我们从PMM拿到的都是物理内存地址,而我们已经开启了分页机制,这使我们面临两个问题: 1、不是所有的空闲内存物理地址,都有对应的页映射。也就是很大一部分物理内存,是没办法通过虚拟地址访问的。 2、即使是那些有对应页映射的物理内存,我们也没办法直接访问,需要将物理内存地址映射到虚拟地址才能使用这些空闲内存,目前我们是采用硬编码的方式(+0xC0000000); 那么接下来,我们要实现的虚拟内存管理,就能解决这两 […]
2026年2月26日 3 次浏览 -
自制操作系统(8):物理内存管理 上一节,我们开启了时钟中断并实现了sleep函数,最重要的是:我们把之前留下来的一个坑——高半区内核,给填上了。但是因为我们过于“硬核”的显存区域映射方式,我们又留下了一个新的坑,不过不用担心,我们接下来将要实现的内存管理,就是可以把这个坑填上的一个特性。 接下来,我们开始涉足内存管理的领域,来谈谈怎么样管理物理内存。 为什么要进行内存管理呢?说白了,我们现在的内存不像以前那样寸土寸金,但是也不是用之不竭的,最好就是无论是内核还是用户进程,需要用到内存的时候,我们能够在内存里面找到一块空闲的地方,然后分配给它;声明用不到的话,我们又能回收掉这段内存,以备不时之 […]
2026年2月23日 5 次浏览 -
自制操作系统(7):定时中断与sleep(),迁移内核到高半区 在上一节,我们成功地接管了键盘的中断,并重构了一些代码,实现键盘驱动,并实现了一个玩具Shell,今天我们要搞点硬核的东西,但是在此之前,我们先来点轻松的——实现一个sleep函数。 PIT(可编程间隔定时器) PIT接收一个保持一定频率(1,193,182 Hz)的振荡器产生的输入信号,然后根据通过栅极输入(Gate Input)编程的配置,在不同的频道产生不同的栅极输出。PIT与键盘一样也是一种硬件,都可以通过IO端口与CPU进行数据互通。因此,我们可以通过IO端口对其进行编程。 PIT逻辑上有三个频道,0号频道连向了PIC芯 […]
2026年2月21日 5 次浏览 -
自制操作系统(6):硬件中断与键盘驱动 上一篇文章我们设置了GDT与IDT,现在,我们的系统能处理软件中断了。今天,我们来让我们的操作系统具备处理硬件中断的能力。 硬件中断 硬件中断相对于软件中断,顾名思义就是由硬件向CPU发出的中断了,比如说键盘输入、硬盘读取等等,都会向CPU发送中断来告知硬件目前所处的状态以及新发生的一些事件。 但是硬件其实并不直接向CPU发送中断,它们俩的桥梁是一个叫8259 PIC(可编程中断控制器) 的芯片。 硬件中断重映射 由于一些早年的不兼容的设计,8259会有默认的,从IRQ到IDT的如下的映射: 主片 (Master PIC):负责 IRQ 0-7。在 IB […]
2026年2月18日 4 次浏览
-
博客历经半年沉寂再度复活!因服务器到期及备案波折,虽遭遇数据库丢失惨剧,终靠老备份与AI辅助完成重构。
2026年2月5日 -
记录端午期间赴高松、直岛及男木岛的《Summer Pockets》圣地巡礼,分享与同好不期而遇的惊喜及男木岛“口袋猫基地”的感动体验。
2025年6月6日 -
记录意外通过 JLPT N1 考试的心路历程。在备考有限、估分胶着的情况下压线过级,感叹运气之余,也重新审视了语言学习的门槛与价值。
2024年9月5日 -
记一次在富士山下的听觉旅程。当经典的旋律在现实景观中响起,音乐与风景交织成一份独特的旅行感悟。
2024年5月2日 -
韩国真的是“美食荒漠”吗?作者通过亲身经历,从10元的便利店泡面到600元的炭火烤肉,全方位测评首尔饮食文化,带你体验真实的韩国味道。
2023年12月22日 -
记录《原神》枫丹剧情后的感慨,通过一系列游戏精美截图表达对角色芙宁娜(Furina)的喜爱与致敬:“芙芙值得。”
2023年11月17日
