简单操作系统内核——在屏幕上显示字符

引导程序

一般来说机器加电启动后,整个计算机第一个启动的程序就是固化在PC主板上的BIOS固件,它启动之后检测系统参数,如内存的大小、日期和时间、磁盘设备以及这些磁盘设备用来引导的顺序。BIOS寻找用于装载操作系统的指令。装载操作系统的这个程序就是boot loader。Linux系统默认的boot loader就是GRUB(GRand Unified Bootloader),于是PC上电以后系统启动流程如下:

img

步骤一、下载源代码

在虚拟机(Vmware)中打开terminal,输入命令:git clone https://gitee.com/lmos/cosmos/tree/master/lesson02 如果提示git command没找到,输入命令:sudo apt-get install git 安装git工具。

代码文件如下:

image-20210910105050483

其中,

  • entry.asm:是一段汇编代码,用作GRUB引导调用,关掉中断,设定CPU工作模式,初始化寄存器及C语言运行环境等;

    MBT_HDR_FLAGS	EQU 0x00010003
    MBT_HDR_MAGIC	EQU 0x1BADB002 ;多引导协议头魔数
    MBT_HDR2_MAGIC	EQU 0xe85250d6 ;第二版多引导协议头魔数
    global _start ;导出_start符号
    extern main ;导入外部的main函数符号
    
    [section .start.text] ;定义.start.text代码节
    [bits 32] ;汇编成32位代码
    _start:
    	jmp _entry
    ALIGN 8
    mbt_hdr:
    	dd MBT_HDR_MAGIC
    	dd MBT_HDR_FLAGS
    	dd -(MBT_HDR_MAGIC+MBT_HDR_FLAGS)
    	dd mbt_hdr
    	dd _start
    	dd 0
    	dd 0
    	dd _entry
    
    ;以上是GRUB所需要的头
    ALIGN 8
    mbt2_hdr:
    	DD	MBT_HDR2_MAGIC
    	DD	0
    	DD	mbt2_hdr_end - mbt2_hdr
    	DD	-(MBT_HDR2_MAGIC + 0 + (mbt2_hdr_end - mbt2_hdr))
    	DW	2, 0
    	DD	24
    	DD	mbt2_hdr
    	DD	_start
    	DD	0
    	DD	0
    	DW	3, 0
    	DD	12
    	DD	_entry
    	DD      0
    	DW	0, 0
    	DD	8
    mbt2_hdr_end:
    ;以上是GRUB2所需要的头
    ;包含两个头是为了同时兼容GRUB、GRUB2
    
    ALIGN 8
    
    _entry:
    	;关中断
    	cli
    	;关不可屏蔽中断
    	in al, 0x70
    	or al, 0x80
    	out 0x70,al
    	;重新加载GDT
    	lgdt [GDT_PTR]
    	jmp dword 0x8 :_32bits_mode
    
    _32bits_mode:
    	;下面初始化C语言可能会用到的寄存器
    	mov ax, 0x10
    	mov ds, ax
    	mov ss, ax
    	mov es, ax
    	mov fs, ax
    	mov gs, ax
    	xor eax,eax
    	xor ebx,ebx
    	xor ecx,ecx
    	xor edx,edx
    	xor edi,edi
    	xor esi,esi
    	xor ebp,ebp
    	xor esp,esp
    	;初始化栈,C语言需要栈才能工作
    	mov esp,0x9000
    	;调用C语言函数main
    	call main
    	;让CPU停止执行指令
    halt_step:
    	halt
    	jmp halt_step
    
    
    GDT_START:
    knull_dsc: dq 0
    kcode_dsc: dq 0x00cf9e000000ffff
    kdata_dsc: dq 0x00cf92000000ffff
    k16cd_dsc: dq 0x00009e000000ffff
    k16da_dsc: dq 0x000092000000ffff
    GDT_END:
    
    GDT_PTR:
    GDTLEN	dw GDT_END-GDT_START-1
    GDTBASE	dd GDT_START
    
    
  • hello.lds:进行链接调用;

  • install.md:需要将这个文件里的内容复制到GRUB的cfg配置文件中,才能使电脑开机时可以找到我们的Hello OS;

  • main.c:我们Hello OS的主函数,它调用的printf可不是常见的C语言库函数哦,而是我们自己实现的printf!即下面要讲的vgastr.h;

     ```c
     #include "vgastr.h"
     void main()
     {
         printf("Hello OS!");
         return;
     }
     ```
    
  • vgastr.h:控制计算机屏幕VGABIOS固件程序显示特定字符;

    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;
    }
    
  • Makefile:利用make工具来实现编译源代码,主要是将entry.asm、main.c、vgastr.h编译并链接。

步骤二、 编译操作系统

流程

Makefile文件中其实已经写出了如何编译我们的操作系统,有兴趣可以看看。

整个编译流程就如图:

img

编译

安装gcc和nasm。输入命令:sudo apt-get install nasmsudo apt-get install gcc

在当前文件路径下打开terminal,输出指令:make all

image-20210910115901751

经过编译,我们的文件夹下多了很多的东西,.O属于中间生成的文件,不用理会,重点在于这个HelloOS.bin文件:这个HeloOS.bin文件就是我们的简单操作系统了

安装

先通过以下命令,找到boot目录挂载分区

df /boot/

我的结果如下:

image-20210910120345361

也就说我的虚拟机中ubuntu16.04的系统GRUB引导是在硬盘的第5分区。

然后打开文件夹中的install.md,复制粘贴到*/boot/grub/grub.cfg中*,install.md主要是加载我们的Hello OS的启动项:

//install.md
menuentry 'HelloOS' {
    insmod part_msdos
    insmod ext2
    set root='hd0,msdos5' #注意boot目录挂载的分区,这是我机器上的情况
    multiboot2 /boot/HelloOS.bin
    boot
}

注意!df /boot的结果在哪个sda?,set root=‘hd0,msdos?’中的?就填什么。

而后,运行将我们的Hello OS.bin 文件复制到 /boot/ 目录下:

命令 sudo cp HelloOS.bin /boot/

修改GRUB引导显示时间

打开sudo gedit /etc/default/grub,**修改其中的GRUB_CMDLINE_LINUX_DEFAULT为“text”**如下:

image-20210910120801975

然后需要更新grub配置:sudo update-grub

重启

选择系统

image-20210910123106379

显示出来的字符内容,可以在main函数里修改。

image-20210910121014696

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贰拾肆画生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值