Загрузочное ядро ​​x86 из отдельного kernel.asm (nasm)

Я написал бутстрап для загрузочного сектора. Этот загрузчик пытается загрузить ядро ​​из этапа 2 во втором секторе.

Если я включаю ядро ​​в тот же asm, все работает как положено. если я добавлю файл kernel.bin из kernel.asm со смещением 512 байт в образ диска, он не будет делать то же самое, даже с точно таким же кодом. Вместо этого это печатает jibberish.

Мой код для чтения второго сектора и его выполнения выглядит следующим образом...

read_first_byte:
  pusha
  mov ah, 0             ; reset disk
  mov dl, [boot_drive]  ; drive 0
  stc
  int 13h
  jc rs_fail      ; return, we're a failure
reset_success:
  mov bx, stage2        ; place in memory 512 bytes past where the MBR is loaded.
  mov ah, 0x02 ; function
  mov al, 0x01 ; sectors to read
  mov ch, 0x00 ; track/cyl
  mov cl, 0x02 ; sector start
  mov dh, 0x00 ; head
  mov dl, [boot_drive] ; drive
  print_hex [boot_drive]
  stc
  int 13h
  jc rs_fail

  print_hex [stage2]
  print_hex [stage2 + 1]
  jmp stage2
  ;jmp disk_return
rs_fail:
  call int13_show_error

;;  mov ds, es
;;  mov si, 512       ; prep lodsb
;;  lodsb             ; load the first byte of the disk sector read - sector 2
disk_return:
  popa
  ret

Конец 512 по разделам...

    buffer times 510-($-$$) db 0    ; Pad remainder of boot sector with 0s
    dw 0xAA55       ; The standard PC boot signature

stage2:
    mov si, text_string   ; Put string position into SI
    call print_string       ; Call our string-printing routine
    mov si, crlf            ; Put string position into SI
    call print_string       ; Call our string-printing routine
    call read_keys
    jmp $

print_key:
  mov ah, 0         ; 16h read key function
  int 16h           ; al now has character from keyboard
  mov ah, 0Eh       ; TTY output, ah had scan code, we discard
  int 10h           ; prints character in ah

read_keys:
  mov ah, 01h       ; detect key
  int 16h
  jnz print_key     ; only print if key in buffer
    jmp read_keys           ; Jump to read_keys - infinite loop!

    text_string db 'Kernel loaded!', 0
  buffer2 times 1024-($-$$) db 0

Файл kernel.asm выглядит следующим образом...

BITS 16

start:
    mov si, text_string   ; Put string position into SI
    call print_string       ; Call our string-printing routine
    mov si, crlf            ; Put string position into SI
    call print_string       ; Call our string-printing routine
    call read_keys
    jmp $

print_key:
  mov ah, 0         ; 16h read key function
  int 16h           ; al now has character from keyboard
  mov ah, 0Eh       ; TTY output, ah had scan code, we discard
  int 10h           ; prints character in ah

read_keys:
  mov ah, 01h       ; detect key
  int 16h
  jnz print_key     ; only print if key in buffer
    jmp read_keys           ; Jump to read_keys - infinite loop!

print_string:           ; Routine: output string in SI to screen
  push ax
    mov ah, 0Eh     ; int 10h 'print char' function

.repeat:
    lodsb           ; Get character from string
    cmp al, 0
    je .done        ; If char is zero, end of string
    int 10h         ; Otherwise, print it
    jmp .repeat

.done:
  pop ax
    ret

    crlf db 0x0a,0x0d,0
    text_string db 'Kernel loaded!', 0

И загрузчик, и ядро ​​собраны со следующим, на случай, если я захочу использовать gdb...

  nasm -f elf -g -o file.elf file.asm
  objcopy -O binary file.elf file.bin

Для рабочего примера, у меня есть моя маленькая ОС на github. В ветке "kernel" я собираю ядро ​​из отдельного файла kernel.asm. Конкретный момент времени находится по адресу https://github.com/TrentonAdams/tinyos/tree/0524a1af9de7b3e58c7e2c0660f587d4c8573e98

 make clean test # runs qemu with the single myfirst.asm code
 make clean kernel # runs qemu with a disk image that has the kernel.bin in the second sector.

Для того, чтобы этот переполнение стека оставалось отдельным постом, не требующим внешних ссылок, пожалуйста, дайте мне знать, достаточно ли содержания поста для ответа на вопрос. то есть, если вам действительно нужно было узнать что-то от github, чего не было в этом посте, дайте мне знать, и я могу обновить это.

1 ответ

У вас несоответствие фактического ds и предположил org, Исправьте любой из них, чтобы они соответствовали. Если вы не использовали org в файле он по умолчанию равен нулю, поэтому вам нужно настроить ds так что он указывает на адрес загрузки, например mov ax, 0x7e0; mov ds, ax перед передачей управления на второй сектор. В качестве альтернативы используйте правильное orgнапример, org 0x200 сказать ассемблеру, что это продолжение первого сектора.

Другие вопросы по тегам