我目前正在开发一个自制的OS项目。我已成功编写了一个引导加载程序,它将计算机切换到保护模式并加载内核,该内核用c编写。我的内核加载正常,但我在调用main()之外的函数时遇到问题。该函数似乎执行正常,但从我可以告诉我没有传递任何参数。我无法弄清楚为什么会这样,希望有人能告诉我我的问题是什么。下面是我的内核的代码,以及用于编译它的命令。
编辑: 在重读了我的问题之后,我想我需要澄清一下,当我说没有通过论点时我的意思。当我调用print_char时,无论我作为参数传递什么值,它都没有效果。但是,如果我修改函数内部的变量,它可以正常工作。
kernel.c
#define VIDEO_ADDRESS 0xb8000
#define WHITE_BLACK 0x0f
void print_char(char character, int col, int row, char att_byte) {
unsigned char* vid_mem = (unsigned char*) VIDEO_ADDRESS;
int offset;
if (!att_byte) {
att_byte = WHITE_BLACK;
}
offset += 2*col;
offset += 80*row;
vid_mem[offset] = character;
vid_mem[offset+1] = att_byte;
}
void start() {
clear_screen();
print_char('X', 0, 0, WHITE_BLACK);
}
的build.bat
nasm boot.asm -f bin -o boot.bin
nasm kernel_entry.asm -f elf -o kernel_entry.o
gcc -ffreestanding -c kernel.c -o kernel.o
ld -T NUL -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o
objcopy -O binary -j .text kernel.tmp kernel.bin
type boot.bin kernel.bin > OS.bin
qemu-system-i386 OS.bin
答案 0 :(得分:3)
您没有初始化变量:
int offset = 0;
请注意,第一次使用offset是这样的:
offset += 2*col;
这意味着您应该将offset
初始化为0,或者您应该将该行更改为:
offset = 2*col;
答案 1 :(得分:0)
经过大量研究并在gcc
和ld
上乱了几个小时,我已经解决了我的问题。
我使用以下命令构建kernel.c
:
gcc -Wall -pedantic-errors -nostdlib kernel.c -o kernel.exe
ld -nostdlib -Ttext 0x1000 -o kernel.tmp kernel_entry.o kernel.exe
objcopy -O binary -j .text kernel.tmp kernel.bin
我不完全确定为什么这样做,以及我以前的尝试都没有,但是现在一切都正常。感谢我收到的所有帮助。