Вопрос касательно программирования MBR

Тема в разделе "WASM.OS.DEVEL", создана пользователем drunken_cowboy, 26 сен 2011.

  1. drunken_cowboy

    drunken_cowboy New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    6
    Доброе утро. Я в ассемблере, можно сказать, новичок и хочу освоить низкоуровневое программирование на примере своего загрузчика. Схема примерно такова: в MBR диска садится код, проверяющий наличие диска с определённым ID, а оригинальная MBR сохраняется в другой сектор и потом подгружается.

    Дабы не плодить множество файлов, я хотел код, который будет записан в MBR, записать, скажем, в инсталляторе, в отдельной секции, а потом просто скопировать на место MBR. Но инсталлятор на MASM32, поэтому вопрос такой: будет ли код, написанный под Win32 без использования 32-разрядных регистров, работать на таком уровне? Т.е. будет ли он тем же, как если бы я собирал его в отдельном com-файле под досом?

    Сам код для MBR:
    Код (Text):
    1.     org 7C00h                              
    2.                         ; Загрузим себя по другому адресу
    3.                         ; Но не весь код, а только с
    4.                         ; метки payload
    5.     cld
    6.     mov si, (payload + 7C00h)
    7.     mov di, 7D00h
    8.     mov cx, 200h
    9.     rep movsb                          
    10.                                    
    11.     jmp 0000:7D00h      ; far jump на копию нашего кода
    12.    
    13. payload:
    14.                         ; Чтение старой MBR из 8 сектора
    15.                         ; в режиме CHS
    16.                                
    17.     mov ax, 0201h           ; Номер функции & номер сектора
    18.     mov dl, 80h         ; С первого диска
    19.     xor dh, dh          ; Нулевой головки
    20.     mov cx, 0008h           ; Восьмой сектор нулевого
    21.                         ; цилиндра
    22.     mov bx, 7C00h           ; Читаем по смещению бывшего
    23.                         ; загрузчика 
    24.     int 13h
    25.  
    26.     ; Тут рабочий код, не забываем о 446 б. Мэйби есть смысл подгрузить ещё
    27.     ; кода
    28.    
    29.                         ; Прыгаем на оригинальную
    30.                         ; загрузочную запись
    31.     jmp     0000:7C00h
     
  2. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Ты должен вставить бинарник в инсталлятор в каком-либо виде (например, как байтовый массив констант).

    То, о чем ты говоришь, возможно, но не целесообразно и потребует весьма специфических действий по пересчету смещений и т.п. Хотя в fasm'е это сделать не сложно:

    Код (Text):
    1. mbr:
    2.   org 7C00h
    3.   use16
    4.   ...
    5.   rb 7DB8h-$
    6.   org mbr+($-$$)
    7.   use32
     
  3. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Дело не в регистрах. А в системах декодирования команд 16 битной схемы и 32 битной. Но это легко решается используя управляющие слова "use16" и "use32" подробнее зависит от компилятора.

    Вторая проблема это смещения. Надо чтобы компилятор и правильно выставил или твой инсталятор. Это нетрудно.
     
  4. drunken_cowboy

    drunken_cowboy New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    6
    Компилятор - masm32, который, кажется, 16-битный код уже не поддерживает.
    Хм. Понятно, спасибо. Тут нарисовалась другая проблема - вышеуказанный код я собрал фасмом и записал в MBR, сохранив старую в нужный сектор. VirtualBox при запуске выдало примерно следующее: "int13_harddisk: function 42. Can't use 64bits lba", и это притом, что я читаю в CHS, а функция 02, а не 42. Я подозреваю, что я где-то натупил со смещениями на этапе переноса тела загрузчика в другую область памяти, и он прыгнул не в то место. В какую сторону нужно копать?
     
  5. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    drunken_cowboy
    Код (Text):
    1. mov    si, (payload + 7C00h)
    Здесь неверно, т.к. согласно вышестоящему org 7C00h отсчёт адресов всех меток, включая payload, уже идёт начиная с базы 7C00h.
     
  6. drunken_cowboy

    drunken_cowboy New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    6
    Чёёрт, точно, прошляпил. После редактирования:
    Код (Text):
    1.     use16
    2.     org 7C00h                              
    3.                         ; Загрузим себя по другому адресу
    4.                         ; Но не весь код, а только с
    5.                         ; метки payload
    6.  
    7.     xor ax,ax
    8.     mov ds,ax
    9.     mov es,ax
    10.     mov ss,ax
    11.     mov sp,7B00h           
    12.  
    13.     cld
    14.     mov si, payload
    15.     mov di, 7D00h
    16.     mov cx, 200h
    17.     rep movsb                      
    18.  
    19.     jmp 0000:7D00h          ; far jump на копию нашего кода
    20. payload:
    21. ...
    При загрузке это дело намертво зависает, а толкового мана по отладке загрузчиков я так и не нашёл. Вообще, вот такой трюк сработал:

    Код (Text):
    1. org 0600h
    2. use16
    3. xor ax,ax
    4. mov ds,ax
    5. mov es,ax
    6. mov ss,ax
    7. mov sp,7C00h
    8.  
    9. cld
    10. mov si, 7C00h
    11. mov di, 600h
    12. mov cx, 200h
    13. rep movsb  
    14. jmp 0000:payload
    15.  
    16. payload:    
    17. ...
    Вроде схема примерно одинаковая, где тут может быть загвоздка? Обидно, что ошибся в десяти строчках, а не знаю, где. Вроде и
     
  7. acckiitvar

    acckiitvar Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    71
    Могу предложить поотлаживаться на SimNow. Там есть встроенный отладник.
     
  8. drunken_cowboy

    drunken_cowboy New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    6
    У меня 32-битная система, увы.
     
  9. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Я думал, мы не обсуждаем код... Твои 7B00h, 7D00h меня пугают. Действительно на ровном месте столько неоднозначных вещей понаделал... Если чЁ, то вершину стека можно устанавливать на 7С00h, а 7C00h+512 = 7E00h. Твое желание перемещать только полезный код похвально, но если это делать необдуманно, то опять можно наломать дров со смещениями. fasm в отличие от нек. др. компиляторов позволяет делать такие вещи достаточно элегантно. Вот немного обобщенный вариант разметки, используемый в моих MBR-загрузчиках.
    Код (Text):
    1.         org 7C00h
    2. start:
    3.         xor cx,cx
    4.         cli
    5.         mov ss,cx
    6.         mov sp,$$
    7.         sti
    8.         mov ds,cx
    9.         mov si,old_base - old_base mod 2
    10.         mov es,cx
    11.         mov di,new_base - old_base mod 2
    12.         cld
    13.         mov cl,(size+1)/2
    14.         rep movsw
    15.  
    16.         jmp 0:new_base
    17.  
    18.         rb 440-($-$$)-size
    19. old_base:
    20.         org 600h ; 7E00h
    21. new_base:
    22.         ...
    23. ; необязательно, просто четный размер гарантирует
    24. ; выравнивание перемещаемого кода на четную границу,
    25. ; что улучшит эффективность при перемещении словами
    26.         align 2
    27.         label size at $-$$
    Это не самая простая разметка. Можно проще:
    Код (Text):
    1.   org 7C00h
    2.   ...
    3.   align 2
    4. old_base:
    5.   org 600h
    6. new_base:
    7.   ...
    8.   org old_base+($-$$) ; old_base+size
    9.   db 7C00h+440-$ dup 0
     
  10. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Да, забыл сказать, что сложность первой разметки вызвана тем, что я перемещаемый код обычно размещаю под верхней границей доступной области MBR.
     
  11. drunken_cowboy

    drunken_cowboy New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    6
    Однако да. Читая сектор по адресу 7C00h, я затирал скопированный код, поэтому там и творилось нечто невообразимое. Спасибо. Приму к сведению, в т.ч. и код.
     
  12. drunken_cowboy

    drunken_cowboy New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    6
    Ещё такой вопрос, могу ли я использовать 32-битный код в MBR?
     
  13. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    drunken_cowboy
    запретов-то нет... хоть 64-битный. Только тогда там же надо размещать загрузку чего-то еще, и переход в PM, и минимальные драйвера для продолжения работы с диском, и ... Где-то поблизости и недавно была тема похожая, с мудрым советом "не надо впихивать невпихуемое". Пусть МБР делает свою часть - читает в память некий лоадер и передает ему управление. Лоадер может быть бОльшего размера, не ограничен в 1-2 сектора. Впихнуть в МБР инициализацию защищенного режима, драйвер диска, обработчики аппаратных прерываний и исключений - не буду говорить "невозможно", хз, Левши имеются, и блоху подкуют. Но не нужно - и сложно - и при этом чем-то придется пожертвовать (например, проверками на успех дисковых операций, или совместимостью с железом).
     
  14. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    "32-разрядные инструкции" можешь, но компилируй под use16.
     
  15. Novishok

    Novishok New Member

    Публикаций:
    0
    Регистрация:
    18 мар 2012
    Сообщения:
    5
    [modnote=TermoSINteZ]Вам предупреждение , за дублирование сообщения в разных ветках форума[/modnote]