2.2 Sinos 开发工具简介
选择开发语言只是确定开发环境的第一步,由于每种开发语言都有不少编译工具,而这些编译工具的特点、目标程序格式、运行平台等不尽相同,所以对于进行操作系统开发来说,有必要仔细考察开发语言的编译和链接工具。本节将简单介绍一下目前 Sinos 在开发中所使用到的工具程序,在后面具体讲开发时还会详细讨论各开发工具的用法。
NASM 编译器
NASM(The Netwide Assembler)是一个以可移植性与模块化为目标而设计的一个80x86汇编编译器。它支持众多目标文件格式,包括Linux的NetBSD / FreeBSD, a.out,ELF,COFF,微软16 位的OMF和32位的Win32格式,基至它还可以输出纯二进制文件。它的语法设计得相当的简洁易懂,和Intel语法相似但更简单。
基于这些优点,Sinos在开发中涉及的汇编模块均使用NASM编译,这包括引导记录、实模式引导程序汇编模块以及内核中的32位汇编模块。
使用 NASM 的 bin 输出格式,可以生成一个纯二进制代码目标文件,没有文件头或文件尾,只有与汇编对应的目标代码,这种纯代码可以用于引导记录的生成。
使用 NASM 的 obj 输出格式,可以产生16位OMF格式的.obj文件,该格式的模块文件可以与DOS下C编译器产生的模块进行链接,从而达到混合编程的效果。
使用 NASM 的 Win32 输出格式,可以产生能被Windows下32位链接器识别的模块文件,从而在内核中实现C与汇编的混合编程。
Turbo C 2.0/3.0 编译器
Turbo C 是Borland 公司的编译器产品。该公司在1987年首次推出Turbo C 1.0产品,其中使用了全然一新的集成开发环境,即使用了一系列下拉式菜单,将文本编辑、程序编译、链接以及程序运行一体化,大大方便了程序的开发。1988年,Borland公司又推出Turbo C 1.5版本,增加了图形库和文本窗口函数库等,而Turbo C 2.0则是该公司1989年出版的。Turbo C 2.0在原来集成开发环境的基础上增加了查错功能,并可以在Tiny模式下直接生成.COM (数据、代码、堆栈处在同一64K内存中)文件。还可对数学协处理器(支持8087/80287/80387等)进行仿真。Borland公司后来又推出了面向对象的程序软件包Turbo C++ 3.0,它继承发展了Turbo C 2.0的集成开发环境, 并包含了面向对象的基本思想和设计方法。
虽然Turbo C系列编译器对C程序的支持功能相当强大,但这些功能大部分是基于其庞大的运行库的,这对操作系统开发来说没有意义,所以Sinos只用到了Turbo C的最基本的编译功能。当然,其强大的集成开发环境相比,TC本身也是一个相当优秀的编译器。
jloc 链接器
在实模式操作系统即DOS环境下,一般链接程序所产生的目标文件都是DOS格式的可执行映像(.exe文件),每个映像文件都含有一个文件头,其中包括了各类段的定义、段重定位信息等内容,这些内容都是供DOS加载程序时进行内存分配等管理操作的。
然而,在 Sinos 中,实模式引导程序需要的是一个不分段的、已经完成重定位的二进制文件形式,这无论是对于Link还是TLink程序来说都是无法实现的,所以开发 Sinos 引导程序时需要一个特殊的链接器。
jloc是一个由John S. Fine开发的免费链接器,其开发目标是为实模式下的程序模块提供一个可以自由控制的、灵活的链接工具。所以,jloc是一个特别适合于操作系统的开发的链接器。
jloc可以对DOS格式的Obj文件进行链接,所有模块的链接方式通过一个简单的文本配置文件来控制,例如:
========booter.j=========
all:
stub.obj
booter.obj
text.obj
disk.obj
GDT.obj
Paging.obj
PE.obj
HWDetect.obj
HWDTStub.obj
cs.lib
boot: 0
*
这是 Sinos 的实模式引导程序 booter.bin 的链接配置文件。配置文件很简单,只是把所有需要链接的模块列出,由jloc程序依次链接。由汇编编写、NASM编译的stub.obj便被放在了目标文件的最前面,即偏移量为零处。这样,booter.bin 载入后最先执行的就是位于stub.obj中的入口代码。
cl 编译器
cl是Microsoft Visual C++的编译程序,通常并不为人所知,因为大多数情况下,这是通过VC强大的IDE来间接调用的。cl编译器功能相当强大,拥有完整的C/C++支持以及强大的内嵌式汇编程支持,在内核开发时甚至可以将诸如sti、hlt、lgdt等系统指令直接嵌入C程序直接编译。
与cl编译器相配套的,是Link链接程序,用来把cl产生的obj文件链接成目标文件——PE格式的可执行映像。
正如上文所提到的,Sinos内核映像Kernel.dll是一个非常特殊的PE文件,它排除了C运行库,直接指定自己的函数为程序入口。例如,调用Link的命令行参数如下:
Link /OUT:"SINOS_DEBUG/Kernel.dll" /DLL /NODEFAULTLIB /ENTRY:"KernelStartup" /BASE:"0x40000000" /FIXED:No ……
命令行相当长,我们将在以后具体介绍内核开发时再详细讨论它的参数问题。简单地说,/OUT参数指定了目标文件名;/DLL表示链接格式为动态链接库格式;/NODEFAULTLIB用于排除所有的默认运行库;/BASE参数指定了映像中的默认基址,在解析该映像时需要用到;/FIXED:No指示链接器生成重定位信息,以便实模式引导程序在加载内核时可以把它重定位到3G以上虚地址中。