译:JamesM的内核开发教程

1.环境配置

我们需要一个基础环境来设计开发我们的内核,在本教程中,我假设您使用的是*nix操作系统和GNU工具集。如果您使用的是Windows操作系统,您必须使用诸如cygwin或DJGPP这类*nux模拟环境。即便如此,本教程中的生成文件和命令仍然可能会出错。

1.1目录结构

我的目录布局如下:

tutorial
 |
 +-- src
 |
 +-- docs

所有的源文件都放入src中,所有的文档都放入docs中(平时开发你写文档吗?)

1.2编译

教程里的所有例子都已经通过GNU工具集成功编译 (gcc, ld, gas, etc),所有样例代码都是用intel风格汇编书写的,因为我个人认为,使用GNU时,intel风格汇编的可读性比AT&T风格汇编的要好很多。我们要使用NASM来汇编程序。

本教程并不是一个内核引导教程,我们使用GRUB来加载内核。为此,我们需要让GRUB预载一个软驱映像。有很多教程可以指导我们使用GRUB,更可喜的是,你可以在我这里找到我做的一个标准软驱映像,把它放在你的教程目录下吧。

1.3运行

什么都不能替代在真机上进行内核测试,但不幸的是,真机的运行结果无法告诉你到底哪里错了(当然,你可能第一次就写出了没有问题的代码,不是吗?)。使用Bochs吧,他是一个开源的兼容32位及64位的虚拟机。当你的程序出错时,Bochs会通知你,并把一些有用的寄存器状态保存到日志中。另外,Bochs比真机启动的快很多,我的所有例子都可以在Bochs上成功运行。

1.4Bochs

为了运行Bochs,我们需要一个Bochs配置文件(bochsrc.txt),凑巧,下面有一个配置例子。

一定要注意这些BIOS文件的顺序,These seem to change between installations(不同版本可能会有不同???)。如果你用源代码直接编译出Bochs,很可能你没有这些文件。Google一下文件名,并从官网站上下载。

megs: 32
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000
vgaromimage: /usr/share/bochs/VGABIOS-elpin-2.40
floppya: 1_44=/dev/loop0, status=inserted
boot: a
log: bochsout.txt
mouse: enabled=0
clock: sync=realtime
cpu: ips=500000

以上设置使Bochs虚拟出一个32M内存,350MHz P2的CPU。每秒都会刷过很多信息——但我喜欢一个慢速的虚拟机,原因很简单,这样我可以看清很多文字在滚动。

1.5 使用脚本

我们将要频繁的做一些事——编译和连接我们的项目,把生成的二进制内核写入软驱镜像。

1.5.1 生成脚本

代码
# Makefile for JamesM's kernel tutorials.
# The C and C++ rules are already setup by default.
# The only one that needs changing is the assembler 
# rule, as we use nasm instead of GNU as.

SOURCES=boot.o

CFLAGS=
LDFLAGS=-Tlink.ld
ASFLAGS=-felf

all: $(SOURCES) link 

clean:
 »  -rm *.o kernel

link:
 »  ld $(LDFLAGS) -o kernel $(SOURCES)

.s.o:
 »  nasm $(ASFLAGS) $< 

 

这段生成脚本将编译SOURCES中的每个文件,并把他们连接在一起生成一个二进制内核。当然,做这些需要一个连接脚本,下面所说的link.ld就是做这个的。

1.5.2 link.ld

代码
/* Link.ld -- Linker script for the kernel - ensure everything goes in the */
/*            Correct place.  */
/*            Original file taken from Bran
's Kernel Development */
/*            tutorials: http://www.osdever.net/bkerndev/index.php. */

ENTRY(start)
SECTIONS
{
  .text 0x100000 :
  {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(4096);
  }

  .data :
  {
     data = .; _data = .; __data = .;
     *(.data)
     *(.rodata)
     . = ALIGN(4096);
  }

  .bss :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    . = ALIGN(4096);
  }

  end = .; _end = .; __end = .;

 

这段脚本告诉LD如何建立内核映像。首先,它告诉LD开始的位置应该在start符号的位置。之后,他告诉LD,.text (你的代码所在)将从0x100000开始执行。之后执行.data段和.bss段,这两项都是page-aligned (ALIGN(4096)),Linux GCC也增加了一个额外的数据段:fodata,这个只是用来初始化,像常数一样。为了简单起见,我们捆绑使用他们。

posted on 2010-08-31 01:14  寻雨  阅读(942)  评论(0编辑  收藏  举报

导航