编写操作系统真相还原 – 中断系统时, 在编译链接时遇到了一个问题
我先按照书上所说(如下方), 进行编译
gcc -m32 -I lib/kernel/ -I lib/ -I kernel/ -c -fno-builtin -o build/main.o kernel/main.c
nasm -f elf -o build/print.o lib/kernel/print.S
nasm -f elf -o build/kernel.o kernel/kernel.S
gcc -m32 -I lib/kernel/ -I lib/ -I kernel/ -c -fno-builtin -o build/interrupt.o kernel/interrupt.c
gcc -m32 -I lib/kernel/ -I lib/ -I kernel/ -c -fno-builtin -o build/init.o kernel/init.c
ld -m elf_i386 -Ttext 0xc0001500 -e main -o build/kernel.bin build/main.o build/init.o build/interrupt.o build/print.o build/kernel.o
编译后,用ld链接时,也就是最后一行
ld -m elf_i386 -Ttext 0xc0001500 -e main -o build/kernel.bin build/main.o build/init.o build/interrupt.o build/print.o build/kernel.o
运行后会链接失败,显示如下错误:
ld: build/interrupt.o: in function `idt_init':
interrupt.c:(.text+0x3a2): undefined reference to `__stack_chk_fail_local'
ld: build/kernel.bin: hidden symbol `__stack_chk_fail_local' isn't defined
ld: 最后的链结失败: bad value
编译遇到“__stack_chk_fail_local”错误
可能archlinux上会遇到这个问题,其他linux发行版不确定是否会遇到这个问题(大概率不会,因为没找到相应问题的博客)
为了防止ld时出错,我们要在在gcc编译时加上参数-fno-stack-protector
,切记不是在ld链接时加上
正确编译链接如下
gcc -m32 -I lib/kernel/ -I lib/ -I kernel/ -c -fno-builtin -o build/main.o kernel/main.c -fno-stack-protector
nasm -f elf -o build/print.o lib/kernel/print.S
nasm -f elf -o build/kernel.o kernel/kernel.S
gcc -m32 -I lib/kernel/ -I lib/ -I kernel/ -c -fno-builtin -o build/interrupt.o kernel/interrupt.c -fno-stack-protector
gcc -m32 -I lib/kernel/ -I lib/ -I kernel/ -c -fno-builtin -o build/init.o kernel/init.c -fno-stack-protector
ld -m elf_i386 -Ttext 0xc0001500 -e main -o build/kernel.bin build/main.o build/init.o build/interrupt.o build/print.o build/kernel.o
最后进入 bochs 运行成功
每执行一个中断处理程序将会打印字符串“interrupt occur!”一次并换行
我们再来看一下安装后的中断描述符是什么样的,在bochs中输入info idt
第一列是中断门描述符的序号,这里共 0x20 个。target 是门描述符中所指
向的中断处理程序地址,用选择子:偏移量的形式给出,所有中断处理程序所在段的选择子都是 0x0008,
段内偏移地址各不相同,也就是中断门描述符中记录的目标程序的选择子及选择子所在段的偏移量