自己创建一个小操作系统

篇首语:迎接开源,拥抱成长,加油。。。。。。。。。

最近跟着教程完成了一个十分简单的操作系统,下面是主要步骤和我遇见的坑。

  1. 首先介绍一下我的安装环境:virtualBox 5.13.0 + ubuntu 20.04  x86_64(uname -a);
  2. 再查看虚拟机的网络情况,主机和虚拟机互ping一下,看看通不通,这里我遇见的问题是:虚拟机ping主机是通的,但是主机ping虚拟机是不通的,解决方案是:
  1. 查看虚拟机ip ($ip addr  或是 $ifconfig)都可以查到

inet 后面就是虚拟机的ip,(10.0.2.15)

  1. 在主机命令行,ping一下这个ip(10.0.2.15)  显示 请求超时;
  2. 打开虚拟机 -> 设置 -> 网络 ->连接方式,选择桥接网卡;
  3. $reboot;
  4. Ctrl+alt+T  $ifconfig
  5. 这时再次查看ip,就变成和windows上同一个网段的了,(我的是 192.168.1.x)
  6. 再次打开windows cmd ping下,这时是通的,ok!!!

(后面会介绍:连接方式那么多,为啥就桥接好用,其他的连接方式都是啥,为什么不能用,又在何种情况下会用到它们???)

  1. 主机和虚拟机的网络通了,方便互传文件,那么如何互传文件呢?

多种方式,我用的是ssh ,用的工具软件是 WinSCP ,下面是操作的步骤:

  1. 查看虚拟机上是否安装ssh服务 $ ssh localhost
  2. 如果显示(ssh: connection refused 表示没安装
  3. 先更新已经安装的工具包:$ sudo apt-get update;
  4. 再安装ssh:  $ sudo apt-get install openssh-server
  5. 如果安装失败,估计是没联网,可以查看2
  6. 下载WinSCP,  分享个百度云,有需要自取();
  7. 打开WinSCP,新建站点,在会话填写主机名,用户名和密码,然后登录。

 

 

主机名:zhangqi-VirtualBox     用户名:zhangqi

       (8)   如果你忘记密码,$passwd   就重置一下吧~;

       (9)   至此,安装步骤就完成了,下图是winSCP打开

(备注下:主机->虚拟机: 上传; 虚拟机->主机: 下载)

下面还会去介绍ssh是个啥,为什么它能传输文件,还有哪些宝藏功能。。。

  1. 有了传文件的工具,就可以把主机的文件传给虚拟机,emmm….我太懒。。。

1-3是准备工作,下面正式开始我们的小小OS之旅。。。

  1. 首先有个大体流程:
  1. PC机的引导流程(我理解:启动流程);

 

看了流程,可能会有一些疑问:

(1)  BIOS固件是什么?为什么PC机加电后首先就需要加载它?都干了啥?

(2)   加载BIOS是为加载可引导设备吗?可引导设备是什么样子的,是不是依赖于GRUB,GRUB是不是决定可引导设备是什么?

(3)   Hello OS是个什么类型的文件?里面的内容是操作系统吗?都写得是什么?

(4)PC开机,加载引导程序,找到存放OS文件的内存地址,加载,是这样吗?

解答:

复制一段文字…………:

PC BIOS 固件是固化在 PC 机主板上的 ROM 芯片中的,掉电也能保存,PC 机上电后的第一条指令就是 BIOS 固件中的,

它负责检测和初始化 CPU、内存及主板平台,

然后加载引导设备(大概率是硬盘)中的第一个扇区数据,

0x7c00 地址开始的内存空间,

再接着跳转到 0x7c00 处执行指令,在我们这里的情况下就是 GRUB 引导程序。

(此处是待填充的空白。。。。。。。)

  1. Hello OS引导汇编代码(也就是GRUB的引导程序)

下面有些自己的理解。。。

引导程序就是告诉用户要安装OS了,先做哪一步,再做哪一步。

GRUB(GRand Unified Bootloader)多操作系统启动程序,允许用户在计算机内同时拥有多个操作系统。

为什么GRUB引导程序要用汇编?

答:底层语言无外乎是C和汇编,汇编比C更加底层,更底层就意味着,给计算机发指令更加直白,(汇编难点就在于,你要明白1+1=2的在计算机中完整的实现流程,并写出来),C 作为通用的高级语言,不能直接操作特定的硬件,而且 C 语言的函数调用、函数传参,都需要用栈。(我理解:汇编可以直接操作硬件,并且数据可以直接访问寄存器,创建栈内存空间)

汇编学习-----看书王爽的《汇编语言》

这段引导程序都写点啥?

答:(1) 定义GRUB多引导协议头,目的是让GRUB可以识别我们自己写的Hello OS的操作系统,就是按照GRUB的方式来让它认识我们自定义的操作系统;

(2)关掉终端,设定CPU的工作模式;(不懂。。。)

(3)初始化CPU的寄存器和C语言的运行环境;(也就是开始创建栈内存,以及我们用C语言写的操作系统的内容了)

(4)GDT_START开始的,是CPU工作模式所需要的数据。(我写了什么。。。不懂);

这一步最后,我一直在纠结为什么引导,从PC加电到访问准备好CPU所需要的数据,都经历了哪些步骤?于是有个大神的原文如下:

答:在你安装完一个操作系统之后(就是把光盘镜像的文件或者GHOST文件丢到主分区)或者开机后,需要让计算机在开机的时候能识别电脑中的系统,这个过程就是系统引导,计算机系统引导的过程就是在保证硬件设备正常后,计算机利用CPU运行特定程序,通过程序识别硬盘,识别硬盘分区,识别硬盘分区上的操作系统,最后又通过程序启动操作系统。

我理解:说到底,并不是开机了就安装操作系统了,而是需要一步确认(硬件,CPU,硬盘等等都是好的),一步引导,我告诉你哪里可以找到操作系统。问题来了,如果一台裸机,没有OS,怎么去安装OS呢?

(64条消息) 操作系统引导详细过程_Adenialzz的博客-优快云博客_系统引导

还得再看。。。

  1. Hello OS的主函数

//彭东 @ 2021.01.09

#include "vgastr.h"

void main()

{

  printf("Hello OS!");

  return;

}

(这里的printf需要自定义,为什么?看下一步)

  1. 控制计算机屏幕

需求:我们要在屏幕上显示字符,

方案:就要编程操作显卡。

如何操作?

首先,无论何种显卡都支持VESA标准,这种标准下有两种工作模式:字符模式和图形模式。显卡们为了兼容这种标准,不得不自己提供一种叫 VGABIOS 的固件程序。

显卡的字符模式的工作细节:

它把屏幕分成 24 行,每行 80 个字符,把这(24*80)个位置映射到以 0xb8000 地址开始的内存中,每两个字节对应一个字符,其中一个字节是字符的 ASCII 码,另一个字节为字符的颜色值。

//彭东 @ 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;

}

  1. 编译和安装Hello OS

