- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将引导加载程序从 CHS 更改为 LBA,因此我替换了 int 13h 02h
与 int 13h 42h
.它在 QEMU 中正常工作,但是,我在使用 Bochs 和我的笔记本电脑运行它时遇到了麻烦。
我用 dd if=main.bin of=/dev/sdb bs=512
将引导加载程序写入 USB 闪存驱动器.笔记本电脑加载英特尔 UNDI 并给我以下错误:No bootable device - insert boot disk and press any key
.
所以我尝试用 Bochs 调试它并注意到 Bochs 将这个二进制文件识别为可引导的。但是,在 int 13h
之后没有加载任何内容执行。
然后我尝试从这个闪存驱动器加载我的旧电脑,它工作正常!它加载程序并正确执行它。 QEMU 给了我同样的结果。
这是引导加载程序代码:
org 0x7c00
bits 16
boot:
cli
; Overlap CS and DS
mov ax, cs
mov ds, ax
mov es, ax
; Setup 4K stack before this bootloader
mov ax, 0x07c0
mov ss, ax
mov sp, 4096
; Load next sectors
mov si, DAP
mov ah, 42h
; DL didn't changed
int 13h
; Start
jmp bootend
; Disk address packet
DAP:
db 10h, 0
dw %1 ; Number of sectors to be loaded
dd bootend
dq 1
; Fill the rest of bootsector with zeroes and end it
times 510 - ($ - boot) db 0
dw 0xAA55
bootend:
megs: 32
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xfffe0000
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
floppya: 1_44=main.bin, status=inserted
boot: a
panic: action=ask
log: bochsout.txt
mouse: enabled=0
keyboard: type=mf, serial_delay=200, paste_delay=100000
display_library: x, options="gui_debug"
最佳答案
LBA 磁盘访问可用性
并非所有 BIOS 都支持扩展的磁盘读写功能(尽管在现代硬件上它们几乎都支持)。并非所有 BIOS 都支持通过 Int 13h/AH=42h 对软盘进行扩展磁盘读取. BOCHS 也是如此。您可以通过 Int 13/AH=41h/BX=55AAh 测试驱动器上是否可以使用扩展磁盘功能。 .这会进行扩展磁盘安装检查。
如果您想使用扩展磁盘读取和 LBA 在 BOCHS 上测试您的代码,您将必须创建一个硬盘镜像并修改 BOCHS 以从它而不是软盘启动。 BOCHS 支持的最小硬盘镜像大小为 CHS = 1/16/63 即 512*16*63 = 516096 字节或 1008 个扇区,每个扇区 512 字节。
您可以修改您的 bochsrc.txt
成为:
megs: 32
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xfffe0000
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
boot: c
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="disk.img", mode=flat, cylinders=0, heads=0, spt=0, model="Generic 1234", biosdetect=auto, translation=auto
panic: action=ask
log: bochsout.txt
mouse: enabled=0
keyboard: type=mf, serial_delay=200, paste_delay=100000
display_library: x, options="gui_debug"
disk.img
的磁盘镜像.您可以使用以下命令创建它并将生成的扇区放入其中:
nasm -f bin main.asm -o main.bin
dd if=/dev/zero of=disk.img count=1008 bs=512
disk.img
的开头不截断文件:
dd if=main.bin of=disk.img conv=notrunc
org 0x7c00
所需要的),您应该将代码的开头修改为:
org 0x7c00
bits 16
boot:
cli
xor ax, ax ; Explicitly set DS and ES to 0
mov ds, ax
mov es, ax
bootend
之后添加了这个:
bootend:
; Print MDP to upper left of screen in white on light magenta
mov ax, 0xb800
mov es, ax
mov word [es:0x0000], 0x57<<8 | 'M'
mov word [es:0x0002], 0x57<<8 | 'D'
mov word [es:0x0004], 0x57<<8 | 'P'
; Infinite loop so we don't have the CPU wander memory
cli
endloop:
hlt
jmp endloop
%
的问题前符号
1
:
dw %1 ; Number of sectors to be loaded
dw 1 ; Number of sectors to be loaded
org 0x7c00
bits 16
boot:
jmp main
TIMES 3-($-$$) DB 0x90 ; Support 2 or 3 byte encoded JMPs before BPB.
; Dos 4.0 EBPB 1.44MB floppy
OEMname: db "mkfs.fat" ; mkfs.fat is what OEMname mkdosfs uses
bytesPerSector: dw 512
sectPerCluster: db 1
reservedSectors: dw 1
numFAT: db 2
numRootDirEntries: dw 224
numSectors: dw 2880
mediaType: db 0xf0
numFATsectors: dw 9
sectorsPerTrack: dw 18
numHeads: dw 2
numHiddenSectors: dd 0
numSectorsHuge: dd 0
driveNum: db 0
reserved: db 0
signature: db 0x29
volumeID: dd 0x2d7e5a1a
volumeLabel: db "NO NAME "
fileSysType: db "FAT12 "
main:
cli
xor ax, ax ; Explicitly set DS and ES to 0
mov ds, ax
mov es, ax
[rest of your code here]
file
命令可能能够转储它认为构成磁盘镜像中 MBR 的 BPB 数据。运行命令
file disk.img
你可能会得到这个输出:
disk.img: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", root entries 224, sectors 2880 (volumes <=32 MB) , sectors/FAT 9, sectors/track 18, serial number 0x2d7e5a1a, unlabeled, FAT (12 bit)
print_string
函数用于使用 BIOS TTY 输出和
print_hex_word
向控制台显示字符串。提供了以十六进制显示引导驱动器编号的功能。
org 0x7c00
bits 16
section .text
boot:
jmp main
TIMES 3-($-$$) DB 0x90 ; Support 2 or 3 byte encoded JMPs before BPB.
; Dos 4.0 EBPB 1.44MB floppy
OEMname: db "mkfs.fat" ; mkfs.fat is what OEMname mkdosfs uses
bytesPerSector: dw 512
sectPerCluster: db 1
reservedSectors: dw 1
numFAT: db 2
numRootDirEntries: dw 224
numSectors: dw 2880
mediaType: db 0xf0
numFATsectors: dw 9
sectorsPerTrack: dw 18
numHeads: dw 2
numHiddenSectors: dd 0
numSectorsHuge: dd 0
driveNum: db 0
reserved: db 0
signature: db 0x29
volumeID: dd 0x2d7e5a1a
volumeLabel: db "NO NAME "
fileSysType: db "FAT12 "
main:
cli
cld ; String instructions forward movement
xor ax, ax
mov ds, ax
mov es, ax
; Setup 4K stack before this bootloader
mov ss, ax
mov sp, 0x7c00
; Display a banner to know our bootloader is executing
mov si, msg_booting
call print_string
; Check that Int 13h Extensions are available
; http://www.ctyme.com/intr/rb-0706.htm
mov ah, 0x41 ; Int 13h/AH=41h: Check if extensions present
mov bx, 0x55aa
int 0x13
jc ext_drv_none ; CF set - no extensions available for drive
cmp bx, 0xaa55 ; Is BX 0xaa55?
jnz ext_none ; If not, int 13h extensions not supported
; by BIOS at all.
; Int 13h extensions supported by BIOS and drive at this point
; Load next sectors
mov si, DAP
mov ah, 42h
; DL didn't changed
int 13h
; Start
jmp bootend
; Error: BIOS doesn't support Int 13h extensions
ext_none:
mov si, err_no_extensions
call print_string
jmp error_end
; Error: BIOS supports Int 13h extensions but not for drive in DL
ext_drv_none:
mov si, err_no_drv_ext_support
call print_string
; Print the boot drive number in hex
xor dh, dh ; Zero extended drive number to all of DX
push word 0x00 ; Attribute and page number to write to
push dx ; The value to write as hex
call print_hex_word
error_end:
cli
.loop:
hlt
jmp .loop
; Print 16 bit value passed on stack as first parameter
; in hexadecimal. Use page number and foreground color
; passed in second parameter. This routine will work on 8086+
; processors. This code takes advantage of packed BCD to
; determine the ASCII values to print. This code could have
; used compare and branch to do the same or a translation table.
print_hex_word:
push bp
mov bp, sp ; BP=SP, on 8086 can't use sp in memory operand
push dx ; Save all registers we clobber
push cx
push bx
push ax
mov cx, 0x0404 ; CH = number of nibbles to process = 4 (4*4=16 bits)
; CL = Number of bits to rotate each iteration = 4 (a nibble)
mov dx, [bp+4] ; DX = word parameter on stack at [bp+4] to print
mov bx, [bp+6] ; BX = page / foreground attr is at [bp+6]
.loop:
rol dx, cl ; Roll 4 bits left. Lower nibble is value to print
mov ax, 0x0e0f ; AH=0E (BIOS tty print),AL=mask to get lower nibble
and al, dl ; AL=copy of lower nibble
add al, 0x90 ; Work as if we are packed BCD
daa ; Decimal adjust after add.
; If nibble in AL was between 0 and 9, then CF=0 and
; AL=0x90 to 0x99
; If nibble in AL was between A and F, then CF=1 and
; AL=0x00 to 0x05
adc al, 0x40 ; AL=0xD0 to 0xD9
; or AL=0x41 to 0x46
daa ; AL=0x30 to 0x39 (ASCII '0' to '9')
; or AL=0x41 to 0x46 (ASCII 'A' to 'F')
int 0x10 ; Print ASCII character in AL
dec ch
jnz .loop ; Go back if more nibbles to process
pop ax ; Restore registers
pop bx
pop cx
pop dx
pop bp
ret
; Print string pointed to by DS:SI using
; BIOS TTY output via int 10h/AH=0eh
print_string:
push ax
push si
mov ah, 0Eh ; int 10h 'print char' function
.repeat:
lodsb ; Get character from string
test al, al
je .done ; If char is zero, end of string
int 10h ; Otherwise, print it
jmp .repeat
.done:
pop si
pop ax
ret
; Disk address packet
DAP:
db 10h, 0
dw 1 ; Number of sectors to be loaded
dd bootend
dq 1
msg_booting: db "Booting... ", 0x00
err_no_extensions: db "Int 13h extensions not supported by BIOS", 0x00
err_no_drv_ext_support: db "Int 13h Extensions not supported on drive 0x", 0x00
; Fill the rest of bootsector with zeroes and end it
times 510 - ($ - boot) db 0
dw 0xAA55
bootend:
mov ax, 0xb800
mov es, ax
mov word [es:0x0000], 0x57<<8 | 'M'
mov word [es:0x0002], 0x57<<8 | 'D'
mov word [es:0x0004], 0x57<<8 | 'P'
cli
hlt
关于x86 - int 13h 42h 在 Bochs 中不加载任何东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43786251/
这个fn是吗: function isplainobj ( obj ) { return Object.prototype.toString.call( obj ) === "[object
我尝试创建一个我没有经验的小 bash 脚本。我尝试做类似的事情: #!/bin/bash statut="na" if [ $proc = 0 ]; then statut = "close
我想重写 HighLine 的几个方法来自定义我的控制台,目前我的代码如下所示: cmd = ask("#{@prompt_label} #{@prompt_separator} ",
鉴于下面的 HTML,我尝试使用 jQuery 来匹配所有具有类“foo”的跨度的列表项,并且该跨度应包含文本“relevant”。 Some text relevant Some more
我拥有一个 5 美元 20GB SSD Digital Ocean Droplet,它几乎用完了 Docker 镜像和容器的空间。 有没有办法购买一个卷,将其连接到服务器并安全地将所有 Docker
我有这样的表: id name number result stuff stuff stuff stuff 我只想将 class = "red" 添加到
我需要计算两点之间的距离,但不是以常规方式。我需要知道“东西距离”+“南北距离”。我想这比常规的“乌鸦飞翔”计算更简单,但我仍然不知道如何做到这一点。 我想使用 MySQL 查询来执行此操作,并且最好
#include #include #include typedef struct dict_pair { void *key; void *value; struct dict_p
为什么当我尝试通过 将 char[] word 写入控制台时会发生这种奇怪的事情 Console.WriteLine(word); 我得到了一个正确的结果,但是当我写的时候 Console.Write
一个简单的例子: class C{} class B{ @Inject C c; void doSomething(){ System.out.println(c);
我想做某事,但不确定如何描述它。我有这门课 public class Company { private List _persons; private Person GetPersonByNa
我正在尝试实现我自己的 qDebug()样式调试输出流,这基本上是我目前所拥有的: struct debug { #if defined(DEBUG) template std::os
所以我正在为我的应用程序编写一个搜索功能,代码如下: - (void) selectObject: (NSString *)notes{ [axKnotes removeAllObjects]
我想在 Rust 中匹配一种复杂的继承式东西: struct Entity { pub kind: EntityKind, } pub enum EntityKind { Player
我是 SQL 新手。这没有返回任何结果...... SELECT media.id as mediaid, media.title as mediatitle, media.description
在微型 SDCard 上写入 Android things 图像并将该卡插入 Raspberry Pi 3 Model B 并打开电源,启动时显示“Auto config Please wait”然后
这是一个常见的但是文本出现在框的右侧,不是极右但几乎是这样 h3: ................................................ .................
#include #include #include #include #include int main(int argc, string argv[]) { if(argc >
所以我试图让一些东西相互堆叠。首先,查看工作链接会有所帮助,您会看到问题所在: http://brownbox.net.au/clients/matchlessphotography/ 现在我需要使用
我想在禁用 javascript 时在我的网站顶部显示一条消息(就像在 SO 上一样),但在谷歌浏览器上不起作用 最佳答案 看起来是这样。 您可以使用 javascript 隐藏“noscript”消
我是一名优秀的程序员,十分优秀!