2011-05-12 4 views
2

저는 교육용 부트 로더를 작성 중이므로 잘 종료됩니다. 그러나 실제 시스템에서 부팅을 시도 할 때 디스크 읽기 코드가 일부 섹터를로드하지 못합니다. 오류 코드가 제공되지 않았거나 CF가 설정되지 않았습니다. 또한 1을 읽었 음을 의미하는 1을 반환합니다 (올바른 값이어야 함). 하지만로드 된 섹터로 이동하려고하면 아무 것도하지 않습니다. 첫 번째 단계는 A를 인쇄하고 두 번째 단계는 F로 덮어 씁니다. 실제 하드웨어로 부팅 할 때 A 만 표시됩니다.bios int 0x13이 오류없이 실패합니다.

LOADOFF equ 0x7C00 
BUFFER equ 0x600 

[bits 16] 
[org 0x7c00] 

jmp _start 
nop 
    bootdisk db 0 

_start: ; entry point 
    jmp 0x0:.flush 
.flush: 
    xor ax, ax 
    mov ds, ax 
    mov es, ax 
    cli 
    mov ss, ax 
    mov sp, LOADOFF  ; stack setup 
    sti 

    mov [bootdisk], dl ; boot drive number given by the bios in dl 

    mov si, migrate ; move the code below to the buffer 
    mov di, BUFFER 
    mov cx, 256 
    cld 
    rep 
    movsw 

    jmp 0x0:BUFFER ;get my ass in the buffer 
migrate: 

.reset: 
    xor ax, ax  ; reset the disk 
    mov dl, [bootdisk] 
    int 0x13 
    jc .reset 

.read: 
    mov ah, 0x2 
    mov al, 1 ; read 1 sector 
    xor cx, cx ; cylinder 0 
    mov cl, 2 ; sector 2 
    mov dl, [bootdisk] 
    xor dh, dh ; head 0 


    ; setup buffer 
    xor bx, bx 
    mov es, bx 
    mov bx, 0x7c00 ; chain load it 
    int 0x13 
    jc .read 

    test ah, ah 
    jnz .reset 

    cmp al, 0x1 ; is there one and only one sector loaded? 
    jne .reset 

    mov ax, 0xb800 
    mov es, ax 
    xor di, di 
    mov al, 65 ; capital A 
    mov ah, 0xc 
    stosw 

; mov ax, 0x7c0 
; mov es, ax 
; xor di, di 
; 
; mov [es:di], byte 191   ; this code proves that my far jump does its work 
; mov [es:di+1], byte 160  ; if you would like to test, comment it out. 
; mov [es:di+2], byte 128 
; mov [es:di+3], byte 184 
; mov [es:di+4], byte 0 
; mov [es:di+5], byte 176 
; mov [es:di+6], byte 142 
; mov [es:di+7], byte 192 
; mov [es:di+8], byte 184 
; mov [es:di+9], byte 88 
; mov [es:di+10], byte 14 
; mov [es:di+11], byte 171 

    jmp 0x0:0x7c00  ; execute the loaded sector 

times 510 - ($ - $$) db 0 
dw 0xAA55 

ORG 0x7C00 
[BITS 16] 

2 단계 :

stage2: 
    mov ax, 0xb800 
    mov es, ax 
    xor di, di 
    mov al, 70 
    mov ah, 0xc 
    stosw 
    jmp $ 

times 512 - ($ - $$) db 0 

그것은 KVM에서 완벽하게 작동,하지만 실제 하드웨어에 따라서 부문은

내 MBR입니다 .. 그것이 있어야 메모리에없는 진정한 바이오스와 함께. 나는 실제 하드웨어에서 부팅을 테스트하기 위해 USB 플래시 드라이브를 사용한다.

문제는 내 mbr의 첫 번째 바이트에서 정의하지 않은 BPB 일 수 있습니까? 나는 그렇게 생각하지 않는다. 왜냐하면 나는 단지 원시 섹터를 읽었 기 때문이다. 내가 잘못하면 나를 바로 잡는다.

누구나 단서가 될 수 있습니다.

+2

BIOS에 따라 USB 키가 플로피 드라이브로 취급되지 않을 수도 있습니다 ... USB 장치에서 부팅하는 방법을 찾으십시오. 프로세스가 다를 수 있습니다. – Macmade

+0

아니, 바이오스는 하드 디스크로 에뮬레이션하지 않는다. 또한 int 0x13이 올바른 주소로 섹터를로드한다는 것을 알았지 만 점프 할 때 실행되지 않습니다. – Bietje

+0

이 질문은 오래되었지만, USB 플래시 드라이브에 코드를 삽입하는 데 사용 된 프로그램이 무엇인지 궁금 할 것입니다. Windows에서이 작업이 수행 되었습니까? –

답변

2

귀하의 코드

덕분에 "첫번째 플로피 디스크 드라이브를"인도 표준시 어떤 디스크 0에서로드하려고합니다. 최신 HDD (및 USB 플래시 디스크)는 일반적으로 디스크 0x80으로 액세스됩니다. 따라서 시도해보십시오

bootdisk db 0x80 

코드에

+0

BIOS가 정상적으로 작동하는지 확인하기 위해 bootdisk 변수를 0x80으로 하드 코딩하지 않아도되지만 @Bietje는 bl (현재 부팅 된 장치의 장치 번호를 포함해야 함)를 이동하여 올바른 작업을 수행하는 것처럼 보입니다. 변수를 먼저 변수에 넣습니다. –

+1

또는 DL 레지스터의 BIOS 자체가 부트 로더에 전달한 값을 사용하십시오. 부팅 섹터가 BIOS에 의해로드 된 드라이브 번호입니다. 자체 인터럽트 13h를 사용하여 부트 섹터를로드 한 후 해당 번호가 그대로 남습니다. 그 후 값은 단지 DL에 남아 있고 부트 로더는 어떤 드라이브를 부팅했는지 알기 위해 값을 사용할 수 있습니다. – SasQ

+1

또한 부트 로더가 부팅 된 장치와 독립적 이도록하려면 int 13h function 08h 호출에서 DL의 해당 값을 사용하여 드라이브의 형상을 가져옵니다. 예를 들어 HDD 나 pendrive에서 부팅하는 경우 플로피 디스크의 표준 80 : 2 : 18 CHS 형상과 다를 수 있습니다. – SasQ

관련 문제