linux内核设计的艺术--载入内核代码

在BIOS触发0x19中断将磁盘的第一个扇区(512B)载入到内存中后。计算机才真正開始运行磁盘上的程序。而这512B的程序就是bootsect.s,此时处理器还处于实模式内存寻址的最大范围是1M(0x0000-0xFFFF),接下来我们看看在bootsect.s的第一批代码中做了些什么?

</pre><pre name="code" class="cpp">SYSSIZE = 0x3000                        //内核程序的大小
SETUPLEN = 4				//要载入的setup程序长度单位为扇区数
BOOTSEG  = 0x07c0			//启动扇区被BIOS载入的位置,也就是如今所在的位置
INITSEG  = 0x9000			//bootsect.s即将移动到的位置
SETUPSEG = 0x9020			//setup程序要被载入的開始位置
SYSSEG   = 0x1000			//kernel载入的起始位置
ENDSEG   = SYSSEG + SYSSIZE		//kernel的结束位置
ROOT_DEV = 0x306                        //根文件系统的设备号

上述代码声明了给一系列变量赋值,用于内存规划

</pre><pre name="code" class="cpp">entry start
start:
	mov	ax,#BOOTSEG             //
	mov	ds,ax                   //
	mov	ax,#INITSEG             //这段代码是将bootsect的代码从0x07C0
	mov	es,ax                   //拷贝到0x9020处
	mov	cx,#256                 //
	sub	si,si                   //
	sub	di,di                   //
	rep                             //
        movw                            //
</pre>由于在后面的程序中,bootsect之前所在的位置会被其它程序覆盖。所以须要将bootsect程序的位置移动至0x90200处<p></p><p></p><p>复制完毕之后。紧接着运行</p><p></p><pre code_snippet_id="403621" snippet_file_name="blog_20140623_7_6144482" name="code" class="cpp">	jmpi	go,INITSEG
go:	mov	ax,cs
	mov	ds,ax

这句指令的意思是,跳转到新复制的bootsect处的go继续运行

这个时候。開始载入setup(setup.s)程序到内存中了

还是老样子,载入setup,仅仅只是这次通过寄存器指定了一系列信息方便中断服务程序訪问磁盘

load_setup:
	mov	dx,#0x0000		//指定磁头为第0个
	mov	cx,#0x0002		//指定在第2个扇区。第0个磁道
	mov	bx,#0x0200		//setup在磁盘中的物理地址
	mov	ax,#0x0200+SETUPLEN	//指定结束的位置
	int	0x13			//中断读取磁盘
	jnc	ok_load_setup		//载入完毕,运行ok_load_setup
	mov	dx,#0x0000
	mov	ax,#0x0000		//重置磁盘
	int	0x13
	j	load_setup

然后调用read_it载入system也就是kernel模块了

	mov	ax,#SYSSEG      //指定system模块载入在内存中的位置
	mov	es,ax
	call	read_it
	call	kill_motor

到了这一步。bootsect的工作也就算完毕了。这时候,内核的代码已经载入到了内存中,可是在离直接运行内核程序的时候另一段路要走,下一篇将介绍怎样为内核代码运行做准备

时间: 2024-08-27 04:42:00

linux内核设计的艺术--载入内核代码的相关文章

linux内核设计的艺术--加载内核代码

在BIOS触发0x19中断将磁盘的第一个扇区(512B)加载到内存中后,计算机才真正开始执行磁盘上的程序.而这512B的程序bootsect.s中的第一批代码,此时处理器还处于实模式内存寻址的最大范围是1M(0x0000-0xFFFF),接下来我们看看在bootsect.s的第一批代码中做了些什么? SYSSIZE = 0x3000 //内核程序的大小 SETUPLEN = 4 //要加载的setup程序长度单位为扇区数 BOOTSEG = 0x07c0 //启动扇区被BIOS加载的位置,也就是

《LINUX内核设计的艺术》第一章从开机家电到执行main函数之前的过程 学习笔记之一

从开机加电到实行main函数之前的过程 分为三步,目的是实现从启动盘加载操作系统程序,完成实现main函数的准备工作 启动BLOS,准备是模式下的中断向量表和中断服务程序 从启动盘加载操作系统程序到内存.加载操作系统程序就是靠第一步实现的 为实现32位的main函数做过度工作 1.1启动blos,准备实模式下的中断向量表和中断服务程序 由blos来加载软件操作系统的任务 1.1.1         BLOS的启动原理 0XFFFF0 由硬件来启动,CPU硬件设计逻辑设计为加电瞬间就强行将CS的值

