1

我正在尝试制作一个简单的程序。我使用 windows10x64、qemu(x86_64)、C 和 assembly-nasm。我没有使用 asm 的经验。我试图理解它。我使用了一个简单的 boot.asm、kernel_entry.asm 和 loader.c 文件。我基于一个totorial。

引导程序

;; memory offset where our kernel is located
KERNEL_OFFSET equ 0x1000

;; save the boot drive number
mov [BOOT_DRIVE], dl

;; update base and stack pointers
mov bp, 0x9000
mov sp, bp


init: 
  mov si, msg ; loads the address of "msg" into SI register 
  mov ah, 0x0e ; sets AH to 0xe (function teletype) 
print_char: 
  lodsb ; loads the current byte from SI into AL and increments the address in SI 
  cmp al, 0 ; compares AL to zero 
  je done ; if AL == 0, jump to "done" 
  int 0x10 ; print to screen using function 0xe of interrupt 0x10
  jmp print_char ; repeat with next byte

;; call routine that loads kernel into memory
call load_kernel_into_memory

;; switch to Protected Mode
call switch_to_pm
jmp $

;; routine reads kernel from disk into memory
load_kernel_into_memory:
    ;; store all register values
    pusha
    ;; set up parameters for disk_read routine
    mov bx, KERNEL_OFFSET
    mov dh, 15
    mov dl, [BOOT_DRIVE]
    call disk_read

    ;; restore register values and ret
    popa
    ret
;

[bits 32]

begin_pm:
    ;; Check if we can move from Protected Mode to Long Mode
    ;; If something went wrong (detect_lm shouldnt return at all)
    ;; we call execute_kernel in x32 Protected Mode
    call detect_lm
    call execute_kernel
    jmp $

[bits 64]

begin_lm:
    ;; In case, if detect_lm and switch_to_lm works fine, call kernel in x64 mode
    call execute_kernel
    jmp $
;
execute_kernel:
    call KERNEL_OFFSET
    jmp $
;
%include "disk/disk_read.asm";
%include "lm/detect_lm.asm";
%include "lm/switch_to_lm.asm";
%include "pm/gdt.asm"
%include "pm/switch_to_pm.asm"
%include "print/print_string.asm";
%include "print/print_nl.asm";


BOOT_DRIVE: db 0

done: 
  hlt ; stop execution 
  msg: db "PROGRAM STARTED", 0x0a; we need to explicitely put the zero byte here 
;

times 510-($-$$) db 0 ; fill the output file with zeroes until 510 bytes are full 
dw 0xaa55 ; magic number that tells the BIOS this is bootable

kernel_entry.asm

global _start
global kernel_main

[bits 32]
[extern _kernel_main] ; I use "_" otherwise it will not compile. _kernel_main comes from "c" file.
                      ;In there that is kernel_main

_start:
  call _kernel_main
  jmp $

加载器.c

#include <stdio.h>

extern void kernel_main() {
//printf("test");
for (int i = 0; i < 26; i++) {
        char c = 0x41 + i;

        asm(
            "mov %0, %%al;"
            "mov $0x0E, %%ah;"
            "int $0x10;"
            :
            : "r" (c)
        );
    }
}

我使用 nasm-WINx64version 和 GCC-TDM 在 WINx64 上编译。

我的步骤是:

nasm kernel_entry.asm -f elf32 -o loader_entry.o

gcc -O0 -g -ffreestanding -m32 -c C:/Users/_USR_/Desktop/nasm-2.15.05/loader.c -o C:/Users/_USR_/Desktop/nasm-2.15.05/loader.o

ld -o "C:/Users/_USR_/Desktop/nasm-2.15.05/loader.tmp" -m i386pe -Ttext 0x1000 -T NUL C:/Users/_USR_/Desktop/nasm-2.15.05/loader_entry.o C:/Users/_USR_/Desktop/nasm-2.15.05/loader.o

objcopy -O binary loader.tmp loader.bin

type boot.bin loader.bin > myboot.bin

最后,我在 QEMU 中运行它并获得“程序启动”输出,但没有“C”语言消息。此外,当我使用printf("...");时出现未声明的错误。. 还有一件事,如果我在LD命令中添加-lc参数,我会收到“找不到”消息。看起来它不识别“C”。否则我运行程序 aster 与“C”和 asm 链接。我没有得到任何错误,但我也没有得到“C”函数。

在此处输入图像描述我的输出是:

我在这里做错了什么?

4

1 回答 1

0

在我搜索了很多文档之后,我发现制作引导加载程序非常困难,同时也不难。是的,从头开始写所有东西对我来说是不可能的。评论是正确的,这可能在模拟器中工作,但会在真实硬件中引起很多问题。我无法处理这个。最后,我发现intel有EFI。Whis 现在是 UEFI。不过,我并不声称自己知道任何事情。但至少我在搜索之后学到了很多东西。首先,从 Windows 迁移到 linux 在头脑中很容易,但实际上很难做到。改变你的习惯是不可能的。首先我搜索了 linux 版本的 UEFI。有很多版本问题。然后我寻找WIN版本。希望找到vs2019兼容版本的uefi环境。项目在“gnu-efi”中没有源代码,并且在构建时抛出错误。我搜索了“gnu-efi-3.0.12” 根据信息并下载它。我将主文件夹中的文件放入“gnu-efi”。然后,回到 vs2019。构建它并且构建成功。我在调试模式 aa64 平台上运行它。我收到一条 Windows 消息,它会下载一次 qemu。它自己下载了,我得到了带有正确消息的 qemu 页面,例如:

Print(L"\n%H*** UEFI:HI I AM GOMI ***%N\n\n");
Print(L"%EPRESS ANY KEY AND EXIT.%N\n");

我还检查了调试文件夹并找到了“.efi”文件。我不确定我是否制作了一个真正的可启动 USB 设备并放置了可以工作的编译文件。

但是,既然那是 efi,我认为应该启动。

我发现有用的源页面

uefi 的好站点:https ://wiki.osdev.org/

vs2019 兼容项目:https ://github.com/pbatard/uefi-simple

结果: 在此处输入图像描述

于 2020-11-25T17:23:55.947 回答