【从头开始写操作系统系列】环境搭建以及第一个Hello World

写在最前

笔者在动手写此操作系统时是一名大学本科大二的学生,可能文章中会有好多地方我没有解释清楚,可能也会有许多地方出现错误,我恳请各位读者能提出质疑和纠正我的错误,谢谢!

参考书籍:

  • 《30天自制操作系统》川合秀实
  • 《ORANGE’S:一个操作系统的实现》

开发环境

笔者采用以下开发环境

  • Apple Macbook Air
  • Ubuntu 12.04 LTS(32 bit)

读者准备

毕竟是动手写一个操作系统,对读者的要求也会相应要求高一些,对计算机编程0基础的读者还是不建议直接看这个系列的文章。希望读者能有 汇编语言、C 语言的基础,对操作系统最好有了解(推荐书籍《操作系统概念》),另外由于开发是在 Ubuntu 的环境中进行的,读者最好对 Linux 的命令、操作等比较熟悉。

环境搭建

安装Bochs 等

Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。更为有趣的是,甚至可以不使用PC硬件来运行Bochs。事实上,它可以在任何编译运行Bochs的平台上模拟x86硬件。通过改变配置,可以指定使用的CPU(386、486或者586),以及内存大小等。一句话,Bochs是电脑里的“PC”。根据需要,Bochs还可以模拟多台PC,此外,它甚至还有自己的电源按钮。

我们所写的操作系统就是模拟在 Bochs 来运行和调试的。

我们使用以下的命令来安装 bochs 等一些工具

sudo apt-get install vgabios bochs bochs-x bximage bochs-sdl

第一个 Hello World

创建软盘镜像

  • 使用bximage 命令
  • 按照以下来进行配置

========================================================================
                                bximage
                  Disk Image Creation Tool for Bochs
        $Id: bximage.c,v 1.34 2009/04/14 09:45:22 sshwarts Exp $
========================================================================

Do you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd] fd

Choose the size of floppy disk image to create, in megabytes.
Please type 0.16, 0.18, 0.32, 0.36, 0.72, 1.2, 1.44, 1.68, 1.72, or 2.88.
 [1.44] 1.44
I will create a floppy image with
  cyl=80
  heads=2
  sectors per track=18
  total sectors=2880
  total bytes=1474560

What should I name the image?
[a.img] helloworld.img

Writing: [] Done.

I wrote 1474560 bytes to helloworld.img.

The following line should appear in your bochsrc:
  floppya: image="helloworld.img", status=inserted
  • 最终我们得到了一个名叫『helloworld.img』的文件,它就是我们创建的软盘镜像

操作系统源码

  • hello.asm
    org 07c00h
    mov ax, cs
    mov ds, ax
    mov es, ax
    call    DispStr
    jmp $
DispStr:
    mov ax, Str
    mov bp, ax
    mov cx, 13
    mov ax, 01301h
    mov bx, 000ch
    mov dl, 0
    int 10h
    ret
Str:        db  "Hello, world!"
times   510-($-$$)   db  0
dw  0xaa55  
  • 下面我们来逐行分析这段汇编代码

org 07c00h 指定程序的起始地址,告诉编译器程序从这里开始

org是Origin的缩写:起始地址源。在汇编语言源程序的开始通常都用一条org伪指令来实现规定程序的起始地址。

mov ax, cs 将 cs(代码段寄存器)中的值赋值给 ax 寄存器

mov ds, ax 将 ax 中的值赋值给 ds( 一个段寄存器)

mov es, ax 将 ax 中的值赋值给 es()

call DispStr 跳转执行到 DispStr

jump $ 死循环

mov ax, Str 将 Str 的首地址放入 ax

mov bp, ax 将 ax 的值赋给 bp(栈底指针)

mov cx, 13 将13放入 ax 寄存器

mov ax, 01301h ax 寄存器高位AH=13,低位 AL=01h

mov bx, 000ch 将000ch 放入 bx 寄存器

mov dl, 0 将光标设置为0行0列

int 10h 调用10h 中断

  • int 10h 中断功能介绍
