快捷搜索:

操作系统实战01——运行一个最简单的操作系统HelloOS

操作系统是所有软件的基础,所有上层软件都要依赖于操作系统提供的各种机制,才能运行
操作系统也是一个应用,但工业级的操作系统有着上千万行的代码,其难度不亚于研制一颗原子弹
这里我们通过实现一个简单的HelloOS,让你练练手,直观的感受一下

目录


一、HelloOS安装运行

先把程序跑起来了,我们再细究原理

    代码:HelloOS为极客时间《操作系统实战45讲》的例子,很不错的专栏,下载位置: 环境:我是在VMware + Ubuntu 16.04环境下运行的(别的环境也可以,但可能出现一些小问题),虽然Ubuntu有提供图形化界面,但掌握一些基本的linux命令更佳。 Ubuntu需要安装:gcc工具编译c语言(sudo apt-get install build-essential)、nasm汇编器(sudo apt-get install nasm)与make工具(读取当前一个叫“makefile”的文件,这个文件中写好了构建软件的规则,它能根据这些规则自动化构建软件)(sudo apt-get install make) 执行过程: 1)下载代码:(上面链接)到自己虚拟机上,如果是ubuntu图形化界面,可以直接通过火狐浏览器下载ZIP文件(其他方式:使用git下载也是一个不错的选择) 2)编译代码:在代码当前目录下执行:make命令 编译该项目,生成HelloOS.bin文件 3)grub启动配置: 我们将HelloOS作为一个操作系统启动项供grub启动,因此需要能够在PC启动时进入grub引导菜单,并选择启动HelloOS,为了能够每次启动时进入grub引导菜单,需要进行如下设置(/etc/default/grub): 更新grub:sudo update-grub 4)安装 Hello OS 我们编译得到了HelloOS.bin。但是我们还要让 GRUB 能够找到它,才能在计算机启动时加载它。GRUB 在启动时会加载一个 grub.cfg 的文本文件,根据其中的内容执行相应的操作,其中一部分内容就是启动项。GRUB 首先会显示启动项到屏幕,然后让我们选择启动项,最后 GRUB 根据启动项对应的信息,加载 OS 文件到内存。 1)Hello OS 的启动项(将其添加到 /boot/grub/grub.cfg 文件尾): menuentry HelloOS { insmod part_msdos #GRUB加载分区模块识别分区 insmod ext2 #GRUB加载ext文件系统模块识别ext文件系统 set root=hd0,msdos4 #注意boot目录挂载的分区,这是我机器上的情况 multiboot2 /boot/HelloOS.bin #GRUB以multiboot2协议加载HelloOS.bin boot #GRUB启动HelloOS.bin } 2)把 Hello OS.bin 文件复制到 /boot/ 目录下,最后重启计算机,你就可以看到 Hello OS 的启动选项了。 3)加入HelloOS后,发现报boot目录挂载的分区不存在,我们需要修改menuentry HelloOS’里面的boot分区为你自己Ubuntu上的 4)查看自己Ubuntu上的bootboot挂载的分区: 在上图的工作目录下点击按键c进入grub命令行下,在grub命令行里确认(通过确认(hd0,gpt3),可以查看到HelloOS.bin)。所以我的是在第一个磁盘,第3个分区下 5)修该启动项 insmod part_msdos 修改为 part_gpt set root=‘hd0,gpt3’ 6)再次重启Ubuntu(一个简单的HelloOS运行成功) 7)如果发生HelloOS.bin找不到 这个就是要确认boot的挂在路径是/还是/boot(在 Linux 系统的终端下输入命令:df /boot/) 文件系统 1K-块 已用 可用 已用% 挂载点 /dev/sda4 48752308 8087584 38158536 18% / 如果跟上面的一样,不用修改。 但是如果挂载点是/boot,需要把路径改为multiboot2 /HelloOS.bin 当然你也可以在grub命令行里面确认, 如果ls (hd0,gpt2)/boot 找不到boot目录,就 ls (hd0,gpt2)/,如果能看到HelloOS.bin,说明grub把boot设为root,路径前面不需要加boot了。

二、HelloOS构成

    1、MakeFile(这个文件中写好了构建软件的规则,make工具能根据这些规则自动化构建软件) 2、vgastr.c与vgastr.h: 控制计算机屏幕的显示 //彭东 @ 2021.01.09 void _strwrite(char* string) { char* p_strdst = (char*)(0xb8000); while (*string) { *p_strdst = *string++; p_strdst += 2; } return; } void printf(char* fmt, ...) { _strwrite(fmt); return; } 3、main.c:打印Hello OS 其中printf函数是自己实现的,调用的上面的函数 //彭东 @ 2021.01.09 #include "vgastr.h" void main() { printf("Hello OS!"); return; } 4、entry.asm:汇编代码,操作操作特定的硬件(代码就不展示了、辣眼睛,有兴趣的可以自己去读)

三、Grub原理

grub是一个引导程序,只要我们的 PC 机上安装了 Ubuntu Linux 操作系统,GRUB 就已经存在了。
    Hello OS 的引导流程 简单解释一下,PC 机 BIOS 固件是固化在 PC 机主板上的 ROM 芯片中的,掉电也能保存,PC 机上电后的第一条指令就是 BIOS 固件中的,它负责检测和初始化 CPU、内存及主板平台,然后加载引导设备(大概率是硬盘)中的第一个扇区数据,到 0x7c00 地址开始的内存空间,再接着跳转到 0x7c00 处执行指令,在我们这里的情况下就是 GRUB 引导程序。 作用 我们将HelloOS作为一个操作系统启动项供grub启动,因此需要能够在PC启动时进入grub引导菜单(上面的配置/etc/default/grub),并选择启动HelloOS。
经验分享 程序员 微信小程序 职场和发展