fluentos-C
所属分类:操作系统开发
开发工具:C/C++
文件大小:1248KB
下载次数:45
上传日期:2006-10-30 00:00:40
上 传 者:
rj45
说明: 我个人编写的操作系统,实现了保护模式并切换到用户态运行用户进程,对与操作系统初学者有一定帮助!
(I personally prepared by the operating system, achieved a protected mode and switch to user mode users running process, with the right operating system will definitely help beginners!)
文件列表:
fluentos-C\boot\boot.asm (6204, 2005-11-27)
fluentos-C\boot\boot.bat (33, 2005-11-05)
fluentos-C\boot\head.asm (539, 2005-12-08)
fluentos-C\boot\head.bat (112, 2005-11-27)
fluentos-C\boot\init.asm (5550, 2005-11-27)
fluentos-C\boot\init.bat (33, 2005-11-06)
fluentos-C\boot (0, 2006-07-03)
fluentos-C\build\boot.bin (512, 2006-03-12)
fluentos-C\build\build.bat (813, 2006-01-17)
fluentos-C\build\buildw.bat (614, 2006-04-09)
fluentos-C\build\head.obj (328, 2006-03-12)
fluentos-C\build\help.txt (10276, 2005-12-21)
fluentos-C\build\init.bin (464, 2006-03-12)
fluentos-C\build\kernel (8704, 2006-04-09)
fluentos-C\build\kernel.map (4012, 2006-04-12)
fluentos-C\build\ld.exe (642048, 2004-09-05)
fluentos-C\build\ldbak.exe (559104, 2002-10-09)
fluentos-C\build\ld_script.txt (420, 2005-12-21)
fluentos-C\build\link.ld (356, 2005-12-01)
fluentos-C\build\link.txt (55, 2005-12-01)
fluentos-C\build\main.asm (1386, 2006-04-09)
fluentos-C\build\main.obj (758, 2006-04-09)
fluentos-C\build\object_manager.asm (5171, 2006-04-09)
fluentos-C\build\object_manager.obj (906, 2006-04-09)
fluentos-C\build\screenctrl.asm (11419, 2006-04-09)
fluentos-C\build\screenctrl.obj (2108, 2006-04-09)
fluentos-C\build\vc70.pch (262144, 2006-04-09)
fluentos-C\build (0, 2006-07-03)
fluentos-C\Debug (0, 2006-07-03)
fluentos-C\doc\BBS水木清华站∶精华区.files (0, 2006-07-03)
fluentos-C\doc\BBS水木清华站∶精华区.htm (44230, 2005-11-10)
fluentos-C\doc\BBS水木清华站∶精华区2.files (0, 2006-07-03)
fluentos-C\doc\BBS水木清华站∶精华区2.htm (21559, 2005-11-10)
fluentos-C\doc\Bochs调试指南.files\bn.gif (44256, 2005-11-08)
fluentos-C\doc\Bochs调试指南.files\style.css (3159, 2005-11-08)
fluentos-C\doc\Bochs调试指南.files (0, 2006-07-03)
fluentos-C\doc\Bochs调试指南.htm (9398, 2005-11-08)
fluentos-C\doc\LinuxRen - 内核学习方法 - 《Linux内核完全注释》部分习题答案----沪ICP备05008216号.files\35.gif (7889, 2005-11-14)
fluentos-C\doc\LinuxRen - 内核学习方法 - 《Linux内核完全注释》部分习题答案----沪ICP备05008216号.files\A4FCCED85B85DD511EB0F3715D95AEDC.gif (5294, 2005-11-14)
fluentos-C\doc\LinuxRen - 内核学习方法 - 《Linux内核完全注释》部分习题答案----沪ICP备05008216号.files\arrow_dw.gif (95, 2005-11-14)
... ...
------------2005/11/05------------------------------------------
这是我的个人操作系统,它的英文名字叫做fluent,中文名字叫做顺顺。
我不是为了哗众取宠,而是把它当作一种爱好、乐趣,或者说是一种理想。
首先,我最看重的是和谐的家庭,我并不想抛弃我的一切,去实现所谓远大的
目标,我喜欢渐进的改变着自己。写个操作系统,也许是慢慢改进自己的一
方法......
我想写一个实用的系统内核,《操作系统设计与实现》是我的工具,它
会教我写一个好的系统内核,但是仅仅是内核。其他的如,shell,编译器,
连接器等等,可以移植现有的开源工具,只有这些东西都具备了,才
可以称的上是一个可以使用的操作系统。
开发工具采用NASM+VS.NET2003+qmake工具(自动生成工程文件) wrong!!!2005-11-29
------------2005/11/07--------------------------------------------
在写启动程序时(boot),
LOADSEG EQU 0x6000 ; load segment address 加载段地址
LOADOFFSET EQU 0x0000 ; load offset address 加载段偏移
使用jmp LOADSEG:LOADOFFSET时,bochs无法启动,但把LOADSEG EQU 0x500
时,可以启动,怀疑后续扇区还没有真正的加载到0x6000,所以出现这种错误
-------------2005/11/08--------------------------------------------
掌握住调试的利器。在jmp LOADSEG:LOADOFFSET跳到一堆乱码上。如果LOADSEG
<=0x500时,会跳回到0x500:0x200(相当于0x7c00:00),重复执行程序。当LOADSEG〉
0x500时,就再也回不到0X7C00地址上来了.
修改:
将init.bin复制到第二个扇区,并且init.bin最后的命令为
halt:
jmp halt
就OK了。
-------------2005/11/09--------------------------------------------
在init.asm添加了设置保护模式的代码后,就崩溃了。
-------------2005/11/10--------------------------------------------
找到了原因,保护模式代码包含 bits 32.而此时PrintMessage放在后面,被
当作32位运行。而它的调用是在没有进入保护模式之前进行的。提到init.asm
之前就没有问题了。
-------------2005/11/11--------------------------------------------
在lgdt 命令执行后,总是不能跳转到保护模式。经检验,描述符加载不正确。
跳到保护模式之后,出现错误,添加mov sp,0xffff; 之后,不再出现错误。
但老是跳转不到正确的地方去,经过反反复复的调试,原来init.asm的代码被
加载到0x5000:0处,而protectmode标签出的代码没有被移动到0x0000处。如下
jmp codesel:protectmode
bits 32 ;32位运行
protectmode :
mov ax,datasel
此时protectmode 如果等于30,那么段地址等于0x5000。而我们的段描述符的基地址已经变成0x0000,当然出错了。
-------------2005/11/11--------------------------------------------
linux0.11经典问题整理
1、PC机在上电时候所说的在物理地址0处开始初始化中断向量,是说在内存的起始位置1K空间内放256个中断矢量么?
2、是不是说在代码中出现的INT 0X13等就是在这个向量表中找到相应的服务程序呢?
3、这些中断服务程序在640K~1M的内存里面么?这些服务程序是从哪里来的?
4、之所以将SYSTEM模块不直接搬到0X00000处,而是先搬到0X10000是因为其间要使用这些中断向量么?
5、那在后来将SYSTEM模块搬到0X00000,进入了保护模式,把中断描述符都指到默认的无中断过程代码后,在MAIN.C中出现的INT 0X80是根据什么进行的系统调用呢,这时候前1K的向量表不是已经被破坏了么?
1. 是的。
2. 在实模式下是这样的。
3. 是的,这些中断服务程序在ROM BIOS中。
4. 是的,bootsect需要把system先加载到x010000位置处就是要避免覆盖掉实模式的中断向量表。因为setup程序需要使用ROM BIOS中断。
5. main.c在调用int 0x80之前会先执行init_schedule(),其中对int 0x80进行了初始化设置。
-------------2005/11/27--------------------------------------------
编译head.asm的命令
nasm -o head.o head.asm
单独链接head.o,主要目的是去除目标文件中的一些信息(具体这些信息是什么,
请参考深入理解计算机系统一书中链接一章)
ld -Ttext 0x0 --oformat binary -s -o head head.o
终于明白了连接的原理,经过调试,现在可以调到head中去了
-------------2005/11/29--------------------------------------------
考虑开发工具:
调试工具: bochs
汇编工具: nasm
C/C++编译器: djgpp
二进制编辑工具: winhex
1、32位代码([BITS 32]),它调用函数 k_main(), k_main() 定义在 kernel.c 中。
你可能想知道为什么在c源文件叫它k_main而在汇编文件中叫它_k_main,这是因
为C/C++编译器在所有c/c++函数前添加一个下画线。(除非你将其连接到一个ELF文件)。
2、具体让哪个函数首先执行可以通过连接命令ld 进行控制,由于系统的整个kernel的代码被
加载至0x80000地址处, 并且系统的kernel的入口为kernelEntrance()函数,所在以
makefile中使用一条ld命令将各个.c .s 编译后的.o文件连接成为一个kernel.o目标文件,
如
$(LD) $(OBJS) $(LDFLAGS) -o $@.pre
其中的$(LDFLAGS) = -melf_i386 -Ttext 0x80000 -e kernelEntrance
这里便指定了kernel.o的code被加载到 0x80000 的地址, -e kernelEntrance 即制
定程序的入口为kernelEntrance()函数。
3、还有 stosl指令 什么作用.
把eax内容保存到 ES:[edi]内存处,并更新edi(增或减4)。
stos后缀:b -- 字节; w -- 16位字; l -- 长字。
-------------2005/11/29--------------------------------------------
这样写有错误:
.bss: {
*(.bss)
*(.common)
end = . ; _end = . ;
}
一些有bug的 ld 会把 'end' 放在common 和 bss中间. 所以应该这样写:
...
*(.common)
}
end = .; _end = . ;
(thanks to Jarek Pelczar for finding this bug)
partcopy bootsec.bin 0 200 floppy.img 0
这句是将bootsec.bin的前512B(200H=512)拷贝到floppy.img的前512B(第一个扇区MBR)
partcopy main.bin 0 1000 floppy.img 200
这句是将main.bin的内容拷贝到floppy.img的第二个扇区以后(不够1000H会报错但不必理会)
objcopy -O binary -R .note -R .comment
真是不好意思,又发了一片废文,刚刚看了赵老师修改的makefile,里面讲得很明白。
在ld的选项里加上-e startup_32.不过我把ld的选项改过以后,_start_stack的地址现在是0x18260,但是那个print_guard_results:guard_found还是照样出现。看了更本就不是这个原因。正在查找当中。
-e startup_32
编写操作系统或引导程序时,GCC和NA***是两个常用的工具。一般而言,我们总是希望在写这样的代码时,生成的目标文件是无格式的,也不需要重定位,直接从磁盘读入内存,并跳转到第一个字节去执行就可以了。因此,要求第一个字节是可执行代码的入口。但是GCC并没有那么合作,在默认的情况下,它会把数据段放在前面,这就是为什么GCC在连接时,需要用户指定入口地址。为了让GCC把代码段放在前面,我们可以使用-ffreestanding选项。
下面举一个例子。假如我们正在写一个操作系统的加载程序,这个程序由两个文件构成,boot.asm和boot.c。假定这个程序将被引导扇区的程序加载到0x8000处,那么我们可以写出下面的一个makefile:
all:boot
boot:boot.ld asm.o c.o
ld -T boot.ld -o boot asm.o c.o
asm.o: boot.asm
nasm -faout -o asm.o boot.asm
c.o: boot.c
gcc -ffreestanding -c -o c.o boot.c
其中boot.ld是一个控制ld的脚本文件,内容如下:
OUTPUT_FORMAT("binary")
SECTIONS
{
.text 0x8000 : {
*(.text)
}
.data : {
*(.data)
}
.bss :
{
*(.bss)
}
}
--------------------2006/03/11--------------------------------------------
使用ld命令连接成的内核,需要去掉一些头部信息,为512字节
--------------------2006/04/06--------------------------------------------
全局变量的定义:
以下是如何定义全局变量。众所周知,全局变量应该是得到内存分配且可以被其他模块通过
C语言中extern关键字调用的变量。因此,必须在 .C 和 .H 文件中定义。这种重复的定义
很容易导致错误。以下讨论的方法只需用在头文件中定义一次。虽然有点不易懂,但用户
一旦掌握,使用起来却很灵活。表1.2中的定义出现在定义所有全局变量的.H头文件中。
程序清单 L 1.2 定义全局宏。
#ifdef xxx_GLOBALS
#define xxx_EXT
#else
#define xxx_EXT extern
#endif
.H 文件中每个全局变量都加上了xxx_EXT的前缀。xxx代表模块的名字。该模块的.C文件中有以下定义:
#define xxx_GLOBALS
#include "includes.h"
当编译器处理.C文件时,它强制xxx_EXT(在相应.H文件中可以找到)为空,(因为xxx_GLOBALS已经定义)。
所以编译器给每个全局变量分配内存空间,而当编译器处理其他.C文件时,xxx_GLOBAL没有定义,
xxx_EXT被定义为extern,这样用户就可以调用外部全局变量。为了说明这个概念,
可以参见uC/OS_II.H,其中包括以下定义:
#ifdef OS_GLOBALS
#define OS_EXT
#else
#define OS_EXT extern
#endif
OS_EXT INT32U OSIdleCtr;
OS_EXT INT32U OSIdleCtrRun;
OS_EXT INT32U OSIdleCtrMax;
同时,uCOS_II.c有中以下定义:
#define OS_GLOBALS
#include "uC/OS_II.H"
当编译器处理uCOS_II.C时,它使得头文件变成如下所示,因为OS_EXT被设置为空。
INT32U OSIdleCtr;
INT32U OSIdleCtrRun;
INT32U OSIdleCtrMax;
这样编译器就会将这些全局变量分配在内存中。当编译器处理其他.C文件时,
头文件变成了如下的样子,因为OS_GLOBAL没有定义,所以OS_EXT被定义为extern。
extern INT32U OSIdleCtr;
extern INT32U OSIdleCtrRun;
extern INT32U OSIdleCtrMax;
在这种情况下,不产生内存分配,而任何 .C文件都可以使用这些变量。
这样的就只需在 .H 文件中定义一次就可以了。
近期下载者:
相关文件:
收藏者: