RayCommand操作系统的实现笔记1--BareBone!把架子搭起来

项目主页https://github.com/reyoung/RayCommand。Wiki的主页https://github.com/reyoung/RayCommand/wiki

BareBone版本是RayCommond的最基本的版本,仅仅实现了经由grub引导,在32位保护模式下向屏幕输出一个字符'A'。在阅读之下文章之前,请确定你了解基本的操作系统原理,GCC工具链,Makefile等基础知识。如果你有些许不了解,请参考http://wiki.osdev.orghttp://osdev.sinaapp.com

如果你想动手写你自己的操作系统,BareBone是你最基础的版本,你可以完全复制走这个版本的代码。代码的下载地址是https://github.com/reyoung/RayCommand/zipball/BareBone,使用NASM和i586-elf-gcc编译,推荐在Cygwin下构建交叉编译器和NASM

Table of Contents

自己写Bootloader还是用GRUB?

这个问题被广泛讨论,并且没有一个确实的答案。在于渊写的《自己动手写操作系统》中,几乎三分之一的内容在写一个bootloader。而我第一本如何写操作系统的书也是看得于渊这本。但是,我觉得基于我个人的能力,大多数的代码是汇编,并不能开发出一个真正的操作系统。我更喜欢有组织的写代码的方式。

另外,如果按照于渊的《自己动手写操作系统》中描述的那样,自己完全写一个bootloader,那么必须使用软盘或者U盘,完全格式化后,按照自己的意图,写启动扇区等工作。事实上,那样的操作系统,也没有办法真正的安装到电脑中。

当今,有很多通用的bootloader可供选用,例如grub,syslinux等等(事实上,我写的操作系统使用syslinux引导)。如果使用这些bootloader,只需要在内核上做出一点点设置即可。这样做,一来保证了通用性,二来使事情变得更加简单。同时,可以很容易的支持U盘引导系统,并且U盘还可以存储其他数据。这样子可以很简单的在自己的电脑上进行测试。所以,我个人选择了使用标准化的bootloader引导我的系统。

总体概述

BareBone中仅仅有几个文件,其中Makefile是编译脚本,方便自动编译的。其他的三个文件列举如下。做一下简单的说明。
  • loader.S - GRUB等标准化bootloader启动后,调用loader.S中的loader函数,这是内核的入口点。这个汇编文件的作用就是分配一定量的栈空间,并调用外部的kmain函数(也就是调用C语言写的入口点)。
  • main.c - 顾名思义,内核的入口点。里面有个函数叫做kmain,被loader.S调用。
  • linker.ld - 链接脚本。grub等bootloader有一定的可执行文件格式,这里使用elf进行连接。具体的连接设置在这个链接脚本中。例如哪个段在哪个位置等等。
下面就每个文件进行更加细致的讲解。

文件讲解

这些文件都是可以找到源代码的。请从代码下载地址下载代码。

loader.S

在loader.S的前几行EQU部分,定义一些常量,这些常量是为了告诉Grub这个内核是可以被引导的。当然,定义常量仅仅相当于C语言中的#define,并没有分配内存。

在section .text后,是代码段的开始。可以看到,在代码段开始的时候,分配了一个双字,将那些刚才定义的常量写下来。

在loader函数中,按照C语言的调用约定,加入了几个参数。并调用了kmain。这里使用了标准的Multiboot方式引导,具体可以参考Multiboot的相应文档。

在kmain结束后,系统进入一个死循环。这样子,就算是退出了。(事实上,后面会写关机的。只是先死循环在这)

loader.S使用

nasm -f elf -o loader.o loader.S
编译

main.c

在main.c中,首先检查了magic是否正确,也就是Multiboot是否正确的引导。如果不正确,就不能相信grub引导所提供的参数了(GRUB引导会提供一些参数,表示计算机当前的硬件情况,例如内存大小等)。

第二步,是直接对0xb8000位置的显存进行写操作。写入一个字符。默认的时候,在保护模式下可以对0xb8000进行写操作,输出到显示器上。

main.c使用

i586-elf-gcc -o main.o -c main.c -Wall -Wextra -Werror -nostdlib -fno-builtin -nostartfiles -nodefaultlibs
编译。

linker.ld

这里写了各种数据段代码段的安排,给连接器做脚本。连接时使用
i586-elf-ld -T linker.ld -o kernel.bin loader.o main.o
进行连接。

连接完毕后,就有一个可供启动的kernel.bin了。

自动化构建Makefile

如果仅仅有这么三个文件,一行一行的敲命令没有什么问题。但是,随着开发必然的情况是文件越来越多。这时候,我们需要一种方式帮我们自动化的编译。

我选择Makefile进行管理,这里写了一个Makefile示例,和上边所调用的编译命令一致。

模拟器中运行

这里选择qemu模拟器,这个模拟器与其他模拟器相比有几个优势。
  • 可以直接载入内核文件,不需要创造镜像文件
  • 可以模拟arm等其他CPU内核的文件
  • 可以良好的模拟GUI(后期方便)
在安装好qemu的系统中,在含有kernel.bin目录中,运行qemu -vga std -kernel kernel.bin即可以启动系统。

或在RayCommand的根目录,输入make run,即可运行。

启动效果截图

这里可以看到,对话框中第一个字母输出是A,证明程序正确的运行。(其他的字母仍在,是因为程序并没有清屏的工作)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值