Привет всем.Не могу понять,есть первичный загрузчик,(с его работой я уже вроде как разобрался)после включения компа происходит процедура POST,после чего bios читает первые 512 байт (именно загрузчик)сектора по смещению 7C00h ,дальше есть несколько вариантов загрузки,меня интересует как загрузить файл(условно пусть будет ядро) ядро типа com с дискеты (или жд) в память и исполнить его? з.ы. при етом хотелось бы уточнить всегда ли нужно включение линии А20?
После того как передано управление загрузчику, он смотрит в таблицу разделов, выбирает нужную и из заранее известного места (будь-то смещение в таблице или имя файла [для этого уже нада будет файловую таблицу парсить]) подгружает рантайм. Но иногда для "умного" загрузчика не хватает 512байт, тогда загрузчик передаёт управление другой свой половинке, расположенной где-то на диске, а уж потом рантайму Рантайм в свою очередь переводит процессор в нужные режимы и грузит ядро в память Если вначале рантайм не влизает в 1Мб памяти, то загрузчик включает А20. Или если не планируется использовать защищённый режим, то для больше доступного ОЗУ рантайм включает А20 В общем как-то так. Тут более подробно: http://insidepro.com/kk/065/065r.shtml http://thestarman.narod.ru/asm/mbr/index.html
с A20 понятно.Ядро как и все ком файлы будет грузиться по смещению 100h, но как энто примерно должно выглядеть в коде?вызов дальнего типа?
Ну смотри, когда грузится boot/mbr сектор, то грузится он из нулевой дорожки в память по адресу 7C00h При этом сразу ты имеешь в регистре DL - номер накопителя с которого произошла нзагрузка. Если этот номер 0 - 7 то это дискета. Если больше 80h то винт и прочие. При этом память 07E00-9FFFF (600 кил) свободна. И юзай как захочешь её. Если захочется заюзать больше метра, тогда уже придется A20 включать. Если больше памяти не надо и нет нужны входить в защищенный режим то этого всего достаточно будет. Далее свою Com прогу грузи через int13h с диска(номер диска ты знаешь сразу) (хз где и как ты там раскидаешь её) можешь свою файловую систему даж сделать или просто тупо в последующих секторах разместить. Если COM прогу компилил с org 100h то кидай её в память по любому адресу из диапазона 07E00-9FFFF но главное чтобы смещение было 100h т.е. подойдет даже адрес 10100h далее уже передавай ему управление. управление передавай тип jmp 1:0100h (мож и ошибаюсь, давно уже не лазел в это)
окей,спасибо за пояснение,завтра попробую,если найду как можно дискету эмулировать, бо флопик отказался работать,и отпишу,пока не три тему пжлст. а и еще маленькое уточнение,в реальном режиме запись в порты ж разрешается?
2 DooD в реальном режиме можно делать всё что угодно. Конечно для некоторого придется переходить в защищенный режим. Зачем эмулировать флопик? 1) ставишь VMware 2) создаешь файл (можно через WinHex) в котором - первые 500 байт - твой загрузчик потом идут 2 байта сигнатура конца загрузочного сектора. далее уже идут данные какие тебе надо (к примеру твоя COM программа) 3) далее полученный файл цепляй как образ дискеты к виртуалке и грузись. Зависит от того на чем пишешь (какой именно ASM), можно всё сразу писать в виде одно большой COM программы, главное правильно разделить части.
2 slesh пишу на nasm еще такой вопрос,если просто написать ради теста прогу которая выводит на экран что то юзая прерывания биоса,и загрузить ее загрузчиком это будет равносильно как ядро загрузить?
ну хз. ядро ОС это та часть которая выполняет определенные действия помогающее работе других прорамм (а также возможность загрузки этих программ). Проще делать как было в DOS - ставить свои обработчики на пустые прерывания и на основе их уже делать нужные вещи. минут через 30 покажи приколюху которую сегодня навоял, может будет полезной
я имел ввиду что оно работать будет если так сделать? еще понял что придется писать что то типа int 21h,свое прерывание
Вот лови фишку. Написал на FASM (удобнее на нем было писать) Что делает: 0) бутсектор настраивает сегменты и стек 1) бутсектор ставит разрешение экрана - текстовое 80x25 2) бутсектор считывает "ядро" у меня оно 1 сектор размером. Но можно до 16 секторов сделать (для дискеты 1.44) и грузит его по адресу 9000h:0000h 3) если ядро считалось, то передаётся на него управление 4) если ядро не считалось, то выдаётся сообщение, затем ждется нажатие кнопки, после чего происходит ребут 5) после запуска ядра, оно выводит на экран сообщение 6) ставится графический режим 320*200 256 цветов. 7) из следующих секторов грузится картинка сразу в видеопамять. (с палитрой косяки вышли по этому цвета не красиво вышли ((((( ) 8) затем ждется нажатие кнопки, после чего происходит ребут Тестил на bochs и VMware. на VMware картинка не показалась (наверное из-за особенностей его BIOS или не правильно дискету распознал). При тесте на bochs пришлось насильно указать в его конфигах что это дискета 1,44 метра. Иначе не правильно пахало бы всё. Дело в том, что для разных дискет/дисков соотношение секторов на дорожке, кол-во головок и кол-во дорожек на стороне - разное, по этому функция загрузки секторов написана только для поддержки 1,44 дискет. (хотя если парсить системные таблицы или заюзать 08H функцию из int10h то можно универсально всё сделать) P.S. там для загрузки картинки я чуть ошибся. надо грузить на 2 сектора больше (картинка начиная с 3 сектора и имеем 125 секторов). Скрины: В архиве найдешь: 1) исходник с комментами 2) файл картинки (чисто данные) 3) готовый образ дискеты
оёёё, ну спасибо огромное,я в принципе все примерно знал как,вот кроме пункта 2,а так сейчас буду смотреть,спасибо еще раз. а если заменить " ядро " программой такого типа,она сработает ? Code: org 0x100 start: mov ah,9h mov bh,0 mov al,34 mov bl,1 mov cx,5 int 10h ret
Тут главное помнить 3 вещи: 1) максимум исполняемого кода в сегменте - 65 кил. т.к. выходить за пределы сегменты нельзя. т.е. можно, но всё должно быть правильно настроено в программе. 2) за раз можно только 128 секторов загрузить подряд (иначе в сегмент не влезит) 3) правильно создать функцию чтения секторов. т.е. чтобы по номеру сектора вычислялась головка, цилиндр (трек), и номер сектора на цилиндре. которые зависят от диска/дискеты. по этому лучше сразу параметры вписывать при компиляции под разный вид дискет или для винта. Хотя для винта по другому чуть делается. Можно покопаться в системных таблицаъ 1) если DL = 0..7 то это дискета и значит параметры брать из Diskette Parameter Table т.е. по адресу 0:78h лежит таблица 2) если DL >= 80h то это жесткий и значит параметры брать из Hard Disk Parameter Table т.е. по адресу 0:0104h лежит таблица Эти таблицы в сети найти можно.
да заработает, но 1) вместо ret чтонить другое надо (или ожидать ввода или ребут) или вообще остановить работу проца (hlt) 2) org 0x100 замени на org 0x0 т.к. тыже код грузишь сразу в память, по смещению 0 а не 0x100. Это смещение нужно только для того, чтобы всё что от 0 до 0x100 было стеком. но так как загрузчик ставит и так стек то можно и его юзать норм, главное не трогать ss и sp и будет норм тогда
Вообще советую запускать всё в emu8086 1) компилишь всё что получилось 2) открываешь этот bin файл в emu8086 3) записываешь его на виртуальный FDD 4) грузишься в виртуального FDD далее уже можешь сразу отлаживать код загрузчика также как и в обычном дебагире. Можно вообще ASM код набрать прям в нем, он понимает синтаксис FASM'а и еще чегототам
еще вопрос,если до разрешения прерываний включить линию А20 таким кодом: in al,92h or al,2 out al,92h как проверить что разрешено больше 1 мб? и вообще когда именно она открывается?и включать надо защищенный режим установокй бита в регистре CR0 ?либо лучше оставить так?
просто так обратиться к памяти выше 1 метра нельзя. и вся фишка в адресации. сегмент:смещение. Преобразуется по формуле сегмент*16 + смещение. вот и выходит 65535*16+65535 = 1 метр. выше просто так не обратишься. Если A20 активировать, то можно будет уже к 16 метрам обратиться. Но толку от этого всё равно не очень много. Проверить можно хитро: некоторые адреса обрезаются. К примеру FFFF:0010 указывает туда же, куда и адрес 0000:0000. В википедии описано почему и как. По этому просто надо найти адрес (неиспользуемый), записать туда чтонить и считать уже по большему адресу. если тоже самое считалось, то значит не включен A20. В защищенный режим лучше не соваться, больше гемора, да и к тому же запрещено использовать bios прерывания. И графика доступна только начиная с Vesa 3.0. А так придется напрямую обращаться к видеопамяти чтобы текст вывести. Для защищенного режима недостаточно править CR0, надо еще настраивать таблицу дискрипторов и желательно таблицу прерываний. И тогда для полного счастья еще активировать работу со страничной памятью (но это уже сложнее). Хотя можно продолжить работать и с сегментной памятью.
да, прикольная тема, сам недавно делал тривиальный бутлокер от детей, делал на фасме, написал правда только код верификации пасса, а через день винт грохнул трукриптом (с хидден осью, когда устанавливал подставную) и все сорцы аж с 03года =(
Вообще для полной красоты можно заюзать Vesa по полной к примеру переключиться в режим 118h (1024x768 24 бита) и рисовать что угодно и как угодно, вот тока жопа будет из-за переключения буферов (чтобы зарисовать весь экран потребуется 36 раз переключать буферы видеопамяти) зато можно что-то красиво сделать (типа окошек)