(03)从引导进入内核<一>

一 前言

前面已经准备好开发环境,并且写了一个简单的引导程序。从本节开始,就要真正的开发操作系统了。

本节代码位于:github

1.1 系统启动流程

这里重新描述一下系统的启动流程:

  1. PC电源打开,CPU 将自动进入实模式
  2. 加载BIOS程序并执行
  3. BIOS进行一些硬件检测配置
  4. BIOS将可启动设备的第一个扇区(磁盘引导扇区,512 字节)读入内存绝对地址 0x7C00 处,并跳转到这个地方开始引导启动机器运行。

我们的程序从前面第四步开始介入,主要分为三块,功能如下:

程序功能磁盘内存
boot引导代码,512 字节。负责读取磁盘加载setup、system第一个扇区(引导扇区)0x7C00
setup获取系统硬件信息,进入保护模式,复制system内存到0x100000扇区2~扇区90x9000
system真正的系统内核扇区10以后0x100000

1.2 内存分布

BIOS的内存分布:

0x00000 ~ 0x003FF: 中断向量表(1024B)
0x00400 ~ 0x004FF: bios数据区(256B)
0x00500 ~ 0x07BFF: 自由内存区 30kb
0x07C00 ~ 0x07DFF: 引导程序加载区(512B)
0x07E00 ~ 0x9FFFF: 自由内存区 608k

0xA0000 ~ 0xAFFFF: EGA/VGA/XGA/XVGA图形视频缓冲区(64KB)彩色显示适配器


本系统自由内存区的分配:
0x7E00 ~ 0x8FFF  硬件信息、启动信息
0x9000 ~ 0x9FFF  setup
0x10000 ~ 0x9FFFF  system

我们的boot肯定是加载到0x7C00处,然后它会继续读取磁盘的2~9扇区(共8个扇区,4KB)并放到内存的0x9000处,读取system放到内存的0x10000处。最后跳转到0x9000处,开始执行setup。

setup会通过BIOS中断读取一些系统硬件信息,进入保护模式,同时将system从0x10000处拷贝到0x100000 (1MB)处,然后跳转到0x100000处开始执行system

接下来将逐步实现boot和header。

二 虚拟硬盘

2.1 创建硬盘

执行bximage命令创建一个虚拟硬盘:
请添加图片描述

这里将创建一个20MB的虚拟硬盘,文件名为c.img

将最下面那句话copy到bochsrc.os文件中。

三 boot引导

3.1 boot.h

#ifndef _BOOT_H
#define _BOOT_H

// setup的段地址
#define DEF_SETUPSEG	0x900
// system段地址
#define DEF_SYSSEG	0x1000
// system的大小
#define DEF_SYSSIZE	0x10000

#endif

3.2 boot.S

在上一节boot.s的基础上增加了setup和system的加载

#include "boot.h"

BOOTSEG		= 0x07C0		/* 引导程序加载的位置*/

.code16
.text
	jmpl	$BOOTSEG, $_start

.global _start
_start:
// 初始化寄存器
	movw	%cs, %ax
	movw	%ax, %ds
	movw	%ax, %es
	movw	%ax, %ss
	movw	$0x7c00, %sp

// 清屏	
	movw	$0x0700, %bx	
	movw	$0x0600, %ax	
	movw	$0x184f, %dx
	int		$0x10			

showMsg:
// 调用0x10中断显示字符串
	movw	$27, %cx
	movw	$0x7, %bx	
	movw	$0, %dx	 
	movw	$msg1, %bp
	movw	$0x1301, %ax	 
	int		$0x10			 


read_setup:
	movb $0x42, %ah
	movb $0x80, %dl
	movw $setup_packet, %si  
	int $0x13

read_system:
	movb $0x42, %ah
	movb $0x80, %dl
	movw $system_packet, %si  
	int $0x13
// 跳转到setup

	jmpl $DEF_SETUPSEG, $0

msg1:
	.ascii	"Hello, Boot is starting\r\n"

setup_packet:
	.word 0x10  /* struct's size */
	.word 8 /* 读多少个 sectors */
	.word 0, DEF_SETUPSEG /* buffer address */
	.quad 1 /* 从哪个 sector 开始读 */

system_packet:
	.word 0x10  /* struct's size */
	.word DEF_SYSSIZE/512 /* 读多少个 sectors */
	.word 0,DEF_SYSSEG /* buffer address */
	.quad 9 /* 从哪个 sector 开始读 */

.org 510
boot_flag:	.word 0xAA55

四 setup和system

本节只为验证新的boot以及程序结构,所以setup和system里面只有一个死循环:



.global _start
_start:
jmp _start

我将在后面的章节中慢慢完善这两个程序。

五 运行

编写Makefile,开始运行:


all: img

boot.o: boot.S boot.h

boot: boot.o
	ld -Ttext 0 -s --oformat binary -o $@ $< 
	
setup: setup.o
	ld -Ttext 0 -s --oformat binary -o $@ $< 

system: system.o
	ld -Ttext 0 -s --oformat binary -o $@ $< 


img:boot setup system
	dd if=boot of=c.img count=1 conv=notrunc seek=0
	dd if=setup of=c.img count=1 conv=notrunc seek=1
	dd if=system of=c.img count=1 conv=notrunc seek=9


run: boot bochsrc.os
	bochs -f bochsrc.os

clean:
	rm boot setup  system *.o  *.s

%.s: %.S
	gcc -E $< -o $@

执行make & make run

运行效果如下图所示:

请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值