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 文件中定义一次就可以了。

近期下载者

相关文件


收藏者