这里编译和安装需要准备nasm和gcc两个编译工具,如果没有自行下载

$sudo apt-get install -y nasm

$sudo apt-get install gcc

编译:

首先nasm是编译.asm汇编文件,命令 $nasm -f entry.asm -o entry.o -w-orphan-labels(后面-w-orphan-labels)表示不显示警告信息,;

然后gcc编译.c, 可以直接 $gcc HelloOS.c -c -o HelloOS.o;

也可以一步步来:其实编译.c程序主要分四步:

第一步:预处理 $gcc HelloWorld.c -E -o HelloWorld.i;

目的是加入头文件,替换宏。

 第二步:编译 $ gcc HelloWorld.c -S -c -o HelloWorld.s 

包含预处理,将 C 程序转换成汇编程序。

 第三步:汇编 $ gcc HelloWorld.c -c -o HelloWorld.o 

包含预处理和编译,将汇编程序转换成可链接的二进制程序。

第四步:链接 $ gcc HelloWorld.c -o HelloWorld 

包含以上所有操作,将可链接的二进制程序和其它别的库链接在一起,形成可执行的程序文件。

但是如何将多个.o文件链接到一个项目中,这里还需要再看。。。

这里是用$make -f Makefile,直接完成编译,链接,生成.bin文件

下图,讲的很明白了。。。

(6)Make工具

这个后面补充详细的文章,因为它很重要它很重要它很重要!!!

(7)编译

就是最后生成的.bin文件。

 (8)安装Hello OS

为什么要将HelloOS.bin文件放到GRUB能找到的地方?

答:因为我们像让它开机时选择HelloOS后显示“HelloOS”,更cool😎一点。

GRUB的路径怎么找?

答:找grub.cfg(/boot/grub)

(65条消息) ubuntu下查找文件位置的方法_慢下去、静下来的博客-优快云博客_ubuntu查找文件所在位置

这篇博客提供不同情况下找文件路径的方法。

对grub.cfg修改插入内容(65条消息) Linux下如何修改grub.cfg_想入非非、的博客-优快云博客_grub.cfg修改

$sudo chmod +w /boot/grub/grub.cfg

$sudo gedit /boot/grub/grub.cfg

然后将下面代码插到最后:

menuentry 'HelloOS' {

     insmod part_msdos #GRUB加载分区模块识别分区

     insmod ext2 #GRUB加载ext文件系统模块识别ext文件系统

     set root='hd0,msdos5' #注意boot目录挂载的分区,这是我机器上的情况

     multiboot2 /boot/HelloOS.bin #GRUBmultiboot2协议加载HelloOS.bin

     boot #GRUB启动HelloOS.bin

}

这里注意boot目录挂载分区,查询 $df /boot/

文件系统          1K-块    已用     可用      已用% 挂载点

/dev/sda4      48752308 8087584 38158536   18%    /

复制大神的原文:

其中的“sda4”就是硬盘的第四个分区(硬件分区选择 MBR),但是 GRUB menuentry 中不能写 sda4,而是要写“hd0,msdos4”,这是 GRUB 的命名方式,hd0 表示第一块硬盘,结合起来就是第一块硬盘的第四个分区。

这里面,什么时挂载,硬盘的分区是什么,一共有几个分区,为什么就选择第5个分区了?(不懂啊。。。)

最后重启Ubuntu,按esc键,结果,就启动了HelloOS,虽然没懂什么,但还是很高兴。。。下面贴个图,分享喜悦…………

 

 篇尾语:感谢彭东大神,感谢上面博客的大佬们。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值