您的位置:首页 > 其它

实现自己的操作系统 第三部分

2008-03-31 12:59 549 查看
3-1

2006-1-9 23:43

实现了和C函数的整合。

ld -Ttext org之后的obj的顺序似乎有讲究。

call 命令对堆栈的影响:
16位的实模式中,会将cs和ip压栈,因此栈会减少4。
32位的保护模式中,如果是段内调用,只会将eip压栈;如果是段间调用,会将eip和cs入栈,不过目前还没遇到过这种情况。

C函数调用约定
参数从右向左入栈,在汇编中等调用完后,要手动将esp的值复位。
返回值是4字节时,通过eax传递;2字节通过ax传递;1字节通过al传递。

3-2

2006-1-12 23:47

将光标的行列值改成了全局变量。

在汇编中如果入栈一个符号变量,那入栈的会是指向这个变量的指针。
但在C语言中调用汇编中声明的全局变量时,得到的是这个变量本身而不是其指针。

汇编中用global声明全局变量时,应把该global声明放在它相应的data或bss段中。

3-3

2006-1-14 03:19

实现了中断函数的初始化。

中断函数和函数是不同的概念。
后者可以直接调用,而前者不能。

从汇编层次看,数组和指针是不一样的。
比如:
汇编:
global g_idtr
g_idtr:
%rep 256
dd 0
dd 0
%endrep

C语言中,如果如下声明:
extern long long g_idtr[256];
则可以正常操作。

但是如果使用
extern long long * g_idtr;
那么程序会出错。

究其原因,当使用的是指针时,程序会分配一个空间保存该指针本身的值,而当使用数组时,则不将此标号作为变量另外保存。

3-4

2006-1-14 23:28

实现了部分printf的功能,能够分辨%d和%x。
还没有在其中实现系统调用、/n/t、光标跟随移动等。

实现了一些字符串函数。

3-5

2006-1-15 23:01

完善了printf,当前拥有的功能包括
/t /n %x %d

已经能获取内存信息,目前暂不添加内存映射。

3-6

2006-1-16 22:03

完善了中断函数。

general_intr.c中的宏定义和中断的实现是值得好好研究的。

3-7

2006-1-17 20:38

操作了8259,实现了一个时钟中断。

保护模式下中断产生时,系统在通过中断门后自动关中断,并在iret中自动开中断。

在io.h中的outb等宏定义上面花了很多时间。

x86上指针和in、out等汇编指令是区分的,操作端口的时候不能使用指针,这与arm结构不同。

0xb8000开始的那一段内存由bios进行了映射,所以才可以用指针操作,这只是一个特例。

3-8

2006-1-18 3:09

实现了光标的跟随移动。

如果编译时指定了-O优化,那么使用asm嵌入式汇编的时候就要小心了。
即当指定汇编中参数为任意寄存器,同时汇编本身也用到寄存器的话,就可能会引起冲突。
如:
#define outb(port,value) /
__asm__ __volatile__ ( /
"movb %1, %%al /n" /
"movw %0, %%dx /n" /
"outb %%al, %%dx /n" /
: :"r"(port), "r"(value) /
)
当调用时参数是立即数的时候可以运行,但当参数是变量的话就出错。
原因:汇编内部和调用参数本身都使用了al存放数据。
如果把"r"指定为"m",那么也能成功,但不排除以后又会因为优化而产生问题,
所以目前的解决方法:不使用优化。

3-9

2006-1-18 7:26

实现了滚屏操作,但目前只支持一个控制台。

计划总共实现4个控制台,每个占一页。
所有控制台都可以映射到current console中,占4页。

3-10

2006-1-20 18:01

实现了键盘的读取。

inb等函数也已实现。

3-11

2006-1-24 11:02

实现了不同权限之间的切换。

注意ldt指令一定要在kernel中更换了gdtr之后才能使用,为此浪费了5个小时。

下一步是添加系统调用。

3-12

2006-1-24 22:22

实现了一个简单的陷阱门。

Linux中的0x80属于陷阱门,使用陷阱门来完成系统调用的操作,而不是使用调用门。
因此本系统中也将不实现调用门。

陷阱门和中断门一样,返回时也是使用iret。不同之处在于进入中断门的时候会自动cld。

从用户级进入到特权级时,仅仅cs和ss属于当前级,其他段寄存器仍然属于用户级,因此需要手动更改,
这在Linux中是由SAVEALL宏完成的。

需要注意的是,SAVEALL中只改变了ds和es,fs和gs保留原值,后两个似乎从来不需要。

目前中断不允许嵌套,但在陷阱门中可以进行中断。

3-13

2006-1-25 17:32

添加系统调用实现了write_console,目前暂时还没有控制台的概念。

此系统调用还实现了返回值的功能,比较有趣的。

3-14

2006-1-26 20:04

实现了进程切换。

进程切换最关键的地方,就是系统返回用户空间的时候内核态堆栈总是在同一个偏移处。
可以据此判断cpu现在究竟是返回用户空间,还是仅仅在系统空间中嵌套返回。
了解了这一点,切换进程就不是很困难了。

另外需要注意的是,系统进入内核空间的时候要使用到tss中的esp,这个值在切换进程时要预先设置好。

至此,操作系统的编写就告一段落了。

代码地址:

http://d.download.csdn.net/filedown2008/aHR0cDovL2RsMi5jc2RuLm5ldC9kb3duNC8yMDA4MDMzMC8zMDIxMzU0MTgyMi56aXA=!398454
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: