Пытаюсь считать с диска сектор с помощью функции 02h, прерывания 13h. После выполнения прерывания в ah - 00h, al - 01h, CF = 0. Однако в памяти, вместо того, что мне нужно - нули. Вот код: Код (Text): org 7c00h use16 main: jmp loader error db "ERROR!", 0 loader: mov ax, cs mov ds, ax mov es, ax mov bx, 1000h mov es, bx mov bx, 0000h mov cl, 01h mov ah, 02h mov al, 1 mov ch, 0 mov dh, 0 int 13h jc ERROR jmp FINISH ERROR: ;тут выводится сообщение об ошибке jmp $ FINISH: jmp 1000h:0000h times 510 - ($ - main) db 00h db 055h, 0aah times 1024 db 0CCh ;--> то что должно читаться в память Компилирую фасмом, потом с помощью winHEX'a записываю в созданный Bochs Disk Image Creation Tool'сом диск (именно диск, а не дискету [хотя если создать дискету, и записать код на неё - также будут читаться нули.]). Перелопатил тучу исходников, ни один не заработал.
Вот так у меня было: Код (Text): ; Запись на диск mov bx, [startSaveAddress] ; В bx адрес, с которого будет вестись запись mov ax, [numberSavingBytes] ;\ shr ax, 9 ;/ В ax число секторов для записи mov byte[nSectors], al mov ah, 03h ; Функция записи на диск mov ch, byte[track] ; Номер цилиндра mov cl, byte[sector] ; Начальный сектор для записи mov dh, byte[head] ; Номер головки mov dl, byte[disk] int 13h Работало
Извиняюсь. Вот: Код (Text): ; Чтение с диска mov bx, 0 ; В es:bx - начало нашего буфера mov al, byte[nSectors] mov ah, 02h mov ch, byte[track] mov cl, byte[sector] mov dh, byte[head] mov dl, byte[disk] int 13h
Ты что в es загружаешь, чудилО? В [es:bx] должен быть адрес буфер, куда считается информация. RTFM, и это самый мягкий ответ, который тебе могут здесь дать.
в dl должен быть номер диска. номер диска в загрузчик передается только при эмуляции флопика. в остальных случаях - по желанию разработчиков.
Привет! а зачем ты юзаешь эту старую функцию? Меня лично воротит от всяких древностей типа "цилиндров" попробуй так ;Чтение через 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, и не надо код модифицировать
прошу прощения за оффтоп olegsys, а ты не мог бы выложить пример своего загрузчика, если есть под tasm.
Выкладываю полный код загрузчика. Только написан под 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): BITS 16 org 07C00h mov ax,cs mov ds,ax ; устанавливаем сегментные регистры mov es,ax mov ss,ax mov sp,07c00h ; устанавливаем стёк вниз от этого адреса ; Проверка наличия BIOS Extensions mov ah,41h ; номер функции mov bx,55aah mov dl,80h ; drive index (e.g. 1st HDD = 80h) int 13h ; Результат: jc _error_bios_ext ; в CF=1-ошибка, CF=0 =всё ОК cmp bx,0aa55h ; в BX должна быть сигнатура jnz _error_bios_ext ;Чтение через 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 ; в DS:SI указатель на нашу структуру Пакета Диского Адреса jc _error_bios_ext ; Проверка успешности: cmp ah,0 ; CF - сброшен, AH - код возврата jne _error_bios_ext jmp RM ;если нормально прочиталось прыгаем на только что загруженное _error_bios_ext: jmp $ ; у меня при ошибке - зацикливается ; DAP : Disk Address Packet _packet db 16 ; Размер структуры = 16 байт db 0 ; всегда равно 0 dw 98 ; Число секторов для чтения (не больше 127) dw 07e00h,0 ; segment:offset pointer на память КУДА читать dq 1 ; номер первого сектора для чтения (отсчет с 0) в LBA ;внимание используем dq т.к. это поле 64-битное times 510-($-$$) db 0 db 55h,0aah RM: ................. здесь наша ОС :) .......