# yogaOS **Repository Path**: YOYOYOYOGA-seu/yogaOS ## Basic Information - **Project Name**: yogaOS - **Description**: 支持优先级、时间片调度的,采用页式虚拟内存管理的玩具操作系统(x86) - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-06-21 - **Last Updated**: 2025-07-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # **yogaOS** 一个玩具内核特性如下: 1、支持优先级、时间片调度 2、一个采用POSIX标准的系统(仅有很少部分的接口。。。) 3、采用页式虚拟内存管理 4、文件系统(还未设计。。。) 5、目前是在x86上运行的,希望能够多架构支持(至少在设计上是这么考虑的,虽然不一定有时间移植) # 源文件结构 ![图片不存在](https://gitee.com/YOYOYOYOGA-seu/yogaOS/raw/master/readme/structure.png) # 开发日志 2020.2.01 - 2020.2.22 完成x86架构下系统由MBR -> loader -> 载入系统 的内容 * 2020.2.22 x86 架构下的线性地址映射方式: 1、用户程序一律从线性地址4M处开始 2、用户堆栈与系统堆栈都放在线性地址0x0000处 3、用户页表中系统内核区域(0x1000至1M,2M-4M)为物理地址一一对应的映射方式 4、进程页表目录、页表与系统内核使用的页表统一映射到同一线性地址处(1M处) 5、系统内核页表采用与物理地址一一映射的方式(无效的物理地址不做线性地址映射,最大物理内存支持为1023*1024 = 1G ) 6、初步完成PCB结构体架构无关成员的初始化 * 2020.2.22 - 25 1、完成了PCB初始化与简单的页式内存管理 2、重新组织了内存分布 3、抛弃了段式内存管理,仅在初始化时简单使用 4、地址分布可能还需要更改,将实际的物理空间全部映射到高地址处(系统线性地址基址改到1G处,并附带映射整个物理空间),这样可以去除内核页表,在进入内核态时(比如管理物理空间,分配物理内存等)可直接使用任务页表,不需要切换到内核表 * 2020.2.26 1、最终定稿(也许并不是最终)了x86架构下线性地址空间的分布 2、完成了系统任务初始化中的页表与线性地址初始化 * 2020/3/1 1、第一次提交仓库 2、终于完成了历史性的多任务按时间片调度功能 3、事实上现在仅仅能够实现基本的任务调度,和仅仅实现页分配(还不能回收与换页)的内存管理 4、在地址空间的分配上花了很多时间,才最终暂时确定了现在的物理内存空间和线性地址空间的布局结构 5、之前从没接触过x86,不过还是觉得x86并不是一个简单的漂亮的架构,相比于arm显得比较脏乱,在弯弯绕架构上花费了绝大部分的时间(保护模式与段式内存管理处理除了向下兼容,还有什么具体的意义?) * 2020.3.8 - 3.9 1、加入了任务延时挂起功能(suspend list) 2、完成了系统调用的框架雏形(x86下使用0x80号中断) 3、添加完成了sleep()、getpid()两个POSIX接口api(通过系统调用) * 2020.3.21 - 3.22 1、加入的键盘驱动(刚刚实现键盘的简单输入(字母键与数字等),与回显) 2、为了测试将显卡显存段的dpl改为了3(方便在应用中直接显示) 3、现在的tty测试进程写在了main.c中,后期考虑单独弄成可执行文件或放在server文 件夹中 4、修改了一处bug,./arch/x86/lib/asm.S 中进入系统调用中断的函数没有对传参的寄存器进行保存与恢复,导致返回进程后寄存器值丢失发生错误 5、**整理代码!!!整理代码!!** * 2020.3.26 1、解决了键盘读buff的bug(循环赋值时没有递增接收buff指针,导致丢键) 2、加入了特殊键的识别(ESC、SHIFT、ALT等) 3、**现在不得不思考到底是走向宏内核还是微内核。微内核虽然易于扩展,但是由于很多内核服务都是以进程的形态工作用户态下的,对于个人开发来说难以调试;宏内核对于初期开发来说具有很多方便的地方,并且效率更高,但是对于添加模块、移植来说更为困难(特别是对于嵌入式arm这种外设繁的环境来说)** 4、**现在的想想法是内存管理与进程调度仍然工作在内核态下(在系统调用中直接完成),一是更方便调试,而更利于保证实时性(也许是?),而驱动部分、文件系统尽量放在用户态服务进程中完成(系统调用与外部中断只作信号量传递),也许是一种混合内核?** * 2020.3.27-3.28 1、根据微内核驱动模型搭建了tty驱动框架,分为顶层的驱动tty服务进程,中间的驱动处理函数以及底层的硬件操控api接口 2、**重新整理了源码文件结构,一些名称的改变,以及将虚存管理(页式内存管理)放在了kernel/mm下(内核的自身的运行必须依赖虚存管理,任务调度,内存管理是OS最核心的两个部分),根目下外的mm则改为存放后期物理内存管理的模块(malloc,堆内存管理等)** 3、实现了3个tty的切换,并且实现了中换行、翻页的功能 4、修改了arch/include/driver 下io.h io操作函数中的bug 5、在lib库中加入队列功能(lib/queue.c),将需要使用队列的地方封装成库 6、**调度器改动:为了实现微内核,x86架构将内核服务进程的dpl改为1,优先级处于0,1下;而之后的用户任务(通过fork创建,需要文件系统支持)则处于其他优先级下,并且dpl=3;内核态下dpl = 0** * 2020.3.28 1、更改了x86页表的特权限制,现在内核空间的页不在能被用户task访问(dpl = 3),而系统服务进程与内核仍可以访问(dpl<3)不过文件缓存区内存则为所有用户进程共有,均可以访问 * 2020.4.4 1、调度器改动,将原来的单一优先级改为抢占优先级与时间片优先级(新加入),现在同一抢占优先级下的任务不再均等的享有时间片,而是根据时间片优先级分配(加入fork之后还会受到父子进程的影响,即父子进程共享时间片) 2、修改了x86 console驱动的几处BUG,更改了翻页逻辑 3、加入了tty对键盘backspace的处理 4、加入了printf族库函数与itoa等stdlib函数,实现格式化字符串与向TTY打印的功能(简易,还需扩充功能) 5、加入了临时的write()系统调用,供printf使用(没有文件系统) * 2020.4.19 1、加入了控制台字体色彩改变功能(通过写"/033[0;31;42m "控制码的方式改变对应tty显示字体的前景背景色以及样式) 2、加入了内核使用的assert()宏定义(x86下处于dpl1的服务进程也可以使用(dpl0-2均拥有访问权限)) 3、改变了调度器pid分配方式,由原先的无限分配改为加入全局PCB指针数组(主要是为了方便后面进程间通信通过dpl定位进程),拥有有限的最大运行数,pid可循环利用 * 2020.5.12 1、构思了一下系统用进程间通信结构request,现在的构思是仅被系统任务使用,故不封装成库,具有一个根据优先级排列的等待链表 2、增加了sleep超过系统最大时间(0xFFFFFFFF,单位10ms)即永久不会唤醒的功能 * 2020.6.26 1、更改了之前的几处bug,改动了一些文件结构,将系统独有的库函数放在新的libh/yogaOS目录下,同时将系统调用的处理函数从arch/xxx/kernel下放在了根目录kernel下(系统调用的实现是架构无关的C文件) 2、更改了几处bug包括list删除函数添加pOwnList置零,解决系统调用返回值被覆盖等; 3、将tty驱动的某些警告等文字输出由printk实现改为直接调用写函数(原先使用printk一是迂回了一步,二是内核用函数不应暴露给处于非内核态下的程序使用) 4、sched加入的新的库函数,同时加入的指向自身PCB的指针(架构有关,指向虚存映射PCB的块的首地址),将包括currentActiveTask在内的全局变量保护了起来(static),使对PCB的访问不在通过currentActiveTask(直接访问物理内存线性存映射区)而是通过每个任务私有的虚存映射访问(避免当currentActiveTask切换而不是指向当前还在运行的任务的PCB的情况) * 2020.6.27 1、完成了第一版的request进程间通信功能(注释详情见文件),顶层封装成库(libh/yogaOS/yogaOS/req.h),将所有的通信功能实现放在了内核态下; 2、用户发送时,需要先将信息写入一个临时的request结构体内,通过指针传入系统调用,在内核态下复制信息到pcb中的req结构体并加入到目标服务进程pcb下的请求等待列表中,并唤醒服务进程,自身睡眠等待; 3、服务进程通过reqw系统调用等待请求的到来,如果没有请求则睡眠,并返回状态码; 4、当服务进程被请求服务的进程唤醒后,会检查系统调用的返回值,如果这一次没有读到信息,就再次进入,此时等待列表中应有成员,固立即返回req信息;(等于某些时候需要两次系统调用才可以读到req信息) 5、服务进程处理完之后,可以选择直接返回req处理结果,通过reqa函数通过系统调用将结果写入请求源进程pcb中的req结构体,并唤醒,或者通过reqt传送至其他服务进程继续处理; 6、用户进程被唤醒后,可以调用reqr读取储存在pcb中req结构体中的结果信息,当不需要查看时,也可忽略直接进行下一步。 * 2020.7.16 1、线性地址布局更改,将原来1G的用户代码数据空间分割出512M给堆区; 2、在start.S中加入最大支持内存检测; 3、list中增加了一个可以快速配置自定义链表的宏定义,现在除了标准双链表、单链简表,多了一个更简单的可直接嵌入各结构体内的最简表和表项(宏定义形式) * 2020.8.1 1、增加了宏定义形式的迷你链表操作函数,包括初始化、插入表头表尾、弹出表头表尾第一个元素 2、构建buddy系统以管理物理内存 * 2020.8.8 1、完成了伙伴系统内存分配部分,替换完毕原来的线性表分配策略,可以正常使用 2、后续需要加入伙伴内存系统的收回部分,以构成完整的buddy内存管理 * 2020.9.6 1、加入伙伴系统内存回收 2、加入缺页中断处理(还需要补全) 3、后续需要加入exit函数 * 2020.9.12 1、完成伙伴系统单个页回收,同时加入函数回收整个page使用表中的页 ; 2、完成 exit() 函数的测试; 3、schedule细节优化 4、加入rand、srand标准库函数的实现 5、加入malloc、free标准库函数的实现 * 2020.10.31 1、完成了对x86架构下外部中断的统一管理,外部中断回调函数放在驱动文件中,通过注册的形式动态的加载,而不是与fault处理函数一样放在统一的文件中; 2、x86架构加入了单个外部中断的使能失能函数(8259A操作) * 2020.11.16 1、request模块改动,加入中断中使用的req等待/发送函数,可使用的超时函数,返回值一律为错误码; 2、修复因加载内核代码后未初始化其.bss段为0而引发的一系列BUG。 3、完成块设备、硬盘驱动的框架雏形,现在已经可以读取硬盘的基本信息。 `重写tty驱动(利用IPC)`