Rambler's
Top100

Переход в защищенный режим

Автор: lonesome TSH/Digital Daemons
Дата: .01.2003
Раздел: Разработка ОС

Ниже приведен пример программы (вторичного загрузчика), выполняющей инициализацию GDT и переход в защищенный режим. Вторичный загрузчик предполагает, что он был загружен с дискеты при помощи первичного загрузчика

BITS16 
 
ORG 0x7E00	;Вторичный загрузчик  
		;исполняется по адресу 0x7E00 
 
section .text  
_entry: 
 
cli	;Отключение прерываний 
 
	;Установка базового вектора прерывания в 0x20: 
mov al,00010001b 
out 0x20,al 
mov al,0x20 
out 0x21,al 
mov al,00000100b 
out 0x21,al 
	;ручной EOI:
mov al,00000001b 
out 0x21,al 
 
	;Включение адресной линии A20: 
in al, 0x92
or al, 2
out 0x92, al
 
	;Загрузка глобальной таблицы дескрипторов (GDT): 
lgdt [gd_reg] 
 
	;Обнуление регистра флагов: 
push byte 2 
popf 
 
	;Включение защищенного режима (бит PE в регистре CR0): 
mov eax, cr0 
or al, 1 
mov cr0, eax 
 
	 ;Загрузка селектора сегмента кода в CS путем длинного прыжка 
	 ;в 32-битный сегмент 
	  
 
jmp 16:_protected 
;=======================================================; 
BITS 32 
_protected: 
;Этот код исполняется в защищенном режиме 
 
 
;Загрузка сегментных регистров нужными селекторами: 
mov ax, 1000b 
mov es, ax 
mov ds, ax 
mov ss, ax 
 
 
 
 
mov [$], byte 0 
 
mov [0xB8000], byte 'S' 
 
xor eax, eax 
xor ecx, ecx 
 
;===========================================; 
 
;Копирование ядра по адресу 0x200000 (2 мб): 
mov ecx, _kernel 
mov eax, 0x200000 
 
.loop: 
mov bl, [ecx] 
mov [ecx], byte 0 
mov [eax], bl 
inc ecx 
inc eax 
cmp ecx, _kernel+0x10000 
jl .loop 
 
;===========================================; 
 
jmp 16:0x200000	;Переход на ядро 
 
 
;===============================================; 
BITS 16 
 
gd_table:	;Глобальная таблица дескрипторов 
dw 0xFFFF,0x0000,0x9200,0x00CF	;Дескриптор данных 
dw 0xFFFF,0x0000,0x9A00,0x00CF	;Дескриптор кода 
db 0x67, 0,0,0,0 ,10001001b, 01000000b, 0   ;сегмент состояния задачи 
 
gd_reg: 
dw 255	;Лимит GDT 
dd gd_table-8	;Линейный адрес GDT 
 
 
BITS32 
 
TIMES 0x1000-($-$$) db 0 ;Размер вторичного загрузчика - 0x1000 байт 
_kernel:	 
 
incbin 'kernel.bin'	 ;Вставка бинарника ядра 
 
TIMES 20000-($-$$) db 0 



Rambler's Top100