如何将第9个扇区复制到第1个扇区? [英] How to copy 9th sector to 1st sector?

查看:131
本文介绍了如何将第9个扇区复制到第1个扇区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建自定义mbr,例如 mbr-lovenote ,但我无法创建将第9个扇区 -(位于原始mbr) 复制到第1个扇区的代码,我已经尝试从

I'm creating custom mbr, something like mbr-lovenote and i can't create code that will copy 9th sector - (there is located original mbr) to 1st sector, i already tried take some code from mbr-lovenote and modify it, but i find out that code only load sector in memory and jump to it, but i have to copy it. I write my code, the code will be loaded from fist sector on PhysicalDrive0, but i don't know why it doesn't works.

;---create buffer
buffer db 512

;---read sector - 9th
mov ax, buffer              ;ES: BX must point to the buffer
mov es, ax                  ;
mov bx, buffer              ;
mov dl,0                    ;drive number
mov dh,0                    ;head number
mov ch,0                    ;track number
mov cl,9                    ;sector number 
mov al,1                    ;number of sectors to read
mov ah,2                    ;read function number
int 13h

;---write sector - 1th
mov ax, buffer              ;ES: BX must point to the buffer
mov es, ax                  ;
mov bx, buffer              ;
mov dl,0                    ;drive number
mov dh,0                    ;head number
mov ch,0                    ;track number
mov cl,1                    ;sector number
mov al,1                    ;number of sectors to write
mov ah,3                    ;write function number
int 13h

;---fake signature
times 510 - ($-$$) db 0
dw        0xaa55

推荐答案

您没有提供最小的完整示例,并且有迹象表明您可能不知道真实模式

You don't provide a minimal complete example and there are indications you may not know how real mode 20-bit segment:offset addressing works. Every memory location in real mode is made up of a 16-bit segment and a 16-bit offset. Both are combined to compute a 20-bit physical address with the formula: PhysicalAddress = (Segment<<4)+Offset. Shifting left by 4 is the same as multiplying by 16.

引导加载程序已加载到内存中的物理地址0x07c00.您必须选择一个ORG并在引导程序中设置段,以便它们引用物理地址0x07c00.一个以上的20位segment:offset地址可以指向相同的物理地址.引导加载程序的2个常见选项是使用ORG 0x7c00,其段设置为0x0000((0x0000 << 4)+ 0x7c00 = 0x07c00),或者使用ORG 0x0000和0x07c0的段((0x07c0< <4)+ 0x0000 = 0x07c00)).

A bootloader is loaded at physical address 0x07c00 in memory. You have to choose an ORG and set the segments in your bootloader so that they reference physical address 0x07c00. More than one 20-bit segment:offset address can point to the same physical address. The 2 common ones for bootloaders are using an ORG 0x7c00 with segments set to 0x0000 ((0x0000<<4)+0x7c00=0x07c00), or usingORG 0x0000 and a segment of 0x07c0 ((0x07c0<<4)+0x0000=0x07c00)).

Stackoverflow答案中,我有一些常规的引导程序提示.如果您可能正在编写引导加载程序以在FDD模式下在USB驱动器上运行,则还需要阅读有关以下内容的 Stackoverflow答案使用代表软盘的BIOS数据区(BDA).

I have some general bootloader tips in this Stackoverflow answer. If you are potentially writing your bootloader to run on a USB drive in FDD mode you will also want to read my Stackoverflow answer about using a BIOS Data Area (BDA) representing a floppy.

此示例是一个简单的引导加载程序,其基于您的代码的BDA将扇区9复制到扇区1(MBR),然后使用 int 0x19 .该代码还在引导加载程序之后的内存(@ 0x0000:0x7e00)中使用该内存进行临时存储,以进行扇区复制.我还提供了一个放置在扇区9中的测试引导程序,该引导程序在运行时会显示一条消息.

This example is a simple bootloader with a BDA based on your code to copy sector 9 onto sector 1 (MBR) and then reboots with int 0x19. The code also uses the memory right after the bootloader in memory (@ 0x0000:0x7e00) for temporary storage to do the sector copy. I also provide a test bootloader that is placed into sector 9 that displays a message when it is running.

boot.asm :

org 0x7c00
bits 16

boot:
    jmp main
    TIMES 3-($-$$) DB 0x90   ; Support 2 or 3 byte encoded JMPs before BPB.

    ; Use a BIOS Parameter Block if you intend to use this on USB in FDD mode

    ; 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:
    ; BIOS passes our boot drive number in DL

    ; Setup segments
    xor ax, ax                  ; AX=0
    mov ds, ax                  ; DS=ES=0 because we use an org of 0x7c00
                                ;    segment<<4+offset = 0x0000<<4+0x7c00 = 0x07c00
    mov es, ax
    mov ss, ax
    mov sp, 0x7c00              ; SS:SP= 0x0000:0x7c00 stack just below bootloader

    ;---read sector - 9th
    mov bx, buffer              ; ES: BX point to buffer (ES set to zero previously)
;    mov dl,0                   ; use boot drive passed to bootloader by BIOS in DL
    mov dh,0                    ; head number
    mov ch,0                    ; track number
    mov cl,9                    ; sector number
    mov al,1                    ; number of sectors to read
    mov ah,2                    ; read function number
    int 13h

    ;---write sector - 1th

