加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
目录.txt 10.32 KB
一键复制 编辑 原始数据 按行查看 历史
* code 目录下包含了按章节放置的课时源码
* diy-200lines-os: 包含了200行代码前置课程的工程代码
* image 开发操作系统时的磁盘映像,具体请参考视频内容
// boot实现
c03.01 计算机启动流程简介(无代码)
c03.02 接管计算机运行(无代码)
c03.03 创建可引导的启动程序
c03.04 初始化引导程序
c03.05 使用BIOS中断显示字符
c03.06 使用BIOS中断读取磁盘
c03.07 进入C语言环境并跳到loader
// loader实现
c04.01 利用内联汇编显示字符串
c04.02 检测内存信息
c04.03 切换至保护模式(1)
c04.04 切换至保护模式(2)
c04.05 使用LBA读取内核
c04.06 创建内核工程
c04.07 向内核传递参数
c04.08 代码/数据段与链接脚本
c04.09 加载内核映像文件
// 中断系统配置
c05.01 创建GDT表及其表项
c05.02 保护模式下的内存管理简介
c05.03 重新加载GDT
c05.04 触发运行中的异常(除0异常)
c05.05 添加门描述符定义
c05.06 初始化IDT表
c05.07 捕获除0异常
c05.08 利用栈解析异常栈中的参数
c05.09 模板化异常处理流程(利用宏)
c05.10 处理其它类型的所有异常
c05.11 初始化中断控制器
c05.12 中断的打开与关闭
c05.13 启动定时器并打开中断
// 字符串与格式化输出
c06.01 创建日志打印接口
c06.02 实现基本的信息输出
c06.03 字符串和内存工具函数实现
c06.04 实现字符串的格式化输出
c06.05 支持整数的格式化
c06.06 打印异常的信息
c06.07 断言与调试
// 实现简单的进程切换
c07.01 创建两个小任务
c07.02 添加任务状态段
c07.03 任务的简单初始化
c07.04 双任务相互切换
c07.05 另一种任务切换方法
c07.06 进程及进程的作用
// 重要的数据结构链表
c08.01 定义结点和链表
c08.02 链表的查询函数
c08.03 链表的两种插入
c08.04 链表的两种删除
c08.05 获取结点所在的结构
// 实现进程的管理与延时
c09.01 添加任务管理器
c09.02 将任务加入就绪队列
c09.03 进程主动放弃CPU: task_yield()
c09.04 让进程按时间片运行 (时间片切换任务时输出会有问题,在log_print中。效果看不出来,下一小节解决)
c09.05 临界资源及简单的保护
c09.06 让进程能够延时运行
c09.07 让所有进程都能延时(如果qemu长时间不在前台运行,可能会待机。vscode中任务输出会停止。将qemu放到前台后,输出将重新进行)
进程间的同步与互斥
c10.01 计数信号量及其初始化
c10.02 发送和等待信号
c10.03 使用计数信号量
c10.04 互斥锁及其初始化
c10.05 互斥锁的加解锁
c10.06 应用互斥锁
虚拟内存管理和保护模式
c11.01 内存管理问题
c11.02 位图数据结构与初始化
c11.03 位图位的分配
c11.04 创建地址分配结构
c11.05 规划内存空间的分配(在1MB空间中分配一个位图表,进行物理地址空间的分配)
c11.06 内存分页机制介绍
c11.07 开启内存分页机制(1) (在loader中开启分页。程序会跑飞,因为未在任务tss设置页表,值为0,所以导致计算机重启。)
c11.08 开启内存分页机制(2)
c11.09 创建内核页表(1)-建立映射表, 触发下异常
c11.10 创建内核页表(2)-页目录和页表结构(主要是页目录表的定义)
c11.11 创建内核页表(3)-完成映射 (注意lds中要加对齐,否则会出现pte-present=1,仍然会死机)
c11.12 创建内核页表(4)-添加权限处理
c11.13 为进程创建页表(解决了死机重启的问题)
// 隔离操作系统与进程
// 所有任务共享同一的代码和数据段,即Protected Flat Model
// 再回头回顾下手动切换时,对tss中ss0中的设置
c12.01 创建系统的第一个进程
c12.02 配置进程的加载地址和运行地址(运行会死机。通过readelf展示具体的init信息,说明加载地址和运行地址的区别.另,如果kernel运行在高地址,loader应当进行相应的存储映射配置)
c12.03 将初始进程搬运至指定位置 (不用搬运,用虚拟内存映射也是可以。这样用搬运好说明进程的一般运行机制)
c12.04 调整应用的特权级(当前first task仍然是运行在特权级0。切换发现出现page_fault,发现异常frame解析错误。因为切换至了idle_task,特权级3,不能运行特权级0的代码)
c12.05 调整异常处理函数(增加更详细的异常输出信息, 栈的变化要在12.07才能看到)
c12.06 修改空闲任务的特权级 (权限不能太低,方便执行特殊指令,同时避免被杀死)
c12.07 切换至用户特权级为最低(first仍然是特权级0状态下运行,所以更改,注意修改界面权限为us。注意esp0和esp3是一样,会导致问题,异常?)
c12.08 为进程添加特权级0的栈空间(去掉msleep和log_printf,否则仍会死机,。。。因为调用了os内核区的代码,没有权限访问)
// 建立系统调用
c13.01 创建调用门
c13.02 实现系统调用的调用和返回
c13.03 实现msleep系统调用
c13.04 实现getid系统调用
c13.05 实现pint_msg调用
c13.06 使用int $0x80实现系统调用
// 从磁盘加载程序运行
// 注意,需要将task_start()分离出来,以免fork()时task_init后立即定时器调用强制切换,导致fork失败
// 注意, 以前的工程中shell的加载地址为0x82000000,修了
// 所以提供下载了以前工程的同学进行修改,
c14.01 实现fork系统调用(1)- 添加调用接口
c14.02 实现fork系统调用(2)- 分配任务块
c14.03 实现fork系统调用(3)- 初始化任务块(子进程能跑,并返回到syscall调用中,但再次返回时跑飞,因为栈和父进程共用)
c14.04 实现fork系统调用(4) - 复制进程地址空间
c14.05 实现exec系统调用(1) - 创建一个空应用
c14.06 实现exec系统调用(2) - 增加空的exec调用
c14.07 实现exec系统调用(3) - 添加虚似文件访问接口
c14.08 实现exec系统调用(4) - 解析并加载elf文件
c14.09 实现exec系统调用(5) - 分配栈并进入进程执行(调用main时会死机,因为argc,argv的地址在栈空间外,不存在,所以导致页出错。可观察出错地址在0xe000xxx开头)
c14.10 实现exec系统调用(6) - 为进程传递参数
c14.11 添加sys_yield()系统调用
// 使用c标准库中的printf输出(文件系统框架和字符设备驱动程序,引用newlib)
c15.01 调整文件系统调用(注意,在链接脚本和cmake中添加了对lib_syscall的使用。特别是链接脚本进行了设置)
c15.02 导入newlib c并调用printf(实现几个相关的系统调用,测试会死机, 因sbrk为空。改的有点多)
c15.03 为malloc实现sys_brk调用
c15.04 简单的printf调用实现(输出至串口, write写len,需要填0)
// 使用控制台与键盘进行输入输出
c16.01 控制台简介与初始化
c16.02 在控制台上显示字符串(printf显示到屏幕上)
c16.03 处理换行和清屏
c16.04 设置光标并重定向日志输出到显示器
c16.05 有趣的转义字符串\b以及删除字符 (退格暂时不处理,以及删除字符)
c16.06 保存并恢复光标位置
c16.07 更新显示字体的颜色
c16.08 移动光标位置及清屏
c16.09 键盘初始化
c16.10 借助按键映射表进行键值转换
c16.11 处理caplock和numlock键
c16.12 处理其它特殊功能键
// 设备管理与文件系统(实现gets和printf,通过文件系统)
c17.01 设备管理框架简介(定义描述结构)
c17.02 增加tty设备
c17.03 实现dev层接口操作
c17.04 为tty设备添加结构描述
c17.05 实现tty设备的打开
c17.06 通过tty设备写显示数据
c17.07 文件系统简介及初始化
c17.08 为进程添加文件打开表
c17.09 打开tty设备并向其写入数据
c17.10 从tty读取键值字符串并显示
c17.11 打开标准输出及错误输出文件
c17.12 允许切换tty窗口(能切换窗口及输入,但不回显,因为要读取时才能回显,下一章解决)
c17.13 为每个tty窗口创建进程并保护(console还需要加上锁来防止多进程同时写,暂时不做,后面章节加)
// 实现一个命令行解释器:提供几个基础的命令,后续可以让学生自己根据,支持exit和wait
c18.01 初始化命令行解释器
c18.02 实现help命令的解析
c18.03 执行echo命令并给输出加点颜色
c18.04 为进程增加exit接口
c18.05 为进程增加wait接口
c18.06 让子进程继承父进程已打开的文件
// 使用文件系统管理硬件设备
c19.01 描述一个文件系统(调整中)
c19.02 挂载设备文件系统
c19.03 打开/dev/tty0文件(1) - 只打开devfs中的文件
c19.04 打开/dev/tty0文件(2) - 更通用的打开方式
c19.05 往/dev/tty0读写数据
// 磁盘与fat16文件系统
c20.01 磁盘基本特性简介(注意sdb的磁盘索引调整为1)
c20.02 识别系统中已有的磁盘
c20.03 解析磁盘分区表
c20.04 增加磁盘设备管理
c20.05 实现磁盘的读取和写入
c20.06 FAT16文件系统简介(添加文件系统接口)
c20.07 挂载FAT16文件系统
c20.08 遍历目录命令ls的实现(1)- 添加系统调用接口
c20.09 遍历目录命令ls的实现(2)- 列出虚假的目录内容
c20.10 遍历目录命令ls的实现(3)- 列出真实的目录内容
c20.11 文件查看命令less的实现(1)- 打开文件
c20.12 文件查看命令less的实现(2)- 显示部分文件内容
c20.13 文件查看命令less的实现(3)- 显示全部文件内容
c20.14 文件查看命令less的实现(4)- 逐行显示文件内容
c20.15 通过文件系统加载shell (shell的加载:注意修改脚本文件复制文件,针对不同平台测试)
c20.16 让shell加载应用程序运行 (loop的加载:复制调试脚本文件、cmakelist文件修改)
c20.17 应用运行异常时强制中断运行
c20.18 文件复制命令cp的实现(1)- 创建新文件
c20.19 文件复制命令cp的实现(2)- 删除文件
c20.20 文件复制命令cp的实现(3)- 文件写入
// 课程总结
c21.01 最后的调整与总结
后续计划:可能加入这个课程,也可能作为单独的扩展课程
* 一些有趣的小游戏支持
* 合并到一块磁盘上启动
* 信号:
* cpp的支持:使用C++编写应用程序
* 多线程库:允许用户程序中创建线程
* 命令行解释器:让解释器能够加载脚本运行,并执行脚本中的代码
* tcpip协议栈:能够通过网络进行通信
* 简单的图形界面:允许使用鼠标操作
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化