Как загрузить ядро ​​с диска с BIOS int 13h в сборке NASM?

Я застрял в этом на несколько недель и понятия не имею, где я ошибаюсь, потому что NASM не выдал мне никаких ошибок. Код довольно понятен из-за комментариев.

это код, который загружается из BIOS

 ;--------------------------------------------
 ; 'boot.asm'
 ; loaded from BIOS

 [org 0x7C00]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

 resetdisk:
  mov ah, 0x00  ; reset function
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc resetdisk

 readdisk:
  mov bx, 0x8000  ; segment
  mov es, bx
  mov bx, 0x0000  ; offset

  mov ah, 0x02  ; read function
  mov al, 0x03  ; sectors
  mov ch, 0x00  ; cylinder
  mov cl, 0x02  ; sector
  mov dh, 0x00  ; head
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc readdisk
  jmp [es:bx]   ; buffer

 ;--------------------------------------------

 times 510 - ($ - $$) db 0x00
 db 0x55, 0xAA

Это код, который должен быть (но не) загружен

 ;--------------------------------------------
 ; 'load.asm'
 ; loaded from 'boot.asm'

 [org 0x8000]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

  jmp $    ; hang

Любая помощь будет принята с благодарностью.

Патрик


person Community    schedule 11.10.2009    source источник
comment
Пожалуйста, исправьте, если я ошибаюсь, но, возможно, будет лучше, если вместо jmp $ вы сделаете cli для очистки прерываний, а затем hlt для остановки процессора. Таким образом, вы не тратите много времени на процессор.   -  person kaneda    schedule 05.02.2011
comment
Пример минимального рабочего газа:   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 28.10.2015


Ответы (5)


jmp [es:bx] не переходит по адресу es:bx. Эта команда выполняет непосредственный переход к адресу, хранящемуся в слове es:bx. Вот почему многие старые ассемблеры заставляли вас записывать такие инструкции как jmp word ptr [es:bx] или даже jmp near ptr [es:bx]; так становится яснее, что должно произойти. Что вы, вероятно, захотите здесь, так это прыжок далеко в фиксированное место:

; jmp far 8000:0000
db 0eah
dw 00000h ; offset
dw 08000h ; segment

Если вы хотите перейти к es:bx, используйте retf:

push es
push bx
retf
person Anton Tykhyy    schedule 13.10.2009
comment
Это похоже на правильную вещь, но я не могу заставить ее работать. Есть ссылки на учебники / документы? - person ; 13.10.2009
comment
Нет: S, это работает. Просто я использовал ".img" вместо "a:". Мне придется это изменить. - person ; 13.10.2009
comment
Почему бы просто не сделать jmp 0x0000: 0x8000 напрямую в nasm? Это более читабельно. - person SecurityMatt; 22.01.2013

Я не уверен, чего вы пытаетесь достичь с помощью кода, но если я правильно понимаю, вы хотите прочитать несколько секторов с диска в местоположение 0x8000, а затем выполнить этот код?

Если это так, то вам придется явно сделать ЗВОНОК / ПЕРЕХОД в это конкретное место. BIOS не будет вызывать этот код за вас. При загрузке, как только BIOS будет инициализирован, он установит IP-адрес указателя инструкции на адрес 0x7c00. Затем процессор начнет выполнять код последовательно, поэтому без JMP / CALL до 0x8000 он не будет выполнять код с 0x8000, пока он не выполнит каждый адрес памяти в диапазоне от 0x7c00 до 0x8000 и т. Д.

Таким образом, решением было бы иметь инструкцию jmp или call после вашего jc readdisk.

Если мое понимание неверно, прошу прощения. Надеюсь это поможет.

person Pratik Bhatt    schedule 11.10.2009
comment
jmp находится после jc readdisk: jmp [es: bx], где es: bx - это буфер кода - person ; 11.10.2009
comment
Извини, что пропустил. Только одно, глядя на ваш код. Вы уверены, что ваш файл load.asm находится в секторе 2? - person Pratik Bhatt; 12.10.2009
comment
да, я использую dd для win32 и его в секторе после загрузки - person ; 12.10.2009

Одна проблема с INT13 заключается в том, что номера заголовков и дорожек начинаются с 0, но номера секторов по какой-то причине начинаются с 1. Вы можете проверить, соответствует ли ваша утилита записи секторов этой схеме нумерации.

Вопросов:

  • Сколько точек вы видите при загрузке?
  • Включается мотор дискеты?
person I. J. Kennedy    schedule 13.10.2009
comment
да, я это проверил, и это не то. Кроме того, я использую эмулятор (win32 qemu), поэтому мотор дискеты не срабатывает. - person ; 13.10.2009

Я не знаю, используете ли вы дискету для загрузки своей ОС, но если вы ее используете, я предлагаю вам объявить некоторые вещи после объявления ORG и Bits, посмотрите (они очень важны):

JMP short main   ; Jump past disk description section
NOP              ; Pad out before disk description

; ------------------------------------------------------------------
; Disk description table, to make it a valid floppy
; Note: some of these values are hard-coded in the source!
; Values are those used by IBM for 1.44 MB, 3.5 diskette

OEMLabel            db "BERL OS"    ; Disk label - 8 chars
BytesPerSector      dw 512          ; Bytes per sector
SectorsPerCluster   db 1            ; Sectors per cluster
ReservedForBoot     dw 1            ; Reserved sectors for boot record
NumberOfFats        db 2            ; Number of copies of the FAT
RootDirEntries      dw 224          ; Number of entries in root dir
LogicalSectors      dw 2880         ; Number of logical sectors
MediumByte          db 0F0h         ; Medium descriptor byte
SectorsPerFat       dw 9            ; Sectors per FAT
SectorsPerTrack     dw 18           ; Sectors per track (36/cylinder)
Sides               dw 2            ; Number of sides/heads
HiddenSectors       dd 0            ; Number of hidden sectors
LargeSectors        dd 0            ; Number of LBA sectors
DriveNo             dw 0            ; Drive No: 0
Signature           db 41           ; Drive signature: 41 for floppy
VolumeID            dd 00000000h    ; Volume ID: any number
VolumeLabel         db "BERL OS"    ; Volume Label: any 11 chars
FileSystem          db "FAT12"      ; File system type: don't change!

; End of the disk description table
; ------------------------------------------------------------------

Это хорошая идея.

С Уважением.

person Nathan Campos    schedule 12.10.2009
comment
это действительно не имеет значения. Это для файловых систем и BIOS - person ; 12.10.2009
comment
Хорошо, теперь я знаю основную идею. С Уважением - person Nathan Campos; 12.10.2009

Я не уверен, почему код не работает, поскольку я не могу проверить всю среду (диск, дамп памяти и т. Д.) ... но я могу сказать, что ... код неправильный. Вы загружаете вторую программу не в 0x8000 (это был смысл использования 0rg 0x8000, верно?), А в 0x80000.

Причина в том, что вы неправильно используете адресацию сегмента: смещение, адрес 0x8000:0x0000 преобразуется в линейный адрес 0x80000, поскольку значение сегмента сдвигается влево на 4 бита и затем добавляется к смещению.

Чтобы решить эту проблему, вам следует взглянуть на дамп памяти и посмотреть, работает ли программа так, как вы ожидаете… либо это, либо вы загружаете неправильные сектора диска.

person thypad    schedule 30.04.2011