发信人: zelor(东村遗少张作乐)
整理人: wenbobo(2003-01-13 17:20:52), 站内信件
|
Doing a kernel in C++
用C++写内核
(This was taken from a message on the OS-Dev message board)
(本文来自于OS开发版的一则信息)
Using C++ is quite easy for the most part just a few snags that have to
be delt with namely the builtin functions that g++ inserts into your
code use the following make line to get rid of most of them.
使用C++时,为了对付众多障碍中的主要部分,也就是builtin function —— 由
g++插入你代码中的函数,简单地使用下面的命令行就可以将其中大部分干掉:
g++ -nostdlib -nostdinc -fno-builtin -fno-exceptions
of course it is easier to just define those options as some macro the
only builtin function you will have to deal with after this will be
__builtin-delete for deleting this __builtin_new for creating new objs
and __builtin_vec_new for arrays of objs simply.
当然,更简单的办法是用宏的形式定义这些选项,你可以用下面的方法处理
builtin function:__builtin-delete (个人怀疑是__builtin_delete。——作乐)删除函数,
__builtin_new 建立新的函数,而__builtin_vec_new可以简单的建立起函数的数
组。(此处对objs是否误解,请wenbobo指正。)
Simply don't use NEW and you are safe from the last two builtins and
just declare this in a header file somewhere
void inline __builtin_delete(void* arg){};
then things should compile without errors if you want to be able to use
new and new[] then you have to define the builtins correctly just like
regular functions where new and new[] take a size number and an
unsigned int and return a void*
i use flat binary mode for the kernel initialization stuff. Compile
everything as modules using (nolib is the crap i described earlier)
在内核初始化阶段,我使用平坦型二进制模式,将所有代码编译成模块使用(NOL
IB是我为了表述清楚所说的废话)。
g++ $(NOLIB) file.cpp -r
the link them in the end using (this is 1 line, but split over two for
display)
将它们按下述连接(实际是一行 ,排版成了两行)。
ld $(NOLIB) -o kernel.bin -e main -oformat binary
-Ttext 0x00100000 file1.o file2.o file3.o ...
The entry point where execution will start is int main(); i find that
if you define main() after you define any other functiosn the linker
doesn't produce code properly for binary output so just make main the
first function in your file and make sure that it is the first file in
the list of files linked by ld in the line i described earlier.
程序执行的进入点从int main()开始,我发现如果你把mian()定义在其他函数定
义后面的话,连接器不会正确输出二进制代码,所以在你的源码里一定要把
main()函数放在第一位。而且,如我先前描述的那样使用ld进行连接时,你必须
把包含 main()函数的文件放在连接用文件列表的首位。
Finally -Ttext 0x00100000 tells the linker where the file will be in
memory when it gets executed is at 1MB mark.
最后, -Ttext 0x00100000 告诉连接器,程序文件执行时被加载到内存的什么位
置,例子中是1MB。
Aiyah! Whats RTTI? (Run Time Type Info)
哎呀!什么是RTTI?(运行时类型信息(识别))
(This info take from a message on the OS-Dev message board)
(本文来自于OS开发版的一则信息)
This is the way i understand RTTI...
这是我理解RTTI的途径……
RTTI is for Run Time Type Information. Because you are using a virtual
function and inherritance, it would be possible to pass two completely
different objects to the same function. Because the function is virtual
the compiler cannot create two versions at link time and sort it out
ahead of time, instead it has to be figured out just before it is
executed.
RTTI是运行时类型信息。因为你使用了虚函数和继承,因此经过相同的函数传递
来的可能是两个完全不同的对象。因为函数是虚拟的,编译器不能在连接时建立
两个版本的函数,也不能在这之前整理好它们,相反,它只能在函数运行之前解
决这个问题。
RTTI is a means of (for lack of a better term) enumerating types while
the machine runs and then providing a means to get that type
information for any object (type number). I think you did the rignt
thing by putting -no-rtti in the compile string but if you ever
dynamically change an object from one type to another during run time
you will get into trouble.
RTTI是一种手段(因为缺乏更好的说法),当机器运行时列举出类型同时提供一
种手段给任何对象用来得到类型信息。我认为通过使用编译开关 -no-rtti
禁用RTTI是明智的,如果你总是在运行时动态的把对象的类型变来换去,你将会
陷入困境。
This eg should clarify for all what i think would happen (in a C
equivalent manner).
这个例子可以为所有人阐明我所认为的并非空穴来风(代码使用类似C的风格)
print(char* string)
{
...prints a string which is given as a 32bit pointer on the stack...
...打印字符串,该字符串作为一个栈上的32位指针传递...
}
print(int number)
{
...prints a 32bit integer that is passed as an argument on the stack
...打印一个32位整数,该整数作为参数由栈传递...
}
//now for the types
//现在看类型
int num1=12345;
char name[]="ABCDEFG;
int_or_string variabletype = "I am a string for now"
//now call them
//现在调用函数
print(num1);
print(name);
print(varialbetype);
variabletype = 98765;
print(variabletype);
variabletype = "a string again";
print(variabletype);
The compiler can figure out a compile time that print(num1); is a call
to the integer version of print() and print(name) is a call to the
string version.
编译器在编译期能处理 print(num1);这是print()调用整数的版本,print(name)
则是调用字符串的版本。
But because our variabletype can change from one type (class) to
another it is not possible at compile time to determine which function
to call until we are actually calling it.
但是因为我们的variabletype(可变类型)可以在类型(类别)间转换,它不能
够在编译期被识别,除非我们正确的调用它。
How do I disable RTTI in GCC?
如何在GCC中禁用RTTI?
You can disable RTTI in gcc by adding the switch "-fno-rtti"
你可以在gcc中加上编译开关 "-fno-rtti" 以禁用RTTI。
Can I use NEW and DELETE in my kernel?
我能在我的内核里使用NEW和DELETE吗?
(This message taken from a message on the OS-Dev message board)
(本文来自于OS开发版的一则信息)
The new a delete will be available if you define them as functions and
it is possible to (from real 16bit mode setup a gdt and idt in a kind
of crude fashion then turn on the pmode bit and long jump into the code
using the right selector and offset which will start right into c++
code with objects and everything you want.
如果你将new和delete作为函数定义它们,你将可以利用它们。在16位实模式下
以粗鲁的方式建立gdt表和idt表(有关gdt和idt还有pmode、selector、offset请参考一本关于保
护模式的书,如果没有该内容,请与书籍供应商联系。——作乐),然后
把pmode置位,然后用一个远jump跳转进代码——这是可能的——前提是使用正确的
选择器和偏移量,你则能够正确开始带有对象的c++代码,所有一切将如你所愿。
---- 生活,就是理想加泡面。
——张作乐,送你一束玫瑰
|
|