OS/OS from Scratch
[OS] 10. 32 bit Enter
jschang
2021. 6. 23. 00:55
서론
이번 강의에서는 32bit protected mode로 진입해 이전 강의에서 만든 코드를 실행해보겠습니다. 해당 Github 강의는 다음과 같습니다.
https://github.com/cfenollosa/os-tutorial/tree/master/10-32bit-enter
cfenollosa/os-tutorial
How to create an OS from scratch. Contribute to cfenollosa/os-tutorial development by creating an account on GitHub.
github.com
이론
Pipelining
이 블로그에서 Pipelining에 대해 알기 쉽게 설명해 놓았습니다. Pipelining은 하나의 명령어가 실행되는 도중 동시에 다른 명령어를 시작하는 방식으로 동시에 여러개의 명령어를 실행해 처리량을 올리는 것입니다.
32 bit mode로 진입하는 순서
32bit 모드로 진입하는 순서는 다음과 같습니다.
- Interrupt 비활성화
- GDT Load
- CPU의 control 레지스터 cr0에 값 설정
- CPU Pipeline Flush
- Segment 레지스터 값 설정
- Stack 설정
- 32 bit 코드의 Label 실행
코드
32bit_switch.asm
32bit_switch.asm 코드는 위 32bit 모드로 진입하는 순서에 따른 코드입니다.
[bits 16]
switch_to_pm:
; 1. Diasble Interrupt
cli
; 2. Load GDT Descriptor
lgdt [gdt_descriptor]
; 3. cr0 레지스터를 32bit 모드로 설정
mov eax, cr0
or eax, 0x1
mov cr0, eax
; 4. far jump로 pipeline flush
jmp CODE_SEG:init_pm
[bits 32]
init_pm:
; 5. Segment 레지스터 설정
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
; 6. Stack 설정
mov ebp, 0x90000
mov esp, ebp
; 7. 32bit 모드의 Label 호출
call BEGIN_OM
32bit_main.asm
32bit_main.asm은 boot loader와 32bit 모드로 진입하는 main코드가 작성되어 있습니다.
; Boot Loader offset
[org 0x7c00]
; Stack 설정
mov bp, 0x90000
mov sp, bp
mov bx, MSG_REAL_MODE
call print
call switch_to_pm
%include 'boot_sect_print_function.asm'
%include '32bit_gdt.asm'
%include '32bit_print.asm'
%include '32bit_switch.asm'
[bits 32]
BEGIN_PM:
mov ebx, MSG_PROT_MODE
call print_string_pm
jmp $
MSG_PROT_MODE db 'Loaded 32-bit protected mode', 0x00
MSG_REAL_MODE db 'Started in 16-bit real mode', 0x00
; boot sector
times 510-($-$$)
dw 0xaa55
실행 결과
WSL에서는 GUI환경을 지원하지 않으므로 실행을 위해서는 windows에서 qemu를 실행시키거나 Linux 가상머신에서 실행해야 합니다. Ubuntu에서 실행한 결과는 다음과 같습니다.