Linux0.12内核学习之(1)——用MASM编写Boot Sector引导扇区

最近在学习Linux0.12内核,正在读《Linux内核完全剖析》。一开始就被ax86写的引导扇区弄晕了。于是Google了很多资料。最终实验了一晚上终于搞定。下面来看看我们怎么用Windows下的MASM来写个Boot Sector。因为我MASM汇编用的比较熟,所以就用MASM来写,当然,汇编只有语法差异,你用什么来写都没关系。

首先,先来说说计算机怎么启动的。经过一系列BIOS加电、系统自检后,会将硬盘0面0道1扇区的512字节(Boot Sector)加载到内存地址07c0:0000处,之后就是执行这个Boot Sector部分了。而我们要写的就是这部分。这部分之后会引导操作系统启动,我们暂时不管这些。

需要注意的是,系统会检查内存地址07c0:01FE处是否等于0xaa55,不等于则报错。

既然知道了系统会把前512扇区加载内存,那么我们就要在汇编里做些设置。

源码如下:

data segment
	org 07c00h    ;将程序加载到07c0:0000处
start:
	mov ax,data
	mov es,ax        ;后面的字符串寻址输出需要es:bp
	mov bp,offset msg1
lop:mov ah,13h	        ;第10h中断向量的功能代码13h---写字符串
	mov al,0	;写模式 使用0就可以
	mov bh,0	;0页,默认为0页即可
	mov bl,07	;显示属性,黑底白字
	mov cx,32	;字符32个,更科学的方法是两个标号相减,为了简化代码,直接数出来
	mov dh,10	;输出在第10行
	mov dl,24	;输出在第24列
	int 10h		;10h 使用第10h中断向量,显示器输出
	jmp lop         ;死循环,让字符保持在屏幕上

	ret

	msg1 db "Welcome to my Operating System !"
	org 07c00h+512-2    ;地址计数器跳到512字节的倒数第二字节,即07c0:01FE
	DW 0AA55H            ;此处在512字节的最后两字节写入AA55H !!
data ends
end start

然后把这汇编用MASM编译即可。我用的MASMPlus,其实都一样,只不过编译器不同。MASM不支持鼠标,麻烦点。

其实编译运行后我们的字符串已经显示出来了。

但是这并不是我们的目的,我们要写Boot Sector。

我们找到编译出来的exe文件,下面用WinHex工具把exe前面的PE文件头去掉,只留下我们需要的512字节。

先找到最后的55AA(高字节在后,低字节在前,所以是55AA),

然后向上选择512字节,

然后导出新的EXE,“编辑”--“复制选块”--“至新文件”

这是裁剪后的

然后就要使用软盘引导,但是现在这年代哪来的软盘,于是我们可以用软盘镜像,直接挂到虚拟机上。

启动Linux系统,用dd命令做个空的floppy镜像。

将我们裁剪好的myboot.exe拖到虚拟机里。不用管它是什么exe文件,现在扩展名去掉都可以,失去作用了。

用dd命令将myboot.exe文件写入myflp.img软盘镜像

好的,现在软盘镜像制作完成,下面开始虚拟机引导。

将做好的myflp.img拖到Windows上。

然后新建虚拟机,操作系统全选‘Other‘,网络连接可以不要,内存8M,硬盘3M。

然后“编辑虚拟机设置”,在软盘驱动器挂上myflp.img,勾上“打开电源时连接”,确定。

好了,开机吧。

完成了,这就是自己用MASM写的Boot Sector。以后可以加上操作系统的内容,让它真正的引导起我们自己的操作系统。这只是个开始。

我是内核新手,写博客只为记录自己的历程,欢迎各位指正,也希望有兴趣的可以一起交流。

Linux0.12内核学习之(1)——用MASM编写Boot Sector引导扇区,布布扣,bubuko.com

时间: 06-09

Linux0.12内核学习之(1)——用MASM编写Boot Sector引导扇区的相关文章

Linux0.12内核之内存管理(2)

本文主要介绍Linux0.12内核memory.c中的函数 1.void free_page(unsigned long addr) //释放物理地址addr处的一页内存.用于free_page_tables()函数 void free_page(unsigned long addr) { //首先判定给定物理地址的合理性.如果物理地址addr小于内存低端1M,对此不///予处理.如果addr>=内存最高端,则显示出错并且内核停止工作 if(addr<LOW_MEM) return; if(a

linux0.12内核的内存组织和进程结构

