-
编写进程之前,写了一个 TestProcess() 函数,这个函数当作一个进程来测试。中途 遇到一个语句
mov fs, ax
引起了 #GP fault,第一感觉很奇怪,这只是一个赋值语句而已 怎么会引起一个保护模式下的异常? -
fs
是一个段寄存器,保护模式下给段寄存器赋值会从GDT或LDT里面预先读取段的属性 (参考概念:影子寄存器),如果当前的CPL\RPL不满足目的段的要求,会引发一个 #GP fault。 -
用了三个进程 TestA、TestB、TestC (按照顺序放在一个数组里)测试多进程,调度 用轮转算法。经过一轮轮转后,发现所有的进程都在执行 TestC 的代码。
-
排查了GDT里面的TSS、TSS里面的LDT selector,数据都是对的,很奇怪。尝试各种方法无果 后准备先洗个澡。边洗边回顾 task switch 的整个流程,发现从内核态返回时会从 kernel stack 里面返回 eip,会不会某个地方写错了,导致三个进程使用的是同一个 kernel stack。经过排查, 发现在进程初始化设置堆栈时用的是
&task + PAGE_SIZE
,多加了一个&,修改成task + PAGE_SIZE
就可以了。 -
代码内定义了一个全局变量,并且赋值为0。但程序实际执行过程中,发现这个变量值是乱码, 但只要修改初值为除0外的其他值,就不会出现乱码现象。猜测是 i386-gcc 对初始值为0的变量有 什么特殊处理。
-
invalid instruction suffix for `mov' "movw %%bx, %0\n\t"
-
sti() 指令移动位置导致 #GP
-
如果在c里面定义了全局变量\静态变量,如果赋值成 0,那么第一次引用这个变量会发现其值 不是0,而是一个随机值,这明显和常识不符。如果是赋值成其他值,比如0、1之类的,运行中其值才是 对的。
-
测试了很多次,发现如果一个全局变量\静态变量的内存地址相差很大。比如:
static int a = 0; static int b = 1;
虽然a、b在代码中是同一个位置定义的,但是两者内存地址的距离却很远。这让我想到了gcc可能是将 初始值为0的变量放置在了 .bss 段里面了,而这个 OS 的 loader 是仿照 Orange'S 来写的,里面 并没有初始化内核 .bss 段的操作,因此导致了初值为0的全局变量\静态变量的值都是随机的。