我在哪里可以找到如何直接从程序集寻址硬盘驱动器(假设我在实模式或环 0 下运行)。例如,假设我想将扇区 100-200 中的数据加载到 RAM 中的某个位置。我将如何寻址特定的硬盘驱动器以及如何告诉驱动器我想要哪些扇区?
我想知道为什么即使我们有 4 核/8 核,BIOS 也是单线程的。最新的 UEFI 技术允许使用 GUI 实用程序。不实施多线程 BIOS 是否有任何具体原因。
简单的问题,我正在阅读有关 PCI 的 OSDev Wiki 页面,它说了以下内容 -
“基地址寄存器(或 BAR)可用于保存设备使用的内存地址,或端口地址的偏移量。通常,内存地址 BAR 需要位于物理 RAM 中,而 I/O 空间 BAR 可以驻留在任何内存地址(甚至超出物理记忆)。”
我不明白哪里说内存地址 BAR 需要位于物理 RAM 中?MMIO 的全部意义在于,当它被分配一个内存地址时,它将被路由到设备而不是物理 RAM。它需要位于物理 RAM 中是什么意思?
难道它不只是 3GB - 4GB 地址空间之间的地址,无论安装了多少物理 RAM?
这是 OSDev 网站上的错误还是我误解了?
谢谢。
在我的引导程序的第二阶段,我试图将一些虚拟软盘上的扇区加载到bochs的内存中,但是在调用时int 0x13,例程就不会返回.
我相信我的第二阶段的相关代码是:
bootsys_start:
mov %cs, %ax
mov %ax, %ds
/*
* Remap IRQs. Interrupts have been disabled in the
* bootloader already.
*/
mov i8259A_ICW1($i8259A_IC4), %al
out %al, i8259A_ICW1_ADDR($i8259A_MASTER)
out %al, i8259A_ICW1_ADDR($i8259A_SLAVE)
mov i8259A_ICW2($USER_INT_START), %al
out %al, i8259A_ICW2_ADDR($i8259A_MASTER)
mov i8259A_ICW2($USER_INT_START + 8), %al
out %al, i8259A_ICW2_ADDR($i8259A_SLAVE)
mov i8259A_ICW3($0x4), %al
out %al, i8259A_ICW3_ADDR($i8259A_MASTER)
mov i8259A_ICW3($0x2), %al
out %al, i8259A_ICW3_ADDR($i8259A_SLAVE)
mov i8259A_ICW4($i8259A_uPM & i8259A_x86), %al
out %al, i8259A_ICW4_ADDR($i8259A_MASTER)
out %al, i8259A_ICW4_ADDR($i8259A_SLAVE)
call mm_detect
/* Load the kernel …Run Code Online (Sandbox Code Playgroud) 我的目标是使用 Int 16 指令能够使用箭头键在程序中上下移动,直到我的用户决定按退出键。我是否在循环中使用以下代码读取多个按键并在末尾添加终止条件,或者是否缺少某些内容?
Mov ah,00
int 16
Run Code Online (Sandbox Code Playgroud) 我正在开发一个基本的引导加载程序,它通过 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) 我有一个简单的程序,它将一些以空结尾的字符串移动到寄存器bx:
[org 0x7c00] ; Tells the assembler where the code will be loaded
mov ah, 0x0e
mov bx, HELLO_MSG ; Moves string inside of HELLO_MSG to bx
call print_string ; Calls the print_string function inside of ./print_string.asm
mov bx, GOODBYE_MSG ; Moves string inside of GOODBYE_MSG to bx
call print_string
jmp $ ; Hangs
%include "print_string.asm"
HELLO_MSG:
db 'Hello, World!', 0
GOODBYE_MSG:
db 'Goodbye!', 0
times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)
和一个print_string内部函数./print_string.asm:
print_string:
mov …Run Code Online (Sandbox Code Playgroud) 我是一名学习汇编语言(NASM)的学生,我需要一些关于中断“功能”或 int 如何知道要“运行”的寄存器的澄清。我发现一个声明
mov ah, 0x0e
mov al, "A"
int 0x10
Run Code Online (Sandbox Code Playgroud)
打印A并且0x0eand A( ) 像( ) 一样0x41形成寄存器,但是 int “函数”如何知道寄存器应该“运行”而不是or ?仅仅是因为和 的语句位于 int 之上吗?ax0x0e, 0x41axbxcxahal0x10
中断ah=0Eh int 10h在屏幕上显示一个字符,它有几个参数,其中包括BH,本来应该表示页码,但是经过几次测试我发现BH完全没有用。即使我更改页码,无论如何,字符仍将显示在活动页面上。
“日期为 1981/4/24 和 1981/10/19 的 IBM PC ROM 要求 BH 与当前活动页面相同”
互联网上的一个页面这样写道: https: //www.ic.unicamp.br/~celio/mc404-2004/service_interrupts#int10h_0Eh
此功能在屏幕上显示一个字符,根据需要推进光标并滚动屏幕。打印始终在当前活动页面上进行。
我必须信任哪个来源,我使用没有操作系统的虚拟盒子,并且我使用引导加载程序。
我明确表示我不理解此信息
1981/4/24 和 1981/10/19 的 IBM PC ROM 要求 BH 与当前活动页面相同
知道我使用 Virtual Box,我不认为 Virtual Box 使用 1981 年 IMG PC 上的 ROM?