进程结构 Linux0.12中的每个进程都有如下的结构: 在gdt中占有两项,一项是tss段描述符,一项是ldt段描述符. 在task数组中占有一项,指向一页物理内存,该物理内存低端是进程控制块task_struct(里面包括tss段和ldt段),其余部分是进程的内核态堆栈. 在页目录表和页表中设置有相关项. Linux0.12中,最多只有64个进程,task数组大小也定义成了64,每个进程与一个task数组中的项一一对应.虽然gdt中有256项,但是并不是都用到.第一个gdt项保留不用,内核用

Linux0.12内核之内存管理(3)

本系列的第三篇文章主要来介绍与共享物理页面相关的两个函数. //在发生缺页异常的时,首先看看能否与运行同一个文件的其他进程进行页面共享处理.该函数首先判断系统中是否有另外进程也在运行与当前进程一样的执行文件.若有,则在系统当前任务中找寻这样的任务.若找到了这样的任务就尝试与其共享指定地址处的页面.判断系统中是否有另一个进程也在执行同一个可执行文件的方法是利用进程任务数据结构中的executable字段.该字段执行进程正在执行程序的内存中的i节点,根据该i节点的引用次数i_count我们就可以判断

Linux-0.12内核sleep_on函数分析

sleep_on用于进程休眠,原型如下: void sleep_on(struct task_struct **p) 当进程访问某个互斥资源时,如果资源被另外进程占用,当前进程就需要休眠. 假设资源的结构如下: struct res { .... struct task_struct *wait; } 其实我们参考下文件系统的i节点就会发现,i节点也是一种资源,它的结构体中就有一个变量i_wait.那么我们就用i节点举例.如果进程访问某个i节点,发现i节点被锁住,当前进程就需要睡眠:sleep_

linux0.12内核bootsect.S

这个文件就是0.12内核的主引导扇区代码,他的作用就是加载操作系统内核. 计算机加电,自检完毕后,BOIS就将启动设备的第一扇区加载到内存0x7c00(31KB)处,并开始从这里执行,若启动设备是硬盘的话,加载的即为该硬盘0磁道0柱面1扇区的内容,共512字节,以0xAA55为结束标志,这就是硬盘的MBR(master boot recorder). linux0.12内核bootsect.S中的代码编译后,将会写入启动设备的MBR中,它的主要工作加载操作系统内核的初始化程序setup.S和操作

linux0.12 学习总序(不断更新状态中)

最近有空闲时间,想静下心来学点东西.一直对kernel有兴趣,又苦于无从下手,就拿linux0.12练手.尝试了解并熟悉kernel各模块工作原理. 接下来的博客主要用来记录自己所遇到的问题和解决的方法以及方法背后涉及的知识,有些是我从别人的博客或者书中搜到的,但更多的是自己折腾出来的,我仅以对得起自己的态度,非常不严谨的表示,解决方法可能会有点坑爹,希望看到这些博客的哥儿们在喷的时候,指点一下,感激不尽. 以下是我搜到的比较有用的资料: 编译linux0.11 http://blog.chin

Ubuntu 12.10安装Bochs 2.6, 调试linux-0.11内核

http://blog.csdn.net/sinzou1/article/details/5903968 Linux(ubuntu)安装bochs http://wenku.baidu.com/view/f968e23b0912a21614792914.html ubuntu下安装bochs http://www.linuxidc.com/Linux/2011-07/38371.html Ubuntu 10.04安装Bochs 2.4.5笔记 http://blog.csdn.net/trace

一站式linux0.11内核head.s代码段图表详解

阅读本文章需要的基础: 计算机组成原理:针对8086,80386CPU架构的计算机硬件体系要有清楚的认知,我们都知道操作系统是用来管理硬件的,那我们就要对本版本的操作系统所依赖的硬件体系有系统的了解,有了系统的了解后才能全面的管理它,我们对8086,80386CPU架构的计算机硬件体系如果有非常深刻的认识,我们看源代码内核的时候,就可以更可能的以一种开发者的角度去思考代码的作用,先从全局的角度去思考问题,而不是采用一种众人摸象的思维从头看到末尾. 计算机编程C语言基础:linux内核基本都是用C

Linux内核学习-进程

先说几个术语: 一.Linux进程的五个段 下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区都是干什么的.重点:代码段.数据段.堆栈段,这是一个概念堆.栈.全局区.常量区,这是另一个概念1)代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像.代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作--它是不可写的.代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域.这部分