§ Описание
Зачастую возникает желание создать свою ОС, но никак не знаешь, с чего начать? Так вот ответ простой — бутсектор! Если напишешь бутсектор, считай, половина ОС в твоем кармане. Ахаха! Поверил? А вот и нет. Это 0.01% от операционной системы.§ Исходный код
Код написан с использованием fasm.1 macro brk { xchg bx, bx } 2 org 7c00h 3 4 jmp short start 5 db 00h 6 7; ---------------------------------------------------------------------- 8; BPB: Bios Parameter Block 9; ---------------------------------------------------------------------- 10 db "FLOPPY12" ; 03 Signature 11 dw 200h ; 0B Байт в секторе 12 db 1 ; 0D Секторов на кластер 13 dw 1 ; 0E Количество зарезервированных секторов 14 db 2 ; 10 Количество FAT 15 dw 00E0h ; 11 Количество Root Entries (224) 16 dw 0B40h ; 13 Всего секторов 17 db 0F0h ; 15 Параметр media 18 dw 9 ; 16 Секторов в FAT 19 dw 12h ; 18 Секторов на дорожке (18) 20 dw 2 ; 1A Количество дорожек 21 dd 0 ; 1C Скрытых секторов (large mode) 22 dd 0 ; 20 Всего секторов (large mode) 23 db 0 ; 24 Номер физического девайса 24 db 1 ; 25 Флаги 25 db 29h ; 26 Расширенная сигнатура 26 dd 07E00000h ; 27 Серийный номер, но используется для ES:BX 27 db 'DEMO BIN' ; 2B Лейбл, используется для файла загрузки 28 db 'FAT12 ' ; 36 Тип файловой системы 29; ---------------------------------------------------------------------- 30 31start: 32 cli ; IF=0 33 cld ; DF=0 34 xor ax, ax ; Очистка DS: ES: SS: сегментов 35 mov ds, ax 36 mov es, ax 37 mov ss, ax 38 mov sp, 7c00h ; Установка стека 39 mov ax, 19 ; Сектор 19-й содержит первый сектор 40dir: les bx, [7c27h] ; root-каталога и он читается в $7E00 41 call ReadSector ; с диска, сектор задается через LBA (AX) 42 mov di, bx ; ES:DI - Начало записей в ROOT 43 mov bp, 16 ; 16 файлов в секторе из 512 байт 44item: mov si, 7c2bh ; DS:SI - Проверка имени формата 8.3 45 mov cx, 12 ; 11 + 1 - Сравниваем 11 символов (+1) 46 push di 47 repe cmpsb ; Сравнение строк 48 pop di 49 jcxz file_found ; Файл был найден, перейти к загрузке 50 add di, 32 ; Иначе искать следующую строку 51 dec bp 52 jne item ; Если просмотр в секторе закончился 53 inc ax ; Перейти к следующему сектору 54 sub word [7c11h], 16 ; Кол-во оставшихся записей 55 jne dir ; Сектора еще не закончились в ROOT? 56 int 18h ; Нет запускного файла 57 58; ---------------------------------------------------------------------- 59; Загрузка файла по адресу 8000h 60; ---------------------------------------------------------------------- 61 62file_found: 63 64 mov ax, [es: di + 1Ah] ; Номер кластера 65 mov [7c22h], word 800h ; Адрес, где начинатся программа 66 67next: push ax ; В AX содержится номер читаемого кластера 68 add ax, 31 ; 33-сектор находится DATA-секция 69 les bx, [7c20h] ; Область памяти, куда будет читать 70 call ReadSector 71 add [7c22h], word 20h ; +20h сегментов (32*16=512 байт) 72 pop ax ; Искать следующий кластер по текущему 73 mov bx, 3 ; Умножить на 3 полубайта (по 4 бита) 74 mul bx ; Поскольку FAT12 -- 12-битная 75 push ax 76 shr ax, 1 + 9 ; Найти номер сектора FAT 77 inc ax ; Пропуск +1 BPB 78 mov si, ax ; Сохранить номер этого сектора на потом 79 les bx, [7c27h] ; Скачать сюда ES:BX=07e0:0000 80 call ReadSector 81 pop ax ; Восстановить номер кластера 82 mov bp, ax ; Теперь он в BP 83 mov di, ax 84 shr di, 1 ; Найти кластер в загруженном секторе FAT 85 and di, 0x1FF ; Срезать лишние биты 86 mov ax, [es: di] ; Загрузка в AX указателя на следующий кластер 87 cmp di, 0x1FF ; Если не хватает данных (конец сектора FAT) 88 jne @f 89 push ax ; Сохраняем AX 90 xchg ax, si 91 inc ax ; Следующий сектор FAT 92 call ReadSector ; Читается в 7E00:0000 93 pop ax 94 mov ah, [es: bx] ; И дополняем AH (которого не хватало) 95@@: test bp, 1 ; Если младший бит кластера равен 0 96 jz @f ; То ничего не делать 97 shr ax, 4 ; Иначе, нечетные кластеры сдвинуть вправо на 4 бита 98@@: and ax, 0x0FFF ; Ограничить от 0 до 4095 99 cmp ax, 0x0FF0 ; Если следующий кластер < 4080 100 jb next ; Продолжить чтение, если так 101 jmp 0 : $8000 ; Иначе запускает программу 102 103; ---------------------------------------------------------------------- 104; AX - номер сектора от 0 до n, ES:BX указывает на данные 105; ---------------------------------------------------------------------- 106 107ReadSector: 108 109 push ax bx ; Сохранить AX, BX 110 mov cx, 12h ; 18 секторов на дорожку 111 cwd ; DX=0 112 div cx ; Разделить LBA на 18 113 xchg ax, cx ; Результат в CX 114 mov dh, cl ; Сохранить CL в DH 115 and dh, 1 ; В DH будет номер головки (0 или 1) 116 shr cx, 1 ; В CX будет номер цилиндра 117 xchg ch, cl ; В CL будет старший цилиндр, в CH младший 118 shr cl, 6 ; В старших 2-х битах старшие 2 бита цилиндра 119 inc dx ; Номер головки 1 или 2 120 or cl, dl ; Объединить биты [5:0] сектора и старшего цилиндра 121 mov dl, 0 ; Номер диска 00 - Floppy 122 mov ax, 0201h ; Чтение данных 123 int 13h ; ES:BX, параметры CHS в CX/DX 124 pop bx ax ; Восстановить AX, BX 125 ret 126 127; ---------------------------------------------------------------------- 128; Оставшееся пространство заполнить нулями 129; ---------------------------------------------------------------------- 130 131 times 7c00h + (512 - 2) - $ db 0x00 132 dw 0xAA55