使用gcc和nasm断断续续修改Makefile,最终完全解决和达到最初在windows下的效果,大概花了十多天时间,中间遇到许多问题,也不单单是gcc和nasm命令的问题,尤其是是否在第一个汇编文件boot.asm里就进入保护模式。。。。。还是放在kernel.asm里边。。。。这花了我七八天时间,本来是将进入保护模式的程序放在kernel.asm里边但是发现不成功,然后我怀疑是不是gcc和nasm的问题,还是代码对齐的问题-----最后没有这么干,但是发现了问题,是生成的kernel.bin文件前有elf头(大概0x1000),其本质就是在boot.asm里边跳转地址不对(这都是采用第二种方法后debug出来的),还一个说明,就是在保护模式下的跳转(jmp)不能跟原来一样了,,
-
例如: jmp 0x08:_start;(_start在第二个文件开头,使用这个指令不知道jmp到什么地方去了)
-
可以采用的跳转: MOV EAX,0x9000 JMP EAX 感觉如果使用汇编不精通,写的代码啥都有可能发生,解决办法就一个:慢慢使用bochs慢慢单步调试,这些问题都能发现
C:\kernel developer\tolset\helloos0>make
C:\kernel developer\tolset\helloos0>..\z_tools\make.exe
../z_tools/make.exe -r img
make.exe[1]: Entering directory C:/kernel developer/tolset/helloos0' ../z_tools/make.exe -r wrwos.img make.exe[2]: Entering directory
C:/kernel developer/tolset/helloos0'
../z_tools/nask.exe bootfirst.nas bootfirst.bin bootfirst.lst
NASK : LSTBUF is not enough
make.exe[2]: *** [bootfirst.bin] Error 19
make.exe[2]: Leaving directory C:/kernel developer/tolset/helloos0' make.exe[1]: *** [img] Error 2 make.exe[1]: Leaving directory
C:/kernel developer/tolset/helloos0'
..\z_tools\make.exe: *** [default] Error 2
这个错误是没有将bootfirst后边填充数据的代码去掉,由于添加了其他代码,空间已经不过用了
C:\kernel developer\tolset\helloos0>make
C:\kernel developer\tolset\helloos0>..\z_tools\make.exe
../z_tools/make.exe -r img
make.exe[1]: Entering directory C:/kernel developer/tolset/helloos0' ../z_tools/make.exe -r wrwos.img make.exe[2]: Entering directory
C:/kernel developer/tolset/helloos0'
../z_tools/nask.exe bootfirst.nas bootfirst.bin bootfirst.lst
../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek
wbinimg src:bootfirst.bin len:512 from:0 to:0
copy from:bootsecond.sys to:@:
imgout:wrwos.img
imgout BPB data error.
make.exe[2]: *** [wrwos.img] Error 37
make.exe[2]: Leaving directory C:/kernel developer/tolset/helloos0' make.exe[1]: *** [img] Error 2 make.exe[1]: Leaving directory
C:/kernel developer/tolset/helloos0'
..\z_tools\make.exe: *** [default] Error 2
FAT12文件的很重要,不能随意更改其中的文件名字(只是更改名字会出错)
-------->2017.05.24
向64h端口写入的字节,被认为是对8042芯片发布的命令(Command): 写入的字节将会被存放Input Register中; 同时会引起Status Register的Bit-3自动被设置为1,表示现在放在
向64h端口写入的字节,被认为是对8042芯片发布的命令(Command): 写入的字节将会被存
放Input Register中; 同时会引起Status Register的Bit-3自动被设置为1,表示现在放在
Input Register中的数据是一个Command,而不是一个Data;在向64h端口写某些命令之前必
须确保键盘是被禁止的,因为这些被写入的命令的返回结果将会放Output Register中,而键
盘如果不被禁止,则也会将数据放入到Output Register中,会引起相互之间的数据覆盖;
在向64h端口写数据之前必须确保Input Register是空的(通过判断Status Register的Bit-1
是否为0)。60h端口(读操作),对60h端口进行读操作,将会读取Output Register的内容。
Output Register的内容可能是:来自8048的数据。这些数据包括Scan Code,对8048发送的
命令的确认字节(ACK)及回复数据。 通过64h端口对8042发布的命令的返回结果。在向60h端口
读取数据之前必须确保Output Register中有数据(通过判断Status Register的Bit-0是否为1)。
60h端口(写操作)向60h端口写入的字节,有两种可能:
[1].如果之前通过64h端口向8042芯片发布的命令需要进一步的数据,则此时写入的字节就被
认为是数据;
[2].否则,此字节被认为是发送给8048的命令。 在向60h端口写数据之前,必须确保
Input Register是空的(通过判断Status Register的Bit-1是否为0)。
向一个空软盘保存文件的时候, 1.文件名会写在0x2600以后的地方(这里我没有去验证); 2.文件的内容会写入到0x4200以后的地方. 决定后边的0xc200
-------->2017.06.23
使用一般的编译器编译操作系统,不再依赖原来作者自己的编译器
使用linux系统,在ubuntu下选择和组合一套工具编译运行这个操作系统
使用一般的编译器编译操作系统,不再依赖原来作者自己的编译器使用linux系统,在ubuntu下选择和组合一套工具编译运行这个操作系统
当前对系统只将堆栈指针指向0x7c00,此处在C代码里边定义一个全局变量,似乎没有存储 这个全局变量的空间,如果设置成局部变量,达到了预想的效果,猜测可能是没有在链接脚本 指定全局变量空间 debug:此处的问题不是链接脚本的问题,是生成的kernel.bin文件是一个elf文件,文件最 开始是elf的头,所以是跳转的地址不对
-------->2017/08/23
完善Deeppink的显示字符串函数(console_puts),添加对字符串里换行等的支持,添加
光标移动函数(console_movecursor)
-------->2017/08/24
添加kernel/printk.c文件
-------->2017/08/25
添加descriptor.h文件,使用c语言重新初始化gdt和idt表
问题:在使用bochs调试时,sreg命令显示的valid=1 or 31是什么意思
-------->2017/08/26
问题:console_puts函数有一个bug,使用printk函数时总是不能按下原来的光标坐标
往下显示。
-------->2017/08/27
console_puts函数的bug是在do{}while里边使用break,以为这个break可以跳出外边的
while循环,看来只是跳出了do-while循环
另外添加console_readcursor函数(读取光标坐标),在console_puts函数开始,先读取
坐标,然后往下显示
完善Deeppink的显示字符串函数(console_puts),添加对字符串里换行等的支持,添加 光标移动函数(console_movecursor)
添加kernel/printk.c文件
添加descriptor.h文件,使用c语言重新初始化gdt和idt表。 问题:在使用bochs调试时,sreg命令显示的valid=1 or 31是什意思??
问题:console_puts函数有一个bug,使用printk函数时总是不能按下原来的光标坐标往下显示。
console_puts函数的bug是在do{}while里边使用break,以为这个break可以跳出外边的while循环,看来只是跳出了do-while循环另外添加console_readcursor函数(读取光标坐标),在console_puts函数开始,先读取 坐标,然后往下显示
- 添加时钟中断,出现bug如下:
链接生成kernel.bin文件
ld -T scripts/kernel.ld -m elf_i386 ./init/kernel.o ./init/console.o ./init/start.o ./kernel/prink.o ./drivers/timer.o -o init/kernel.bin
./drivers/timer.o:在函数‘isr_handler’中:
/home/lollipop/DeeppinkOS/include/interrupt.h:85:
isr_handler'被多次定义 ./init/start.o:/home/lollipop/DeeppinkOS/include/interrupt.h:85:第一次在此定义 ./drivers/timer.o:在函数‘irq_handler’中: /home/lollipop/DeeppinkOS/include/interrupt.h:135:
irq_handler'被多次定义 ./init/start.o:/home/lollipop/DeeppinkOS/include/interrupt.h:135:第一次在此定义 ./drivers/timer.o:在函数‘register_interrupt_handler’中: /home/lollipop/DeeppinkOS/include/interrupt.h:151: `register_interrupt_handler'被多次定义 ./init/start.o:/home/lollipop/DeeppinkOS/include/interrupt.h:151:第一次在此定义 Makefile:50: recipe for target 'link' failed make: *** [link] Error 1
解决办法:
源文件的头文件太多,相互关系包括可能有重复,因此将interrupt.h分成两部分 ----->interrupt.h和interrupt.c,这样只在头文件里边定义原型,在interrupt.c里边 定义函数内容
-------->2017年 08月 30日 星期四 00:17:18 CST
添加键盘处理功能,包括文件keyboard.c和keyboard.h,本来打算按照hurlex-doc将
内存管理部分的分页功能打开,但是发现有点复杂,以后在完善内存管理功能
按键部分目前不完善,只是做了简单的中断处理,和显示数字、小写字母等,对于一
些包括ctrl、shift等按键不支持,按键部分先这样,以后有需求再更改
-------->2017年 08月 31日 星期四 21:17:50 CST
目前,发现整个DeeppinkOS的内存映射特别混乱,包括gdt表地址、ldt表地址和堆栈,
有太多地方需要规范了,先不再往后打开分页机制和进程管理
-------->2017年 09月 01日 星期五 20:41:05 CST
今天,编译这个内核大于1.44M,因此,在想是否使用dd产生的软盘是否可以大于
1.44M。
修改pmm.c文件,将物理内存从0--4G重新分配到一个数组里边,因此导致整个内核
需要4M的连续空间,原来的内核加载地址0x8000已经不能满足需要,因此必须将内核加载
到0x100000(1M)以后才行(1M以后是连续可以的空间)。
make: *** [link] Error 1
- 解决办法: 源文件的头文件太多,相互关系包括可能有重复,因此将interrupt.h分成两部分:interrupt.h和interrupt.c,这样只在头文件里边定义原型,在interrupt.c里边定义函数内容。
添加键盘处理功能,包括文件keyboard.c和keyboard.h,本来打算按照hurlex-doc将内存管理部分的分页功能打开,但是发现有点复杂,以后再完善内存管理功能。 按键部分目前不完善,只是做了简单的中断处理,和显示数字、小写字母等,对于一些包括ctrl、shift等按键不支持,按键部分先这样,以后有需求再更改。
目前,发现整个DeeppinkOS的内存映射特别混乱,包括gdt表地址、ldt表地址和堆栈,有太多地方需要规范了,先不再往后打开分页机制和进程管理。
今天,编译这个内核大于1.44M,因此,在想是否使用dd产生的软盘是否可以大于1.44M。
修改pmm.c文件,将物理内存从0--4G重新分配到一个数组里边,因此导致整个内核需要4M的连续空间,原来的内核加载地址0x8000已经不能满足需要,因此必须将内核加载到0x100000(1M)以后才行(1M以后是连续可以的空间)。
在Makefile添加objcopy功能,删掉kernel.elf相关头信息,节约了一点内存。