본문 바로가기

Security/Kernel & OS

[Operation System] 6. OS 만들기 - Kernel Load - 1

1. Pre..

이번 시간에는 커널을 로드해 볼 겁니다.

 

2. Process

- boot 프로그램 만들기

- kernel 프로그램 만들기

- 두개를 .img 파일로 합치기 : copy /b boot.bin + kernel.bin os.img

- 플로피 디스크로 부팅

 

 

3. Code

- boot.asm

[org 0]
            jmp 07C0h:start    

start:
           
            mov ax, cs
            mov ds, ax
            mov es, ax
 
            mov ax, 0xB800      
     mov es, ax      
     mov di, 0  
     mov ax, word [msgBack]  
     mov cx, 0x7FF        
paint:
     mov word [es:di], ax
     add di,2  
     dec cx     
     jnz paint     
     

    read:
            mov ax, 0x1000      ; es:bx = 0x1000:1000
            mov es, ax          ;
            mov bx, 0           ; 0x10000 번지에 커널 로드

            mov ah, 2           ; 디스크에 있는 데이터 es:bx 의 주소로
            mov al, 1           ;  1 섹터를 읽을거임
            mov ch, 0           ; 0번째 실린더
            mov cl, 2           ; 2번째 섹터부터 읽기 시작.
            mov dh, 0           ; head = 0
            mov dl, 0           ; drive = 0 A 드라이브
            int 0x13            ; 읽기 인터럽트

            jc read             ; 에러 날 경우 ; 다시하셈

      jmp 0x1000:0000     ; kernel.bin 이 있는데로 ㄱㄱ

     msgBack db '.', 0x67

     times 510-($-$$) db 0
            dw 0AA55h
 

- kernel.asm

[org 0]
[bits 16]

start: 
 mov ax,cs    ; CS 에는 0x1000 이 들어 있다.
 mov ds,ax
 xor ax,ax
 mov ss,ax

 lea esi, [msgKernel] ; 문자열 있는 곳 주소 esi 에 넣기
 mov ax, 0xB800
 mov es, ax  
 mov edi, 0   ; 화면의 제일 처음 부분 부터 시작할 것이다.
 call printf
 jmp $

printf:
 push eax 

printf_loop:
 mov al, byte [esi] ; esi 가 가리키는 주소(msgKernel)에서 문자 하나씩 가져오기
 mov byte [es:edi], al ; 문자를 화면에 뿌리기
 or al, al  ; 0인지 체크
 jz printf_end  ; 0이면 print_end 로 ㄱㄱ
 inc edi 
 mov byte [es:edi], 0x03
 inc esi   ; 다음 문자를 꺼내기 위해 esi 를 하나 증가시킨다.
 inc edi   ; 화면에 다음 문자를 나타내기 위해 edi를 증가시킨다.
 jmp printf_loop 

printf_end:
 pop eax  
 ret 
 
msgKernel db "Kernel jam!", 0

 

 

 

 

4. Run