操作系统——笔记day2

HelloOS

PC机的引导流程

PC机加电 -> PC机 BIOS 固件 -> 加载可引导设备中的GRUB -> GRUB引导 -> 加载硬盘分区中的 Hello OS 文件

Hello OS 引导汇编代码

PC机上电后的第一条指令就是BIOS固件中的,它负责检测和初始化CPU、内存和主板平台,然后加载引导设备(硬盘)中的第一个扇区数据,到0x7c00地址开始的内存空间执行指令,在我们这里就是GRUB引导程序

MBT_HDR_FLAGS EQU 0x00010003 ;1
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
DD 0, 0
DD 8
mbt2_hdr_end:
;以上是GRUB2所需要的头
;包含两个头是为了同时兼容GRUB、GRUB2 40
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 0x0000f9e000000ffff
k16da_dsc:dq 0x0000f92000000ffff
GDT_END:
GDT_PTR:
GDTLEN dw GNT_END-GDT_START-1
GDTBASE dd GDT_START

/lesson01/HelloOS/entry.asm

1.代码 1~40行 ,用汇编定义的GRUB的多引导协议头,就是一定格式的数据,Hello OS是用GRUB引导的,要遵循GRUB的多引导协议标准,才能让GRUB识别我们的Hello OS

2.代码44~52行,关掉中断

3.代码54~73行,初始化cpu的寄存器和C语言的运行环境

4.代码78~87行,GDT_START开始的,是cpu工作模式所需要的数据

Hello OS 的主函数

#include "vgastr.h"

void main()

{

printf("Hello OS!");

return;

}

控制计算机屏幕

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

字符模式工作细节:把屏幕分成24行,每行80个字符,把24*80个位置映射到以0x8000地址开始的内存中,每两个字节对应一个字符,其中一个字节是字符的ASCII码,另一个字节为字符的颜色值

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 ;
}

编译和安装 Hello OS

make 工具

make 是一个工具程序,他读取"makefile"文件,这个文件中写好了构建软件的规则,make根据这些规则自动化构建软件

makefile文件中的规则:首先一个或者多个构建目标称为"target"

​ 目标后面紧跟着用于构建该目标所需要的文件

​ 目标下面是构建该目标所需要的命令及参数

Linux都默认自带这个make程序

下面是一个例子

CC = gcc #定义一个宏CC 等于gcc
CFLAGS = -c #定义一个宏 CFLAGS 等于-c
OBJS_FILE = file.c file1.c file2.c file3.c file4.c #定义一个宏
.PHONY : all everything #定义两个伪目标all 、 everything
all:everything #伪目标all依赖于伪目标everything
everything :$(OBJS_FILE) #伪目标everything依赖于OBJS_FILE. 
#而OBJS_FILE是宏会被替换成file.c #file1.c file2.c file3.c file4.c
%.o : %.c
$(CC) $(CFLAGS) -o $@ $<

.PHONY 定义为伪目标,伪目标,就是它不代表一个真正的文件名,在执行make 的时候可以指定这个目标来执行其所在的规则定义的命令,伪目标可以依赖一个伪目标或者一个文件

%.o : %.c 表示所有以".o"结尾的文件依赖与所有以".c"结尾的文件

编译

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PPBJm9mi-1643201315662)(C:\Users\张小瑄\AppData\Roaming\Typora\typora-user-images\1643183704089.png)]

安装 Hello OS

经过上述流程,我们得到了 Hello OS.bin 文件,还要让GRUB能够找到它,才能让计算机启动时加载它。这个过程为安装,安装程序要自己写

GRUB启动时会加载,grub.cfg 的文本文件,根据其中的内容执行相应的操作,其中一部分是启动项

GRUB首先会显示启动项,选择启动项后,GRUB根据启动项对应的信息,加载OS文件到内存

menuentry 'HelloOS'{
	insmod part_msdos #GRUB加载分区模块识别分区
	insmod ext2 #GRUB加载ext文件系统模块识别ext文件系统
	set root='hd0,msdos1'#注意boot目录挂载的分区
	multiboot2 /boot/HelloOS.bin #GRUB以multiboot2协议加载HelloOS.bin
	boot #GRUB启动该HelloOS.bin
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一直饿着肚子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值