【发布时间】:2016-11-22 11:41:41
【问题描述】:
现在当我选择 Custom OS 时,当我从 GRUB 的菜单中执行我的操作系统时,我得到一个紫色背景:
error: secure boot forbids loading module from (hdo, gpt7)/boot/grub/x86_64-efi/multiboot.mod
error: You need to load your kernel first
Press any key to continue . . .
.. 我不一定明白为什么会这样。让我给你看看我的文件:
loader.S:
#Global MultiBoot Kernel Recongnzation
.set MAGIC, 0x1BADB002
.set FLAGS , (1<<0 | 1<<1)
.set CHECKSUM, -(MAGIC + FLAGS)
#Putting in object file
.section .multiboot
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .text
.extern kernelMain
.globl loader
loader:
mov $kernel_stack , %esp
push %eax
push %ebx
call kernelMain
_eof:
cli
hlt
jmp _eof
.section .bss
.space 2*1024*1024 #2 MiB
kernel_stack:
生成文件:
GPPARAMS = -m32 -Iinclude -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wno-write-strings
ASPARAMS = --32
LDPARAMS = -melf_i386
objects = kernel.o loader.o
all:
g++ -m32 -Iinclude -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wno-write-strings -o kernel.o -c kernel.cc
as $(ASPARAMS) -o loader.o loader.S
mykernel.bin : linker.ld $(objects)
ld $(LDPARAMS) -T $< -o $@ $(objects)
install: mykernel.bin
sudo cp $< /boot/mykernel.bin
clean:
rm $(objects)
kernel.cc:
int strlen(char* str)
{
int l=0;
while(str[l]!='\0')l++;
return l;
}
void printf(char *str)
{
unsigned short* ViedoMemory = (unsigned short*)0xb8000;
for(int i=0; str[i]!='\0'; ++i)
ViedoMemory[i]= (ViedoMemory[i] & 0xFF00)|str[i];
}
extern "C" void kernelMain(void* multiboot_structure, unsigned int magicnumber)
{
printf("Hello World");
while(1);
}
linker.ld:
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)
SECTIONS
{
. = 0x0100000;
.text :
{
*(.multiboot)
*(.text*)
*(.rodata)
}
.data :
{
start_ctors = .;
KEEP(*( .init_array ));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
end_ctors = .;
*(.data)
}
.bss :
{
*(.bss)
}
/DISCARD/ :
{
*(.fini_array*)
*(.comment)
}
}
现在我如何加载它是首先由makefile完成:
make
make mykernel.bin
make install
然后我当然在/boot/grub/grub.cfg 中添加了这个:
### BEGIN MYKERNEL
menuentry 'Operating System Tut'{
multiboot /boot/mykernel.bin
boot
}
### END MYKERNEL ###
然后当我执行sudo reboot 并从下拉列表中选择Operating System Tut 时,它会出现我之前描述的错误:
error: secure boot forbids loading module from (hdo, gpt7)/boot/grub/x86_64-efi/multiboot.mod
error: You need to load your kernel first
Press any key to continue . . .
再一次,我不明白为什么内核没有首先加载......我们将不胜感激。
【问题讨论】:
-
它没有卡在启动中。查看屏幕的左上角。它说
Hello World。我认为您的问题与GRUB配置更相关,但也可能与您的硬件交互,但确实很难说。 -
这些问题超出了所提问题的范围。你不妨看看OSDev Wiki。您可以编写一个循环来简单地在当前屏幕的所有单元格中放置一个具有适当属性的空格。在 80x25 的文本显示器上,有 2000 个单元,每个单元 2 个字节。至于写入您指定 row 和 col 的另一个位置
ViedoMemory[row*80+col+i]= (ViedoMemory[row*80+col+i] & 0xFF00)|str[i];。 80 是列数。如果您处于具有不同列数的文本模式,则必须更改它 -
我不是
-Wno-write-strings的粉丝。我建议不要这样做,只需修改您的函数strlen和printf以使用const char *str而不是char *str -
你问了关于如何确定行数的问题,我回答了这个问题,我回答了关于必须进行地址计算才能将事物放在一行/列的问题。那个视频很简单。你现在想做的事情比那个视频复杂得多(是的,我之前看过)。与几乎所有其他方法相比,使用视频模式工作非常容易当您处于保护模式时,事情并不容易。
-
我尝试在 QEmu 上运行该内核,但没有成功...视频 2 展示了如何在 VirtualBox 中运行它 :-)
标签: c++ x86 gnu-assembler osdev grub