最好是评论和一些相关的docmentation和Makefile.
为了清楚起见,这是由Bios加载的机器代码少于512字节(512字节 - 分区表),并负责链接到启动分区中的辅助引导加载程序.
编辑:David和Bdonlan的答案看起来都很有希望.最小的Dos链接转到MBR的Debian源包,但注释的Windows 2000/XP MBR看起来有更详细的注释.
我正在努力在D中制作自己的引导加载程序和内核,而且我遇到了一个绊脚石.
kmain(),我的入口点核心.能够加载PE文件是内核工作的一部分.那么我如何首先将内核本身加载到内存中,以便它可以实际正确执行?
我无法从引导扇区执行此操作,因为(1)它不适合512字节,(2)在汇编时很痛苦.显然,我也无法在内核中做到这一点.那我该怎么做呢?
我想知道引导加载程序在哪些硬件上运行?它是在 RAM 上运行,还是在主板的处理器上运行,如果它不在处理器上运行,那么在加载操作系统时处理器的用途是什么,例如将操作系统的内核加载到处理器中(如果它是'就像那样做)和类似的事情。任何对论文、教程等的引用也将受到赞赏
您的信仰
我在使 PIC32MX795F512L 的引导加载程序正常工作时遇到问题。
我基于 microchip 网站上的示例代码。
这是我应该写入内存的代码部分,到目前为止我已经验证了引导加载程序(解析十六进制文件很好,数据到达这一点但没有写入内存):
#define NVMOP_WORD_PGM 0x4001
// Write the data into flash.
Result = NVMemWriteWord(ProgAddress, WrData);
// Assert on error. This must be caught during debug phase.
if(Result != 0)
{
ASSERT(Result==0);
}
UINT NVMemWriteWord(void* address, UINT data)
{
UINT res;
NVMADDR = KVA_TO_PA((unsigned int)address);
// Load data into NVMDATA register
NVMDATA = data;
// Unlock and Write Word
res = NVMemOperation(NVMOP_WORD_PGM);
return res;
}
UINT __attribute__((nomips16)) NVMemOperation(UINT nvmop)
{
int int_status;
int susp;
// Disable …Run Code Online (Sandbox Code Playgroud) 我最近在我的 SSD(30GB 分区)上安装了 Linux Mint(KDE Plasma),然后在剩余存储上安装了 Windows 10。但是,当我尝试在 Linux Mint 中启动时,我的计算机会自动启动 Windows 10,而不显示用于选择操作系统的启动选项。现在,如何在我的 SSD 的主引导记录 (MBR) 上安装 GRUB 以引导两个操作系统。
我正在开发一个基本的引导加载程序,它通过 BIOSINT 13h AH=02h中断将辅助引导加载程序读入内存。我已经在模拟器(Virtualbox、Qemu 和 Bochs)中运行了它。
随后,我在我的引导加载程序中添加了一个 BPB(BIOS 参数块),制作了一个可引导的 USB,并在我的真机上使用 USB Floppy Emulation(我在真机 BIOS 的配置屏幕中设置)进行了测试。它就像一个魅力。
在我自己的机器上测试引导加载程序后,我在另一台较新的机器上测试了它。这台新计算机的 BIOS 配置中没有软盘仿真选项,因此无法从 USB 驱动器启动。因此,在这个osdev wikipage 之后,我在 MBR 的末尾添加了一个分区表,以便较新的机器可以从 USB 启动。
使用添加的分区表代码,引导加载程序无法将辅助引导加载程序加载到内存中,并且 BIOSINT 13h失败。我不知道为什么会发生这种情况,因为我没有更改任何实际的引导加载程序代码。我刚刚添加了 64 位 MBR 分区表,将数据读入内存立即失败。
bits 16
org 0x7C00
jmp start
nop
;------------------------------------------;
; Standard BIOS Parameter Block, "BPB". ;
;------------------------------------------;
bpbOEM db 'MSDOS5.0'
bpbSectSize dw 512
bpbClustSize db 1
bpbReservedSe dw 1
bpbFats db 2
bpbRootSize dw 224
bpbTotalSect dw 2880 …Run Code Online (Sandbox Code Playgroud) 在我努力创建一个简单的独立程序的过程中,我在第一个扇区中编写了一个简单的引导加载程序。它的目的是将程序加载到内存中。为此,我使用了 AH=2 的 INT 13h。代码是:
disk_load:
push dx ; Store DX on stack so later we can recall how many sectors were requested to be read,
; even if it is altered in the meantime.
mov ah, 0x02 ; BIOS read sector.
mov al, dh ; Read DH sectors.
mov ch, 0x00 ; Select cylinder 0.
mov dh, 0x00 ; Select head 0.
mov cl, 0x02 ; Start reading from second sector (i.e. after the boot sector).
int 0x13 …Run Code Online (Sandbox Code Playgroud) 当从引导加载程序跳转到应用程序时,我们通常将堆栈指针更新为应用程序堆栈指针,然后将程序计数器更新为应用程序的 Reset_Handler。
void jump_to_application(void)
{
/* Function pointer to the address of the user application. */
fnc_ptr_for_app jump_to_app;
jump_to_app = (fnc_ptr_for_app)(*(volatile uint32_t*) (FLASH_APP_START_ADDRESS+4u));
__CRC_CLK_DISABLE();
HAL_DeInit();
/* Change the main stack pointer. */
__set_MSP(*(volatile uint32_t*)FLASH_APP_START_ADDRESS);
jump_to_app();
}
Run Code Online (Sandbox Code Playgroud)
Reset_Handler的第一行代码如下,将栈指针初始化为自己的栈指针值
Reset_Handler:
ldr sp, =_estack /* Atollic update: set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
Run Code Online (Sandbox Code Playgroud)
但仍然建议使用应用程序的堆栈指针更新堆栈指针。
为什么需要,不更新就跳转有什么副作用
我正在尝试编写一个实模式引导加载程序,但我目前在尝试启用 A20 线时遇到了问题。到目前为止,这是我的代码,我正在使用 NASM 进行组装:
[bits 16]
[global _start]
jmp _start
bios_print:
lodsb
test al, al
jz bios_print_done
mov ah, 0x0E
mov bh, 0
int 0x10
jmp bios_print
bios_print_done:
ret
a20_is_enabled:
push ds
push si
push es
push di
xor ax, ax
mov ds, ax
mov si, BOOT_ID_OFFS
mov ax, BOOT_ID_OFFS_PLUS_1MB_SEGM
mov es, ax
mov di, BOOT_ID_OFFS_PLUS_1MB_OFFS
cmp word [es:di], BOOT_ID
mov ax, 1
jne a20_is_enabled_done
mov ax, word [ds:si]
xor ax, ax
mov [ds:si], ax
cmp word [es:di], BOOT_ID …Run Code Online (Sandbox Code Playgroud) 我正在制作一个简单的引导程序。我想在屏幕上打印一些非拉丁文本,但无法正确打印字符“ü”。我怎样才能让我的操作系统打印字符ü?我已经搜索过它,但我找不到任何关于它的信息。
主程序
[org 0x7c00]
call clear
mov bx, SELAM
call print
call print_nl
mov bx, NABER
call print
jmp $
%include "print.asm"
SELAM:
db 'Selamun Aleyküm.', 0
NABER:
db 'Nabün?', 0
times 510 - ($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)
打印.asm
print:
pusha
start:
mov al, [bx]
cmp al, 0
je done
mov ah, 0x0e
int 0x10
add bx, 1
jmp start
done:
popa
ret
print_nl:
pusha
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int …Run Code Online (Sandbox Code Playgroud)