Проблема с int 13h, ah = 02h

Тема в разделе "WASM.OS.DEVEL", создана пользователем int3, 8 апр 2010.

  1. int3

    int3 New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2010
    Сообщения:
    3
    Пытаюсь считать с диска сектор с помощью функции 02h, прерывания 13h. После выполнения прерывания в ah - 00h, al - 01h, CF = 0. Однако в памяти, вместо того, что мне нужно - нули. Вот код:

    Код (Text):
    1. org 7c00h
    2. use16
    3. main:
    4.         jmp loader
    5.    
    6. error db "ERROR!", 0
    7.        
    8. loader:
    9.  
    10.         mov ax, cs
    11.         mov ds, ax
    12.         mov es, ax
    13.        
    14.         mov bx, 1000h
    15.         mov es, bx
    16.         mov bx, 0000h
    17.         mov cl, 01h
    18.  
    19.         mov ah, 02h
    20.         mov al, 1
    21.         mov ch, 0
    22.         mov dh, 0
    23.         int 13h
    24.  
    25.         jc ERROR
    26.  
    27.         jmp FINISH
    28.  
    29. ERROR:
    30.         ;тут выводится сообщение об ошибке
    31.         jmp $
    32.  
    33. FINISH:
    34.  
    35.         jmp 1000h:0000h
    36.  
    37. times 510 - ($ - main) db 00h
    38. db 055h, 0aah
    39. times 1024 db 0CCh                ;--> то что должно читаться в память
    Компилирую фасмом, потом с помощью winHEX'a записываю в созданный Bochs Disk Image Creation Tool'сом диск (именно диск, а не дискету [хотя если создать дискету, и записать код на неё - также будут читаться нули.]). Перелопатил тучу исходников, ни один не заработал.
     
  2. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Вот так у меня было:
    Код (Text):
    1.      ; Запись на диск
    2.      mov bx, [startSaveAddress]  ; В bx адрес, с которого будет вестись запись
    3.      mov ax, [numberSavingBytes] ;\
    4.      shr ax, 9                   ;/ В ax число секторов для записи
    5.      mov byte[nSectors], al
    6.      mov ah, 03h               ; Функция записи на диск
    7.      mov ch, byte[track]       ; Номер цилиндра
    8.      mov cl, byte[sector]      ; Начальный сектор для записи
    9.      mov dh, byte[head]        ; Номер головки
    10.      mov dl, byte[disk]
    11.      int 13h
    Работало
     
  3. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Извиняюсь. Вот:
    Код (Text):
    1.      ; Чтение с диска
    2.      mov bx, 0                  ; В es:bx - начало нашего буфера
    3.      mov al, byte[nSectors]
    4.      mov ah, 02h
    5.      mov ch, byte[track]
    6.      mov cl, byte[sector]
    7.      mov dh, byte[head]
    8.      mov dl, byte[disk]
    9.      int 13h
     
  4. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Ты что в es загружаешь, чудилО? В [es:bx] должен быть адрес буфер, куда считается информация.
    RTFM, и это самый мягкий ответ, который тебе могут здесь дать.
     
  5. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    т.е. чудИло
     
  6. PowerASM

    PowerASM New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    59
    в dl должен быть номер диска. номер диска в загрузчик передается только при эмуляции флопика. в остальных случаях - по желанию разработчиков.
     
  7. int3

    int3 New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2010
    Сообщения:
    3
    Всё. Разобрался.
     
  8. olegsys

    olegsys New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2010
    Сообщения:
    10
    Привет! а зачем ты юзаешь эту старую функцию? Меня лично воротит от всяких древностей типа "цилиндров"
    попробуй так

    ;Чтение через BIOS секторов
    mov ah,42h ; номер функции
    mov dl,80h ; drive index (e.g. 1st HDD = 80h)
    mov si,_packet ; DS:SI segment:offset pointer to the DAP(Disk Address Packet)
    int 13h

    jc _error_bios_ext ; Проверка успешности:
    cmp ah,0 ; CF - сброшен, AH - код возврата
    jne _error_bios_ext
    ................................................................
    ; DAP : Disk Address Packet
    _packet db 16 ; Размер структуры = 16 байт
    db 0 ; всегда равно 0
    dw 98 ; Число секторов сколько читать
    dw 07e00h,0 ; segment:offset pointer to the memory buffer - куда читать
    dq 1 ; номер первого сектора для чтения (отсчет с 0)

    Я пользуюсь этим способом. Тоесть указываешь LBA адрес сектора с кторого нужно читать и адрес куда читать.
    По поводу номера диска: у меня тут указано 80h - это будет тот самый диск с которого у тебя код грузится. Тоесть
    к примеру у меня написан код, я его HEX-редактором копирую прямо в 0-ой сектор флэшки, вставляю флешку и BIOSом гружусь с неё и получается что первый диск - это моя флешка, и вышеуказанным кодом спокойненько загружаю так называемое "ядро" моей будущей ОС. Всё чётко и быстро. Почитай про эту функию 42h- мне очень понравилось то что можно и с флешки грузиться и с винта любого что SATA что PATA, и не надо код модифицировать
     
  9. int3

    int3 New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2010
    Сообщения:
    3
    olegsys
    Спасибо, гляну.
     
  10. domov0i

    domov0i New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    74
    прошу прощения за оффтоп

    olegsys, а ты не мог бы выложить пример своего загрузчика, если есть под tasm.
     
  11. domov0i

    domov0i New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    74
  12. olegsys

    olegsys New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2010
    Сообщения:
    10
    Выкладываю полный код загрузчика. Только написан под NASM. Я его компилирую в плоский формат bin. Записывать его можно на любой жесткий диск или на флешку, без разницы.
    Насчет того в какой сектор записывать - два варианта:
    1) выделяем полность флешку под нашу систему, т.е. флешка не будет видна ни из под какой другой ОСи - это самый простой способ. В этом случае НЕ НАДО делать не главный загрузчик (MBR в "стандартном пониманиии) в 0-ом секторе ни таблицу разделов - ничего. В секторе 0 будет наш код(выложенный ниже). В BIOS Setup выставляем загрузку с флешки. BIOS грузит всегда 0-ой сектор в 0x0:0x7C00. И тут у нас сразу же НАШ код который догружает всё остальное, поэтому никакя таблица разделов НЕ НУЖНА! например у меня в 0-ом секторе этот код (ниже), а всё остальное начинается с 1-го сектора (см в _packet: dq 1 .)
    Еще один плюс такого подхода: под Linux делаю так:
    dd if=/home/oleg/OS/os.bin of=/dev/sdh , где sdh - флешка, а OS.bin - это что получили скомпилированным от NASMA. И всё мгновенно оказывается начиная с 0-го сектора.
    Под WIn для того же самого можно воспользоваться прогой WinHEX: открываю OS.bin, выделить всё Ctrl-A, копировать Ctrl-C, открываю "Физическое Устройство Диск" нужное, встаю на offset 000000, вставить Ctr-V и всё.

    2) Второй способ. Берём флешку или диск с уже созданными разделами и соответственно с уже записанным загрузчиком MBR в 0-ом секторе, он там обычно всегда есть уже даже на новых, его делает Win при "инициализации нового диска" или grub делает при установке на диск. Там в 0-ом секторе смотрим таблицу разделов начиная с 1BEh
    http://ru.wikipedia.org/wiki/Главная_загрузочная_запись.
    там находим начало нужного раздела (у первого раздела обычно 63) и записываем наш загрузчик уже в 63-ий сектор! соответствено в структуре _packet меняем dq 1 на dq 64 (в 63ом-загрузчик, который загружает то что с 64го!)
    Под Linux dd уже не прокатит для этого. Нужно использовать okteta. Под Win можно темже WinHEX.

    Вот код моего
    Код (Text):
    1. BITS 16
    2. org 07C00h
    3.         mov ax,cs
    4.         mov ds,ax               ; устанавливаем сегментные регистры
    5.         mov es,ax
    6.         mov ss,ax
    7.         mov sp,07c00h               ; устанавливаем стёк вниз от этого адреса
    8.                             ; Проверка наличия BIOS Extensions
    9.         mov ah,41h              ; номер функции
    10.         mov bx,55aah
    11.         mov dl,80h              ; drive index (e.g. 1st HDD = 80h)
    12.         int 13h
    13.                             ; Результат:
    14.         jc _error_bios_ext          ; в CF=1-ошибка, CF=0 =всё ОК
    15.                       cmp bx,0aa55h                                  ; в BX должна быть сигнатура
    16.         jnz _error_bios_ext        
    17.  
    18.                             ;Чтение через BIOS секторов
    19.         mov ah,42h              ; номер функции
    20.         mov dl,80h              ; drive index (e.g. 1st HDD = 80h)
    21.         mov si,_packet              ; DS:SI segment:offset pointer to the DAP(Disk Address Packet)
    22.         int 13h                                              ; в DS:SI указатель на нашу структуру Пакета Диского Адреса
    23.  
    24.         jc _error_bios_ext          ; Проверка успешности:
    25.         cmp ah,0                     ;  CF - сброшен, AH - код возврата
    26.         jne _error_bios_ext
    27.  
    28.         jmp RM              ;если нормально прочиталось прыгаем на только что загруженное
    29.  
    30. _error_bios_ext:
    31.         jmp $                                         ; у меня при ошибке - зацикливается
    32.  
    33.                             ; DAP : Disk Address Packet
    34. _packet db  16                  ; Размер структуры = 16 байт
    35.         db  0               ; всегда равно 0
    36.         dw  98              ; Число секторов для чтения (не больше 127)
    37.         dw  07e00h,0            ; segment:offset pointer на память КУДА читать
    38.         dq  1                   ; номер первого сектора для чтения (отсчет с 0) в LBA
    39.                                                                            ;внимание используем dq т.к. это поле 64-битное
    40.         times 510-($-$$)    db 0
    41.         db 55h,0aah
    42.  
    43. RM:
    44. ................. здесь наша ОС :) .......
     
  13. domov0i

    domov0i New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    74
    спасибо !