Search

EntryPoint

대분류
CS
소분류
OS
유형
기초
C
최종 편집 일시
2024/10/27 15:50
생성 일시
2022/04/08 05:44
15 more properties

Kernel32/Source/EntryPoint.s

[ORG 0x00] ; 코드의 시작 어드레스를 0x00으로 설정 [BITS 16] ; 이하 코드는 16비트 코드로 설정 SECTION .text ; text 섹션(세그먼트)을 정의 ;;;;;;;;;;; ; 코드 영역 ; ;;;;;;;;;;; START: mov ax, 0x1000 ; 보호모드 엔트리 포인트의 시작 어드레스(0x10000); 세그먼트 레지스터 값으로 변환 mov ds, ax ; ds에 설정 mov es, ax ; es에 설정 cli ; 인터럽트 발생 못하게 lgdt [ GDTR ] ; gdtr 자료구조를 프로세서에 설정하여 gdt 테이블을 로드 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 보호 모드로 진입 ; ; Disable Pagin, Disable Cache, Internal FPU, ; ; Disable Align Check, Enable ProtectedMode ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov eax, 0x4000003B ; PG=0, NW=0, AM=0, WP=0, NE=1, ET=1, TS=1, EM=0, MP=1, PE=1 mov cr0, eax ; cr0에 위에서 저장한 플래그를 설정하여 보호모드로 전환 ; 커널 코드 세그먼트를 0x00을 기준으로 하는 것으로 교체하고 EIP의 값을 0x00을 기준으로 재설정 ; cs 세그먼트 셀렉터 : EIP jmp dword 0x08: ( PROTECTEDMODE - $$ + 0X10000 ) ;;;;;;;;;;;;;;; ; 보호모드로 진입 ; ;;;;;;;;;;;;;;; [BITS 32] ; 이하 코드는 32비트 코드로 설정 PROTECTEDMODE: mov ax, 0x10 ; 보호모드 커널용 데이터 세그먼트 디스크립터를 ax에 저장 mov ds, ax mov es, ax mov fs, ax mov gs, ax ; 스택을 0x00000000 ~ 0x0000FFFF영역에 64kb크기로 생성 mov ss, ax mov esp, 0xFFFE ; esp addr = 0xfffe mov ebp, 0xFFFE ; ebp addr = 0xfffe ; 화면에 보호모드로 전환되었다는 메시지를 찍는다. push ( SWITCHSUCCESSMESSAGE - $$ + 0X10000 ) ; 출력할 메시지의 어드레스를 스택에 삽입 push 2 ; 화면 y 좌표(2)를 스택에 삽입 push 0 ; 화면 x 좌표(0)를 스택에 삽입 call PRINTMESSAGE ; PRINTMESSAGE 함수 호출 add esp, 12 ; 삽입한 파라미터 제거 jmp $ ; 현재 위치에서 무한루프 수행 ;;;;;;;;;;;;;;; ; 함수 코드 영역 ; ;;;;;;;;;;;;;;; ; 메시지를 출력하는 함수 ; 스택에 x좌표, y좌표, 문자열 PRINTMESSAGE: push ebp ; bp를 스택에 삽입 mov ebp, esp ; bp에 sp 저장 ; 함수에서 임시로 사용하는 레지스터들로 함수의 마지막 부분에서 스택에 삽입된 값을 꺼내 원래 값으로 복원 push esi push edi push eax push ecx push edx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; x,y의 좌표로 비디오 메모리의 어드레스를 계산함 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; y 좌표를 이용해서 먼저 라인 어드레스를 구함 mov eax, dword [ ebp +12 ] ; 파라미터 2(화면 좌표 y)를 eax에 설정 mov esi, 160 ; 한라인의 바이트 수(2*80컬럼)를 esi에 설정 mul esi ; eax와 esi를 곱하여 화면 y addr 계산 mov edi, eax ; 계산된 화면 y addr를 edi에 설정 ; x좌표를 이용해서 2를 곱한 후 최종 addr구함 mov eax, dword [ ebp +8 ] ; 파라미터 1(화면 좌표 x)를 eax에 설정 mov esi, 2 ; 한 문자를 나타내는 바이트 수(2)를 esi에 설정 mul esi ; eax와 esi를 곱하여 화면 x addr를 계산 add edi, eax ; 화면 y addr와 계산된 x addr를 더해서 실제 비디오 메모리 어드레스를 계산 ; 출력할 문자열의 어드레스 mov esi, dword [ ebp + 16 ] ; 파라미터 3(출력할 문자열의 어드레스) .MESSAGELOOP: ; 메세지를 출력하는 루프 mov cl, byte [ esi ] ; esi가 가리키는 문자열 위치에서 한문자를 cl에 복사 ; cl은 ecx의 하위 1바이트를 의미 ; 문자열은 1바이트면 충분하므로 ecx의 하위 1바이트만 사용 cmp cl, 0 ; 복사된 문자와 0을 비교 je .MESSAGEEND ; 복사된 문자의 값이 0이면 문자열이 종료되었음을 의미하므로 ; .MESSAGEEND로 이동하여 문자 출력 종료 mov byte [ edi +0xB8000 ], cl ; 0이 아니라면 비디오 메모리 addr ; 0xB8000 + edi에 문자를 출력 add esi, 1 ; 다음 문자열로 이동 add edi, 2 ; 비디오 메모리의 다음 문자 위치로 이동 ; 비디오 메모리는 (문자, 속성) 형식이므로 문자만 출력하려면 2를 더해야 함 jmp .MESSAGELOOP ; 메시지 출력 루프로 이동하여 다음 문자를 출력 .MESSAGEEND: ; 함수 사용이 끝나면 스택 복원 pop edx pop ecx pop eax pop edi pop esi pop ebp ; bp 복원 ret ;;;;;;;;;;;; ; 데이터 영역 ; ;;;;;;;;;;;; ; 아래의 데이터들을 8바이트에 맞춰 정렬하기 위해 추가 align 8, db 0 ; GDTR의 끝을 8byte로 정렬하기 위해 추가 dw 0x0000 ; GDTR 자료구조 정의 GDTR: dw GDTEND - GDT - 1 ; 아래에 위치하는 gdt테이블의 전체 크기 \ dd ( GDT - $$ + 0x10000 ) ; 아래에 위치하는 gdt테이블의 시작 addr ;GDT 테이블 정의 GDT: ; null디스크립터, 반드시 0으로 초기화해야 함 NULLDescriptor: dw 0x0000 dw 0x0000 db 0x00 db 0x00 db 0x00 db 0x00 ; 보호 모드 커널용 코드 세그먼트 디스크립터 CODEDESCRIPTOR: dw 0xFFFF ; Limit [15:0] dw 0x0000 ; Base [15:0] db 0x00 ; Base [23:16] db 0x9A ; P=1, DPL=0, code segment, Execute/Read db 0xCF ; G=1, D=1, L=0, Limit[19:16] db 0x00 ; Base [31:24] ; 보호모드 커널용 데이터 세그먼트 디스크립터 DATADESCRIPTOR: dw 0xFFFF ; limit [15:0] dw 0x0000 ; base [15:0] db 0x00 ; base [23:16] db 0x92 ; P=1, DPL=0, data segment, read/write db 0xCF ; G=1, D=1, L=0, limit[19:16] db 0x00 ; base [31:24] GDTEND: ; GTD 테이블 종료 ; 보호모드로 전환되었다는 메시지 SWITCHSUCCESSMESSAGE: db 'Switch To Protected Mode Success!', 0 times 512 - ( $ - $$ ) db 0x00 ; 512바이트를 맞추기 위해 남은 부분을 0으로 채움
C
복사
root/makefile
all: BootLoader Kernel32 Disk.img BootLoader: @echo @echo ============== Build Boot Loader ============== @echo make -C 00.BootLoader @echo @echo ============== Build Complete ============== @echo Kernel32: @echo @echo ============== Build 32Bit Kernel ============== @echo make -C 01.Kernel32 @echo @echo ============== Build Complete ============== @echo Disk.img: 00.BootLoader/BootLoader.bin 01.Kernel32/Kernel32.bin @echo @echo ============== Disk Image Build Start ============== @echo cat $^ > Disk.img @echo @echo ============== All Build Complete ============== @echo clean: make -C 00.BootLoader clean make -C 01.Kernel32 clean rm -f Disk.img
C
복사
Kernel32/makefile
all: Kernel32.bin Kernel32.bin: Source/EntryPoint.s nasm -o Kernel32.bin $< clean: rm -f Kernel32.bin
C
복사