0%

30天自制操作系统-第二次开启填坑

第二次开始填坑,没有压力真没有动力。老是觉得这样不行那样不行,直到To Do List的堆栈爆了还没动一点点,那还不如开始动手做。上次的进度是认识了实模式,并成功进入了32位模式下,启用了分段的内存管理,打开了保护模式,然后用指针操作了个Demo就草草结束了。

这次重新填坑,碰到了很多问题,但是归根到底是经验太缺乏。之前用了GNU一套工具链,自然有的步骤开始脱离书本,想化为己用还是火候不到,碰到了一些问题要花很久才能解决。

书本上还是用的纯汇编来作为C语言的补充,写了一些函数。之前正好看了一些公开课,诶就是网易孟宁老师的Linux内核,看着内联汇编的实现。那这次就用内联汇编吧。敲代码很快,把这些函数作为一个C的库单独解耦出来,命名为lib.c/libc.h编译出了很多错,后来都一一解决了。分别是:

  • Intel风格汇编和A&AT风格汇编的不兼容,之前看的和书本上都是Intel风格的,一时不习惯,编译不能通过。在Makefile中加入编译选项,-masm=intel后解决。
  • 编译提示Push,Pop,MOV等命令与对操作的数据不匹配,折腾后发现我的操作系统是Debian x64位,安装的工具链是64位,再加入编译选项-m32后提示找不到头文件,通过apt-get安装完依赖后解决。
  • 终于编译完毕,make run伴随着一声强烈有力清脆的回车声,大爷的黑屏了。调试了4个小时,此时我的内心是崩溃的。debug过程很蛋疼,因为没法跟踪调试各个参数和查看变量的值,只能注释修改大法,然后发现在io_out8这个函数这里有问题,因为我把这个循环执行一半(把for循环中的end改为个较小数),发现这调色盘是写过的全黑了。辣么不是这个函数有问题就是数据有问题,但是怎么看都不像是数据有问题啊,数组敲错那也不会全黑啊。于是对函数进行编译,反汇编,怀疑是数据类型的问题,因为就传出8位,int等比这个大。折腾了int8_t和int16_t这些,并引入更多的头文件。但是还是不管用,内心崩溃下重新用nasm作为工具,用纯汇编实现了这些函数。结果很高兴的告诉我我内联汇编实现的不错,因为内联汇编是正确的,纯汇编也黑了,以上4小时我再白费工夫。纠结下在bootmain.c中的io_out8()函数中敲入了立即数0xff,0xff,0xff。白屏了,这更说明了函数编写的都是正确的,那么为啥用static unsighed char定义的数组突然不管用了呢?打开Makefile,objcopy -j .text -O binary bootblock.o bootblock.tmp,真想抽自己,我把数据段删了,我把数据段删了,我把数据段删了…………删了……去掉-j .text之后,一切正常了。
    -此处输入图片的描述