; The following commented lines aren't required. Int AH=13h/AH=2 only
; destroys AX and the following registers remain unchanged from the
; read disk BIOS call

;    mov bx, buffer              ; ES: BX must point to the buffer
;    mov dl,0                    ; use boot drive passed to bootloader by BIOS in DL
;    mov dh,0                    ; head number
;    mov ch,0                    ; track number

    mov cl,1                    ; sector number
    mov al,1                    ; number of sectors to write
    mov ah,3                    ; write function number
    int 13h


    mov si, message
    call print_string           ; Print a banner to the console

    int 19h                     ; Warm reboot, should run bootloader that was in sector 9

; Function: print_string
;           Display a string to the console on display page 0
;
; Inputs:   SI = Offset of address to print
; Clobbers: AX, BX, SI

print_string:               ; Routine: output string in SI to screen
    mov ah, 0eh             ; BIOS tty Print
    xor bx, bx              ; Set display page to 0 (BL)
    jmp .getch
.repeat:
    int 10h                 ; print character
.getch:
    lodsb                   ; Get character from string
    test al,al              ; Have we reached end of string?
    jnz .repeat             ;     if not process next character
.end:
    ret

message: db "Running original bootloader...", 0x0a, 0x0d, 0

times 510 - ($-$$) db 0
dw        0xaa55               ; Boot signature

; This buffer is right after the bootloader and will be at offset 0x7e00.
; 0x0000:0x7e00 is the memory location starting right after the 512 byte
; bootloader loaded into memory by the BIOS
buffer:

sector9.asm :

org 0x7c00
bits 16

boot:
    jmp main
    TIMES 3-($-$$) DB 0x90   ; Support 2 or 3 byte encoded JMPs before BPB.

    ; Use a BIOS Parameter Block if you intend to use this on USB in FDD mode

    ; 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:
    ; Setup segments
    xor ax, ax                  ; AX=0
    mov ds, ax                  ; DS=ES=0 because we use an org of 0x7c00
                                ;    segment<<4+offset = 0x0000<<4+0x7c00 = 0x07c00
    mov ss, ax
    mov sp, 0x7c00              ; SS:SP= 0x0000:0x7c00 stack just below bootloader

    mov si, message
    call print_string           ; Print a banner to the console

    cli
.endloop:                       ; Infinite loop to end bootloader
    hlt
    jmp .endloop

; Function: print_string
;           Display a string to the console on display page 0
;
; Inputs:   SI = Offset of address to print
; Clobbers: AX, BX, SI

print_string:               ; Routine: output string in SI to screen
    mov ah, 0eh             ; BIOS tty Print
    xor bx, bx              ; Set display page to 0 (BL)
    jmp .getch
.repeat:
    int 10h                 ; print character
.getch:
    lodsb                   ; Get character from string
    test al,al              ; Have we reached end of string?
    jnz .repeat             ;     if not process next character
.end:
    ret

message: db "Running sector 9 bootloader...", 0x0a, 0x0d, 0

times 510 - ($-$$) db 0
dw        0xaa55               ; boot signature

要构建1.44MiB软盘映像并将主引导程序放置在扇区1中,将辅助引导程序放置在扇区9中,如果您在具有dd命令的系统上运行,则可以使用以下命令:

To build a 1.44MiB floppy image and place the primary bootloader at sector 1 and the secondary bootloader in sector 9 you could use commands like this if you are running on a system that has the dd command:

nasm -f bin boot.asm -o boot.bin
nasm -f bin sector9.asm -o sector9.bin

dd if=/dev/zero of=disk.img bs=1024 count=1440
dd if=boot.bin of=disk.img conv=notrunc seek=0
dd if=sector9.bin of=disk.img conv=notrunc seek=8

您可以使用QEMU来运行以下代码:

You can use QEMU to run this code using:

qemu-system-i386 -fda disk.img

如果您在仿真器或虚拟机(例如QEMU)中运行此命令,则应显示以下内容:

If you run this in an emulator or virtual machine like QEMU it should display something like:

发生的事情是,扇区9被boot.bin中的原始引导程序复制到了扇区1,然后计算机重新启动了.重新引导后,它在sector9.bin中运行了引导程序代码,该代码已从扇区9复制到MBR.它应该打印:

What has happened is that sector 9 was copied to sector 1 by the original bootloader in boot.bin and then the machine rebooted. Upon reboot it ran the bootloader code in sector9.bin that was copied from sector 9 to the MBR. It should print:

正在运行原始的引导程序...

Running original bootloader...

然后应打印:

正在运行扇区9引导加载程序...

Running sector 9 bootloader...


注意:您需要确保磁盘不受写保护,并且所用的任何BIOS均未使用 MBR安全性. MBR安全性防止BIOS调用覆盖启动驱动器上的MBR(扇区1).


Note: you will need to make sure that your disk is not write protected and that any BIOS you are using isn't using MBR security. MBR security prevent BIOS calls from overwriting the MBR (sector 1) on the boot drive.

这篇关于如何将第9个扇区复制到第1个扇区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