Воскресенье, 19.05.2024, 06:33
Приветствую Вас Гость | RSS
Главная | | Регистрация | Вход
Меню сайта
Форма входа
Поиск
Календарь
«  Февраль 2012  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
272829
Архив записей
Наш опрос
Оцените мой сайт
Всего ответов: 20
Мини-чат
Друзья сайта
  • Заказ Художник
  • Рыбалка
  • Новости
  • Наш университет io-96
  • Железо и другие
  • Наш Counter-Strike
  • Google ot Turbokherson
  • Google ot Turbokherson87
  • Android
  • Программы и Софт
  • Программирование
  • Лечение здоровья
  • О Ремонт компьютер
  • Наш сайт Turbokherson
  • Программирование ICQ 378204653 от Turbokherson
    Главная » 2012 » Февраль » 20 » MBR для флешки своими руками или как сделать из одного устройства три
    13:51
    MBR для флешки своими руками или как сделать из одного устройства три
    Мое почтение читающему!
    Топик мог бы получиться просто катастрофически огромным, поэтому перейдем сразу к делу. Впереди вас ждет рассказ, о том, как можно одну флешку сделать одновременно загрузочной как для ОС семейства Windows, так и *nix, а также сделать из нее live-usb. Заранее прошу прощения за жаргон, не сторонник, но так короче.

    Аннотация


    Как-то пришлось много раз подряд устанавливать на одну и ту же машину кучу разных операционных систем, как от товарищей господ из Майкрософт, так и любимых всеми нами *nix`ов. При этом инсталляторы вновь устанавливаемых ОСей периодически терли загрузчики ранее установленных, так что приходилось их восстанавливать вручную, загружаясь с live-usb. Но самое ужасное, что при всем при этом под рукой была всего одна флешка (и еще 15 компьютеров правда, но толку от них было мало, так как разбирать их по причинам гарантии в надежде на лишний жесткий диск было нельзя). Флешка к счастью была большого объема. Вот тут-то и возникла идея сделать из одной флешки две, а лучше три (хотя можно и 4) разных девайса.

    Немного теории


    Как сделать из одной флешки несколько с целью последующей установки на нее одновременно нескольких установщиков ОС и еще live-операционки? Ответ очевиден — сделать на флешке несколько разделов!

    Покопавшись в интернете глубинах подсознания вспомнил из институтского курса, что информация о разделах хранится в первом секторе диска флешки, называющемся Master Boot Table (MBR), а точнее в отдельной его части, называемой partitions. Находится эта часть по смещению 0x01BE и представляет собой 4 поля по 16 байт, каждое из которых представляет собой запись об отдельном разделе. При этом в принципе возможно на одном устройстве иметь и большее количество разделов, но это сложнее и нам для флешки хватит и четырех.

    Инструментарий

    В форточных ОС существует неприятное ограничение на количество разделов флешки. Оно не должно превышать 1. Точнее разделов может быть сколько угодно, но ОСь будет видеть только первую из записей в partitions. Собственно это и определило выбор средств для форматирования флешки. Будем работать с линуксовым fdisk`ом!

    Сам загрузчик будем писать на FASM`е, так как для программирования кода, выполняющегося вне ОС он наиболее удобен на мой взгляд.

    Работать с флешкой в виде блочного устройства можно с помощью ужасной destroy data (dd), но раз уж тут выходит такая мешанина операционок, то воспользуемся более дружественной оконной DMDE.

    Краткое лирическое отступление
    На самом деле особенность работы ОС семейства Windows с флешками позволяет используя предлагаемую мной технологию абсолютно безболезненно по отношению к дальнейшему использованию флешки в качестве ординарного накопителя данных. Отрезав от имеющихся у меня в наличии 16 GB парочку в конце, я стал обладателем 14-гиговой флешки, работающей с точки зрения винды как и прежде (т. е. другие разделы были не видны), но при этом при попытке загрузки с нее из BIOS позволяющей устанавливать ОСи из двух гигабайтных разделов, созданных в конце.

    Зубофлешко-дробильный аппарат

    Начнем с самого простого, разметим файловую систему на нашей флешке. В частности я использовал флешку Transcend JetFlash 16 GB (была получена в качестве подарка, а дареному коню как известно… Хотя нареканий в ее адрес у меня за 1,5 года использования нет). Как я уже говорил, пользоваться будем линуксовым fdisk`ом (под рукой оказалась старенькая виртуальная машина Ubuntu 9).

    Итак, монтируем флешку (так как сидим под X-ми, то просто втыкаем ее в порт). Получаем устройство /dev/sdb.

    Запускаем fdisk, натравив его на новое устройство:
    root@kubuntu:/# fdisk /dev/sdb

    Имеем выхлоп:
    The number of cylinders for this disk is set to 1953.
    There is nothing wrong with that, but this is larger than 1024,
    and could in certain setups cause problems with:
    1) software that runs at boot time (e.g., old versions of LILO)
    2) booting and partitioning software from other OSs
     (e.g., DOS FDISK, OS/2 FDISK)
    
    Command (m for help): m
    Command action
     a toggle a bootable flag
     b edit bsd disklabel
     c toggle the dos compatibility flag
     d delete a partition
     l list known partition types
     m print this menu
     n add a new partition
     o create a new empty DOS partition table
     p print the partition table
     q quit without saving changes
     s create a new empty Sun disklabel
     t change a partition's system id
     u change display/entry units
     v verify the partition table
     w write table to disk and exit
     x extra functionality (experts only)

    Считаем, что диск чистый и не содержит ни одного раздела. В противном случае командой d исправляем этот недостаток (не забыв скопировать нужные данные заранее).

    Задача проста — создать три раздела. Разделы будем создавать основные (primary), чтобы вся информация о них хранилась в partitions MBR`а. Воспользуемся командой n.
    Первый раздел самый большой (14 ГБ), так как его потом будет видеть Windows, и его будем использовать в качестве обычной флешки:
    Command (m for help): n
    Command action
     e extended
     p primary partition (1-4)
    p
    Partition number (1-4): 1
    First cylinder (1-15320, default 1): 1
    Last cylinder or +size or +sizeM or +sizeK (1-15320, default 15320): +14336M

    Второй и третий по гигабайту:
    Command (m for help): n
    Command action
     e extended
     p primary partition (1-4)
    p
    Partition number (1-4): 2
    First cylinder (13674-15320, default 13674):
    Using default value 13674
    Last cylinder or +size or +sizeM or +sizeK (13674-15320, default 15320): +1024M
    
    Command (m for help): n
    Command action
     e extended
     p primary partition (1-4)
    p
    Partition number (1-4): 3
    First cylinder (14652-15320, default 14652):
    Using default value 14652
    Last cylinder or +size or +sizeM or +sizeK (14652-15320, default 15320):
    Using default value 15320

    Проверим полученные результаты, распечатав сформированную таблицу разделов командой p:
    Command (m for help): p
    
    Disk /dev/sdb: 16.0 GB, 16064184320 bytes
    64 heads, 32 sectors/track, 15320 cylinders
    Units = cylinders of 2048 * 512 = 1048576 bytes
    Disk identifier: 0x0dee0000
    
     Device Boot Start End Blocks Id System
    /dev/sdb1 1 13673 14001136 83 Linux
    /dev/sdb2 13674 14651 1001472 83 Linux
    /dev/sdb3 14652 15320 685056 83 Linux

    Как видим имеем три раздела: 14 ГБ, 1ГБ и остатки (чуть меньше гига). Остается сохранить полученные изменения командой w:
    Command (m for help): w
    The partition table has been altered!
    
    Calling ioctl() to re-read partition table.
    Syncing disks.
    root@kubuntu:/#

    Отключаем флешку от виртуальной машины и моментально лицезреем всплывающее окошко следующего вида:



    Видно, что флешка стала восприниматься Windows, как устройство значительно меньшего размера. Что ж, форматируем! Получаем первый раздел, готовый к использованию. Но что делать с двумя другими? Первое, не факт, что самое умное (но главное, что рабочее!), что пришло на ум — это обмануть старушку Windows и поменять местами записи в таблице разделов.

    Итак, воспользуемся программой DMDE, откроем флешку, как блочное устройство и покопаемся в байтиках загрузочного сектора.



    Выбрали подходящее по размеру устройство.



    Открыли его и первое, что видим — это таблицу разделов, разбитую по полям. Не устраивает, лезем к сырым байтам. Нажимаем F2 и видим содержимое MBR. Помним, что partitions (записи о разделах) хранятся с 446 байта.



    Красным выделена запись о первом разделе. Далее делаем ход конем! Сохраняем все три записи куда-нибудь в блокнотик, а на место первой записи записываем вторую (crtl+e, записываем, ctrl+w сохраняем). Закрываем DMDE, перетыкаем флешку и… бинго! Видим следующее окошко:



    Windows на этот раз увидела второй раздел в гигтар размером. Потираем руки и форматируем.

    Как не сложно догадаться, далее стоит на место первого записать третий, а на место второго скопировать с первого. Снова отформатировать и вернуть полученную запись на третью позицию (не забываем, что записи 16 байт, а при форматировании меняется байт идентификатора файловой системы). На последнем шаге возвращаем из блокнотика на место первую запись. В результате, если подмонтировать такую флешку к Ubuntu, получим три разных раздела, а в случае Windows — только один — первый.

    Способом, аналогичным способу форматирования разделов, на флешку легко устанавливаются всевозможные операционки. Я на свою установил следующие:
    • Раздел 1 (14 ГБ) — установщик Windows 7 (+ также используется как обычная флешка)
    • Раздел 2 (1 ГБ) — live-usb Windows (bartPE)
    • Раздел 3 — live-usb Linux (backtrack)
    А где же код?

    Что дальше? Имеем прекрасную флешку с тремя операционками и… огромным минусом! Чтобы после загрузки BIOS компьютер начинал грузиться с флешки, один из ее разделов должен быть активным (значение первого байта в записи partitions 0x01). Легко, скажите вы, воспользуемся все той же любимой DMDE. Возможно, но тут сталкиваемся с очередной проблемой — что, если мы часто меняем мнение по поводу того, с какого раздела флешки грузиться? Не редактировать же каждый раз таблицу разделов из DMDE вручную. Конечно нет, автоматизируем этот процесс!

    Еще немного теории

    Из чего состоит MBR? MBR — это загрузчик + запись таблицы разделов. После того, как микропрограмма BIOS проверит компьютер (POST), она производит копирование первого сектора диска, с которого предполагается проводить загрузку операционной системы в память по адресу 0x7С00 (процессор работает в реальном режиме адресов) и передает туда управление. Далее кодом загрузчика MBR (все, что до 446го байта) осуществляется проверка готовности диска, проверка записей таблицы разделов (активной должна быть только одна!) и выбор активного раздела с последующей передачей управления загрузчику ОС.

    Что сделаем мы

    Чтобы избавиться ограничения на количество одновременных активных разделов на диске подменим код загрузчика из MBR своим собственным, который будет проверять записи, находить отмеченные как активные и ждать от пользователя нажатия клавиши с цифрой, соответствующей номеру раздела, с которого стоит производить загрузку.

    Как я уже говорил, код будем писать на FASM (а отладка осуществлялась в Bochs). Далее представлен листинг без особых пояснений, иначе топик никогда не закончится. Хотелось бы только отметить, что так сложилось, что это моя первая программа на ассемблере, поэтому не судите строго. Что делает код было описано выше.
    ;регистр dl cодержит номер загрузочного диска!
    
    use16
    ;======== Копируем самого себя по адресу 0000:0600h ===================
     mov ax, 7C0h
     mov ds, ax
     xor si, si
    
     mov ax, 60h
     mov es, ax
     xor di, di
    
     mov cx, 0FFhcx лежит число повторений функции копирования слов
    
     ;[DS:SI] => [ES:DI]; SI += 2; DI += 2;
     rep movsw
    
     ;Передаем управление на новое расположение кода
     jmp 0000:0618h
    
    ;======== Приветствуем пользователя ===================================
     mov ax, hello_msg_1
     call print
     mov ax, hello_msg_2
     call print
    
    ;======== Проверяем таблицу разделов ===================================
     mov si, [part_adr]
     mov bh, 80h
    
     mov cl, -1
    partitions_chek:
     cmp cl, 3 ;если уже было проверено 4 записи, выходим из цикла и переходим к обработке записей
     je partition_select
    
     add si, 10h
     inc cl
    
     mov bl, [es:si]
     cmp bl, bh
     jne partitions_chek ;запись не является загрузочной
    
     call partitions_process ;запись загрузочная!
     ;[es:si] содержит адрес записи в таблице разделов
     ;cl - номер раздела
    
     jmp partitions_chek
    
    ;======== Подпрограмма вывода инофрмации об активном разделе =============================
    partitions_process:
     mov ax, boot_part_msg
     call print
    
     mov di, part_num
     add [ds:di], cl
     mov ax, part_num
     call print
     sub [ds:di], cl
    
     mov di, boot_flags
     mov ch, 0
     add di, cx
     mov byte[ds:di], 1
    
     ret;
    ;=======================================================================
    
    partition_select:
     ;Обрабатываем пользовательский ввод
     mov ax, select_part_msg
     call print
    
    choise: mov di, boot_flags
     mov si, [part_adr]
    
     mov ah, 0
     int 16h
    
    p0: cmp al, 48
     jne p1
     add si, 10h
     jmp disk
    
    p1: cmp al, 49
     jne p2
     add si, 20h
     jmp disk
    
    p2: cmp al, 50
     jne p3
     add si, 30h
     jmp disk
    
    p3: add si, 40h
     cmp al, 51
     je disk
    
    wrong_choise:
     mov ax, wrong_input_msg
     call print
     jmp choise
    
    disk: mov ah, 0
     sub al, 48 ; сначала проверка, выбрал ли пользователь действительно загрузочный раздел
     add di, ax
     cmp byte [ds:di], 0
     je wrong_choise
     ; по [es:si] содержится запись таблицы разделов
     ; о выбранном загрузочном диске
    
     mov ah, 41h ; проверка поддержки диском расширенного режима (> 8 GB)
     ; dl содержит номер диска
     mov bx, 55AAh
     int 13h
     jc ext_not_present_error
     shr cx, 1
     jnb ext_not_present_error
     cmp bx, 0AA55h
     je read_boot_sect
    
    ext_not_present_error:
     mov ax, ext_not_pres_msg
     call print
     int 18h
    
    read_boot_sect:
     mov ah, 42h
     mov di, DAP_structure
     add di, 8
     add si, 8
     mov ebx, [ds:si]
     mov [ds:di], ebx
     mov si, DAP_structure
     int 13h
     jc ext_not_present_error
    
     jmp 0000:7C00h
    ;======== Подпрограмма вывода сообщений ================================
    print:
     push si
     push bx
    
     mov bx, ax
     xor si, si
     mov ah, 0Eh
    
    p: mov al, [bx + si]
     cmp al, 0Ah
     int 10h
    
     je end_print
    
     inc si
     jmp p
    
    end_print:
     pop bx
     pop si
     ret
    
    ;=======================================================================
    hello_msg_1 db '************************', 0Dh, 0Ah
    hello_msg_2 db '*WELL`s LOADER © 2011*', 0Dh, 0Ah
    boot_part_msg db 'Find bootable partitions:', 0Dh, 0Ah
    select_part_msg db 'Select part to boot from (press 0 ... 3)', 0Dh, 0Ah
    wrong_input_msg db 'Wrong choise. Try again', 0Dh, 0Ah
    ext_not_pres_msg db 'a disk read error occured', 0Dh, 0Ah
    part_num db '0', 0Dh, 0Ah
    part_adr dw 1AEh
    boot_flags db 4 dup (0)
    DAP_structure db 10h, 0, 1, 0, 0, 7Ch, 0, 0, 8 dup (0)

    Как видно, программа загрузчика представляет из себя чистый бинарник без всяких точек входа, секций и прочей сложноты. Режим работы процессора — реальный (16-разрядный).
    Чтобы использовать этот загрузчик, его необходимо залить на флешку в первый сектор (с помощью DMDE, например), при этом сохранив нетронутой таблицу разделов. Размер скомпилированного бинарного файла 442 байта.

    Перспективы


    Если такое решение станет пользоваться популярностью, то функциональность загрузчика легко можно расширить например добавив вывод информации о разделах на экран в процессе выбора. Для удобства залилтия загрузчика на флешку и выбора, какие из разделов будут активными можно написать небольшой инструмент. В общем ваши пожелания и предложения принимаются в комментариях.

    Скачать исходный код и бинарник загрузчика можно отсюда.
    Просмотров: 8740 | Добавил: Turbokherson | Рейтинг: 0.0/0
    Всего комментариев: 0
    Имя *:
    Email *:
    Код *:
    Создать бесплатный сайт с uCozCopyright MyCorp © 2024