linux内核设计的艺术--系统启动第一步

计算机究竟是如何执行起来的呢,在我学习计算机的时候一直不是非常明确,可是近期借了本<linux内核设计的艺术>算是知道了计算机从按开机到启动操作系统之间究竟做了些什么. 这本书刚開始介绍的并非linux的启动,而是linux启动之前的一步,也就是在你按下了开机button之后进入系统引导之前计算机做的事情,这个时候做的事情是每台执行操作系统的计算机都须要做的.大致的步骤也差点儿相同,OK,进入正题. 事实上在当我们按了开机键的时候,硬件电路将CPU的CS设置成0XF000,IP设置成0XFFF

【读书笔记】《Linux内核设计与实现》内核同步介绍&内核同步方法

简要做个笔记,以备忘. 需同步的原因是,我们并发访问了共享资源.我们将访问或操作共享资源的代码段称"临界区",如果两个执行线程处于同一临界区中同时执行,称"竞争条件".这里术语执行线程指任何正在执行的代码实例,如一个在内核执行的进程.一个中断处理程序或一个内核线程. 举个简单例子,i++操作.该操作可以转换为下面的机器指令序列: 1.得到当前变量i的值,并保存到一个寄存器. 2.将寄存器的值加1. 3.将i的新值写回到内存中. 当两个线程同时进入这个临界区,若i初值

《Linux内核设计的艺术》学习笔记(一)从开机加电到执行main函数之前的过程

分享一个最近丢了手机心塞到爆炸的我,现在穷的只剩下满脑子的智慧了,好了,我要开始学习了. 首先,搭建一个linux0.11的系统环境,贴出结果图. 从开机加电到执行main函数之前的过程. 1. 启动BIOS,准备实模式下的中断向量表和中断服务程序; 2. 从启动盘加载操作系统程序到内存,加载操作系统程序的工作就是利用第一步中断服务程序实现的; 3. 为执行32位的main函数做过渡工作. 启动BIOS,准备实模式下的中断向量表和中断服务程序 cpu的硬件设计为加电即进入16位实模式下状态运行,

linux内核设计的艺术-开始执行main函数

为了执行linux内的C语言main函数,上一篇讲到了,为了从汇编语言环境跳转到C语言环境下执行,将CPU工作模式从16位转变到32位模式(C语言是32位的),并且重新建立了GDT与IDT,但是此时GDT和IDT中并没有内容,所以不能进行内存寻址与中断,接下来就是初始化GDT和IDT了. 进入32位模式后,寄存器也将变为32位寄存器,下面的汇编语法和之前的intel汇编有些不同,为AT&T汇编,至于差别不在赘述. Head.S startup_32: //重设段寄存器内容 movl $0x10,

《Linux内核设计的艺术》学习笔记(一)从开机加电到执行main函数

  实验内核版本:0.11 ◆ 从开机到main函数的三步: ① 启动BIOS,准备实模式下的中断向量表和中断服务程序: ② 从启动盘加载OS程序到内存中,加载OS程序的工作就是利用第一步中的中断服务程序实现的: ③ 为执行保护模式下32位的main函数做过渡工作. ? Intel将所有80x86系列的CPU硬件都设计为加电即进入16位实模式状态运行: ? 将CPU硬件逻辑设计为在加电瞬间强行将CS置为0xFFFF,IP置为0x0000,即是CS:IP指向了0xFFFF0这个地址: 整个过程是一

linux内核设计的艺术--从16位转向32位

上一篇讲到了将kernel模块加载到了内存的0x10000-0x10000+120KB处,接下来,将会执行setup.s中的代码了. 首先,setup要获取一系列系统硬件信息 mov ax,#INITSEG mov ds,ax //设置段地址 mov ah,#0x03 xor bh,bh int 0x10 //调用0x10中断获取屏幕光标位置 mov [0],dx //将屏幕光标保存至0x90000处 //调用0x15中断,获取内存信息保存至0x90002 mov ah,#0x88 int 0x

《Linux内核设计的艺术》学习笔记(五)INT 0x10中断

参考书籍:<IBM-PC汇编语言程序设计>   ◆ 设置显示方式: AH = 0 AL = 00 40 × 25 黑白文本,16级灰度 AL = 01 40 × 25 16色文本 AL = 02 80 × 25 黑白文本,16级灰度 AL = 03 80 × 25 16色文本 AL = 04 320 × 200 4色图形 AL = 05 320 × 200 黑白图形,4色灰度 AL = 06 640 × 200 黑白图形 AL = 07 80 × 25 黑白文本 AL = 08 160 × 2