AH 功能 调用参数 返回参数
1 置光标类型 (CH)0―3 = 光标开始行
(CL)0―3 = 光标结束行
2 置光标位置 BH = 页号
DH = 行
DL = 列
3 读光标位置 BH = 页号 CH = 光标开始行
CL = 光标结束行
DH = 行
DL = 列
4 读光笔位置 AH=0 光笔未触发
AH=1 光笔触发
CH=象素行
BX=象素列
DH=字符行
DL=字符列
5 显示页 AL = 显示页号
6 屏幕初始化或上卷 AL = 上卷行数
AL =0全屏幕为空白
BH = 卷入行属性
CH = 左上角行号
CL = 左上角列号
DH = 右下角行号
DL = 右下角列号
7 屏幕初始化或下卷 AL = 上卷行数
AL =0全屏幕为空白
BH = 卷入行属性
CH = 左上角行号
CL = 左上角列号
DH = 右下角行号
DL = 右下角列号
8 读光标位置的属性和字符 BH = 显示页 AH = 属性
AL = 字符
9 在光标位置显示字符及其属性 BH = 显示页
AL = 字符
BL = 属性
CX = 字符重复次数
A 在光标位置只显示字符 BH = 显示页
AL = 字符
CX = 字符重复次数
E 显示字符(光标前移) AL = 字符
BL = 前景色
13 显示字符串 ES:BP = 串地址
CX = 串长度
DH, DL = 起始行列
BH = 页号
AL = 0,BL = 属性
串:Char,char,……,char
AL = 1,BL = 属性
串:Char,char,……,char
AL = 2
串:Char,attr,……,char,attr
AL = 3
串:Char,attr,……,char,attr

times 510-($-$$) db 0 将剩余的位置都填充为0

dw 0xaa55 结束标志

制作操作系统镜像

  • 编译源码

nasm hello.asm -o hello.bin

  • 写入软盘镜像扇区

dd if=hello.bin of=helloworld.img bs=512 count=1 conv=notrunc

运行 HelloWorld

编写 bochs 配置文件 - bochsrc


###############################################################
# Configuration file for Bochs
###############################################################

# how much memory the emulated machine will have
megs: 32

# filename of ROM images
romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin

# what disk images will be used
floppya: 1_44=helloworld.img, status=inserted

# choose the boot disk.
boot: floppy

# where do we send log messages?
# log: bochsout.txt

# disable the mouse
mouse: enabled=0

# enable key mapping, using US layout as default.
keyboard_mapping: enabled=1, map=/usr/share/bochs/keymaps/x11-pc-us.map

display_library: sdl

运行bochs

bochs -f bochsrc

运行结果如下图:



版权声明:本文为博主原创文章,未经博主允许不得转载。

文章来源:http://blog.luoyuanhang.com

