Создание загрузочного сектора

21.08.2011

При загрузке компьютера BIOS считывает первый сектор дискового накопителя (жесткий/гибкий диск/DVD/CDROM) (MBR) в оперативную память по адресу 0000:7С00h и передает туда управление. Затем уже загрузчик передает управление операционной системе. Чтобы BIOS мог идентифицировать программу начальной загрузки, она в конце должна содержать ключ 55h 0aah.

Начальный загрузчик может выглядеть примерно так (для создания исполняемого файла воспользуемся MASMом и скомпилируем com-файл)

;===================== Загрузочный сектор. Евгений Попов, 2011===================== 
;==================================================================================

.model tiny ;для того чтобы masm скомпилировал односегментную программу не более 512 байт
CSEG segment
assume CS:CSEG

org 7c00h 	;BIOS производит чтение 512 байт первого сектора MBR в ОЗУ по адресу 0x00007C00 
			;(0x07C0:0x0000 в формате реального режима), затем прочитанному коду передаётся управление
start:
		cli ;запрещаем прерывания
        xor ax,ax	;обнуляем регистр ах
        mov ds,ax	;настраиваем сегмент данных на нулевой адрес
        mov es,ax	;настраиваем сегмент es на нулевой адрес
        mov ss,ax	;настраиваем сегмент стека на нулевой адрес
        mov sp,07C00h	;сегмент sp указывает на текущую вершину стека
        sti	;разрешаем прерывания
        
        ;очищаем экран
        mov al, 02h
  		mov ah, 00h
  		int 10h
        
        call GetCursorPos	;получаем позицию курсора
                                
        mov bp, offset msg             ; Загрузка
        mov cx, 15
        call print					;Вывод на экран строки msg
        
        add dh,1	;переходим на одну строку ниже
        call SetCursorPos
        mov bp, offset Con             ; Загрузка
        mov cx, 23
        call print
        
        mov dx,1701h
        call SetCursorPos
        mov bp,offset Off
        mov cx,30
        call print
        
        mov bp, offset Copyright
        mov cx,30
        add dh,01h
        call SetCursorPos
        call print
                
        call Char_in 
                
        cmp al,'o'
        jz Turn_Off
        cmp al,'r'
        jz Restart
        ;cmp al, 0Dh ;Если нажимаем на Enter, то переходим к загрузке ядра
        ;jz Kernel   ;поскольку ядра нет, код оставлен на будущее
                
        jmp $
;===================== Подпрограммы ===================================
  print:                             ;в регистре  bp - строка, в регистре cx - длина этой строки
        mov bl,04h					;в регистре  bl- атрибут
        mov ax,1301h
        int 10h
        ret
        ;----------------------------------
  GetCursorPos:	;получаем текущее значение курсора функиция 3h прерывания 10h
        				; в bh страница
        mov ah,3h
        xor bh,bh
        int 10h
        ret
        ;----------------------------------
  SetCursorPos:        ;установка курсора : функция 02h прерывания 10h
        mov ah,2h
        xor bh,bh
        int 10h 
        ret
      ;----------------------------------
  Char_in:              ;ожидание нажатой клавиши : функция 10h прерывания 16h
         mov ah,10h
         int 16h
         ret
        ;----------------------------------
  Turn_Off:				;выключение компа
        mov ax,5301h 
        sub bx,bx 
        int 15h 
        jb stop 
        mov ax,530eh 
        sub bx,bx 
        int 15h 
        jb stop 
        mov ax,5307h 
        mov bx,0001h 
        mov cx,0003h 
        int 15h
   stop:
        ret
  Restart:
        jmp dword ptr reboot
            
        ;===================== выводимые сообщения===================== 
      	msg db Hello Eugene...',0     
        Off db   'r --restart       o --turn off',0
        Copyright db 'Copyright ',1,' Eugene Popov, 2011',0
        Con db 'Press Enter to Continue',0
        
        reboot dd 0ffff0000h ;переход по этому адресу будет вызывать перезагрузку
         
	;----------------------------------
codeend:
db 510-(codeend-start) dup (0)	;заполняем оставшуюся часть нулями
db 055h,0AAh ;сигнатура, символизирующая о завершении загрузочного сектора
CSEG ends
end start

Теперь выведем результат программы. Для этого воспользуемся эмулятором Bochs. Сначала нам надо создать конфигурационный файл для программы - в моем случае он выглядит так

# configuration file generated by Bochs
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, gameport=1, pci_ide=1, acpi=1, ioapic=1
config_interface: win32config
display_library: win32
memory: host=32, guest=10
romimage: file="C:\Program Files\Bochs-2.4.6/BIOS-bochs-latest"
vgaromimage: file="C:\Program Files\Bochs-2.4.6/VGABIOS-lgpl-latest"
boot: disk
floppy_bootsig_check: disabled=0
# no floppya
# no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, mode=flat, translation=auto, path="C:\Users\Eugene\NBOOT1.COM", cylinders=1, heads=1, spt=1, biosdetect=auto, model="Generic 1234"
ata0-slave: type=disk, mode=flat, translation=auto, path="C:\Users\Eugene\ASM\BOOT12.BIN", cylinders=20, heads=16, spt=63, biosdetect=auto, model="Generic 1234"
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata2: enabled=0
ata3: enabled=0
parport1: enabled=1, file=""
parport2: enabled=0
com1: enabled=1, mode=null, dev=""
com2: enabled=0
com3: enabled=0
com4: enabled=0
usb_uhci: enabled=0
usb_ohci: enabled=0
i440fxsupport: enabled=1
vga_update_interval: 50000
vga: extension=vbe
cpu: count=1, ips=4000000, reset_on_triple_fault=1, ignore_bad_msrs=1
cpuid: cpuid_limit_winnt=0, mmx=1, sse=sse2, xapic=1, sep=1, aes=0, xsave=0, movbe=0, 1g_pages=0, pcid=0 fsgsbase=0
cpuid: stepping=3, vendor_string="GenuineIntel", brand_string="              Intel(R) Pentium(R) 4 CPU        "
print_timestamps: enabled=0
port_e9_hack: enabled=0
text_snapshot_check: enabled=0
private_colormap: enabled=0
clock: sync=none, time0=local
# no cmosimage
ne2k: enabled=0
pnic: enabled=0
sb16: enabled=0
# no loader
log: -
logprefix: %t%e%d
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
pass: action=fatal
keyboard_type: mf
keyboard_serial_delay: 250
keyboard_paste_delay: 100000
keyboard_mapping: enabled=0, map=
user_shortcut: keys=none
mouse: enabled=0, type=ps2, toggle=ctrl+mbutton

В данном случае у меня файл программы загрузки - C:\Users\Eugene\NBOOT1.COM

В итоге получим следующую картинку

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850