我正在尝试开发自己的操作系统。在设置IDT时,我想像这样使用&isr0获取ISR 0函数的地址:
//The example function
void isr0() {
volatile uint8_t* ptr1 = (uint8_t*)(0xB8000);
ptr1[0] = 'A';
}
void main(){
int ptr = (int)&isr0;
volatile uint8_t* ptr1 = (uint8_t*)0xB8000;
int offset2 = 40;
int value = (int)ptr;
ptr1[0 + offset2] = 48 + (value/100000) % 10;
ptr1[2 + offset2] = 48 + (value/10000) % 10;
ptr1[4 + offset2] = 48 + (value/1000) % 10;
ptr1[6 + offset2] = 48 + (value/100) % 10;
ptr1[8 + offset2] = 48 + (value/10) % 10;
ptr1[10+ offset2] = 48 + (value/1) % 10;
while(1);
...
}
字符串
它的输出是000000。
x1c 0d1x的数据
在普通的Linux机器上,它可以毫无问题地向我显示内存位置。
另外,我注意到,当我尝试创建函数指针,然后调用函数指针时,它确实工作;然而,当我尝试获取它的值时,它就不工作了。(&isr0不可能是一个问题,问题是如何将它解析成int。)
有谁能告诉我为什么会这样,以及如何修复它?
编译步骤
i686-elf-gcc -nostdlib -O3 -ffreestanding -Wall -Wextra -m32 -c kernel.c -o bin/stage4.bin
objcopy -O binary bin/stage4.bin bin/stage5.bin
型
编译这两个使用:
nasm stage1.asm -f bin -o bin/stage1.bin
型
然后把所有的东西放在一起:
cat bin/stage1.bin bin/stage2.bin bin/stage5.bin > bin/stage3.bin
qemu-system-x86_64 -fda bin/stage3.bin -vga vmware -d guest_errors -m 64M >> bin/a 2>&1
型
1条答案
按热度按时间cvxl0en21#
字符串
gcc -c
产生一个可重定位的目标文件,你错误地将其命名为stage4.bin
而不是.o
,它不包含对象在内存中需要的位置的实际地址;相反,它在一个占位符中(可能为0),并有一个单独的重定位表,以通知链接器的名称的符号,其地址应该去那里。你只需要将objcopy
转换成二进制,这只会丢弃重定位表,并留下0占位符占用的内存位置。你必须在你的目标文件上运行链接器来解析所有这些引用,并使用适当的链接器脚本构建一个可执行文件。一些例子见https://wiki.osdev.org/Linker_Scripts。然后你可以将
objcopy
转换为二进制。