版权声明:本文为博主原创文章,未经博主允许不得转载。(文章来源:http://blog.luoyuanhang.com)

时间: 2024-07-31 17:31:52

【从头开始写操作系统系列】环境搭建以及第一个Hello World的相关文章

【从头开始写操作系统系列】使用 Bochs 调试操作系统

在上一篇文章<环境搭建以及第一个Hello-World>中,笔者讲了如何安装 bochs 以及运行一个 helloworld 操作系统,但是使用上一篇文章中的方法安装的 bochs 是不支持调试的,下面我讲介绍如何使用源码编译的方法来安装 bochs,以及使用 bochs 来调试操作系统. 编译安装 Bochs 下载 bochs 源码 http://sourceforge.net/projects/bochs/files/bochs/2.6.8/ 解压之后进入该目录,进行配置 sudo ./c

Robot Framework自动化_环境搭建以及第一个用例

Robot Framework自动化_环境搭建以及第一个脚本 培训老师:肖能尤 2016/06/07 课程目的 一.Robot framework 环境搭建以及第一个脚本 课程内容 1    安装前准备工作 搭建环境所需要的安装文件已经下载好,从SVN上获取即可,解压,如下 2   Robotframework环境搭建 2.1  安装Python 官网下载地址: http://www.python.org/getit/ 2.2  安装setuptools-15.1 2.3  安装pip 2.4 

【从头开始写操作系统系列】页表以及相关的描述符详解

在之前的文章中,我们介绍过 GDT(全局描述符表)以及一致代码段和非一致代码段,这篇文章我们再回到描述符,这次我们来以 ARM 架构为例了解一下页表描述符. 在这篇文章中,我们会看到以下内容: 页表是什么? 一级页表的地址变换过程 由一级描述符来获取二级描述符或者段地址的过程 页表 页表是什么? 页表是一种特殊的数据结构,放在系统空间的页表区,存放逻辑页与物理页帧的对应关系. 每一个进程都拥有一个自己的页表,PCB表中有指针指向页表. (来自百度百科) 通俗的来讲,页表的内容就是一个描述符(关于

非常好!!!【从头开始写操作系统系列】实现一个-GDT(1)【转】

转自:http://blog.csdn.net/luoyhang003/article/details/47338019 权声明:本文为博主原创文章,未经博主允许不得转载.(文章来源:http://blog.luoyuanhang.com) 目录(?)[-] 介绍 GDT GDT 是什么 描述符结构 在这篇文章中我们完成了以下内容: 介绍 GDT 介绍段描述符 实现一个段描述符 介绍 GDT GDT 是什么? GDT(Global Descriptor Table)是一种数据结构,用来提供段式存

【从头开始写操作系统系列】一致代码段与非一致代码段

上几篇文章,我们一直在讨论的都是 GDT 相关的一些问题,现在我们知道在系统在从实模式向保护模式跳转时,GDT 是必须要准备的结构.在介绍这一跳转之前,这篇文章我们来介绍两个概念:一致代码段和非一致代码段. 首先,我们先来看几个问题: 一致代码段和非一致代码段是什么? 为什么要有一致代码段和非一致代码段? 系统提供怎样的机制来使用户程序访问内核数据? 程序如何在段与段之间跳转? 接下来,我们将讨论上述这些问题. 特权级 为了更好的理解之后的问题,我们先来讨论一个概念:特权级. 特权级是一种机制来

【从头开始写操作系统系列】实现一个-GDT(1)

在这篇文章中我们完成了以下内容: 介绍 GDT 介绍段描述符 实现一个段描述符 介绍 GDT GDT 是什么? GDT(Global Descriptor Table)是一种数据结构,用来提供段式存储机制,这种机制是通过段寄存器和 GDT 中的描述符共同提供的. 在保护模式下,虽然现在的寄存器已经有32位的,但是我们依旧采用『段:偏移』的形式来寻址,只不过『段』的概念就相当于 GDT,段值仍然由16位的 cs.ds 等寄存器表示,但是这时段值仅仅是相当于一个索引,指向一个数据结构,这个数据结构就

git环境搭建以及第一个PHP程序

使用mac下的sublime等编辑器帮助代码编写,然后到linux下运行网页代码.可以通过/vagrant共享目录完成,但是默认apache默认目录为/var/www/html,不想改变该目录,同时为了方便“云管理”,使用git和github统一管理代码. 1. 在github建立新仓库:learn_www,并且添加vagrant下的公钥,公钥使用ssh-keygen产生,并使用git --global user.email "e-mail”以及 git —global user.name “n

React学习笔记-1-什么是react,react环境搭建以及第一个react实例

什么是react?react的官方网站:https://facebook.github.io/react/下图这个就是就是react的标志,非常巧合的是他和我们的github的编辑器Atom非常相似.react是Facebook官方推出的一个javascript的库,现在已经有了非常多的库和框架Facebook为什么还要开发一款新的框架呢?原因就是 Facebook遇到了一些新的问题.Facebook需要解决的问题是构建数据不断变化的大型应用.大型应用是什么意思?数据不断变化带来什么问题呢? 

[java基础学习笔记]Java8SE开发环境搭建、第一个Java Hello World、Java程序的编译与执行

本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/25745945 主要内容: ---------------------------------------------------| 1.JDK的下载与安装                            | 2.编写第一个java程序HelloWorld     | 3.编译执行HelloWorld