$bash

0x04_BootLoader

0x0500 : 기술, 분석 문서/0x0503 : OS 원리와 구조

시작전에...가상머신에서 환경 구축해서 안되고..내꺼 맥북에서도 안되서 그냥 내용 숙달로 진행할 계획...


위 그림을 보면 BIOS 영역과 OS영역이 있는데 전에 배웠던 모드에 따라 진행되는 순서도라 생각하면 이해가 빠를꺼 같다..


BIOS 부팅 과정에서도 수많은 작업을 하지만 OS 내용을 공부할꺼기 때문에 ... 일단 이번에는 부트로더 탭을 공부할 것인데

그전에 부트 로더 제작을 하여 메세지 출력? 까지 할 계획이다.


Makefile 파일 생성

Make 프로그램은 소스파일을 이용해서 자동으로 실행 파일 또는 라이브러리 파일을 만들어주는 빌드 관련 유틸리티이다.

그에 따른 문법은 다양한데 Target, Dependency, Command 이라는 3가지 부분으로 기본 형식이 주어진다.


내용은 걍 책 참고하고.. 이제 부트로더 생성 과정을 만들어보자.


디렉터리 구조는 일단 서술하자면


BASH64

ㄴ00.BootLoader

ㄴ01.Kernel32

ㄴSource

ㄴTemp

ㄴ02.Kernel64

ㄴSource

ㄴTemp

ㄴ03.Application

ㄴ04.Utility


이렇게 구성된다.


Makefile(메인최상위 디렉터리) 파일

Makefile(asm은 빼고 이클립스 작성기준)의 목적은 각 하위 디렉터리의 makefile을 실행하는 것 이다

지금은 부트 로더만 있으므로 해당 디렉터리로 이동해서 빌드를 하고, 빌드 결과물을 OS이미지를 생성 하는것이 전부이다.


00.BootLoader/makeflie 파일

위 파일은 BootLoader.asm 파일을 nasm 어셈블리어 컴파일러로 빌드 한 이후 BootLoader.bin파일을 생성하는 구문이다.


위 두파일 공통적으로 clean target이 정의 되어 있기 때문에 구문을 삭제 할 수 있는것을 알 수있다.


부트로더 소스코드 작성

// 어셈블리 기초는 따로 숙지... 이후 바로 부트로더 어셈블리로 코딩을 해보자.


00.BootLoader/BootLoader.asm 소스코드


뭐 주석으로 간단 설명을 했지만 다시 정리해보면 6번줄은 뺀다면 기본적인 부트로더 작성내용이라고 해도 무방하다..

이제 jmp쪽을 건드리면서 부트로더를 생성하면 된다.


이후 QEMU로 테스트를 할 수 있지만.. 환경이 없음으로 페쓰


화면 버퍼와 화면 제어

화면에 문자를 출력하려면 현재 동작 중인 화면 모드와 관련된 비디오 메모리의 주소를 알아야 된다. 비디오 메모리는 화면 출력과 관계된 메모리로 모드별로 정해진 형식에 따라 데이터를 채우면서 원하는 화면에 문자나 그림을 출력을 하는 구조로 되어있다.


기본적으로 비디오 메모리 주소는 0xB8000에서 시작하며 가로80자, 세로25자로 시작한다. 또한 화면에 표시하는 한 문자값은 1바이트와 속성값 1바이트로 구성되며 메모리 크기는 총 4000바이트이다.


// 구조에 따른 알고리즘 그림은 패스..

// 속성값 도표도 있는데.. 이것도 그냥 책보면서 넣어야 될듯.


// 이후 M글자 넣는거 나오는데 바로 넘어가서...


세그먼트 레지스터 초기화(문자열 출력)

전까지는 부트 로더가 잘 동작하는지 눈으로 확인 할 수 있게(사실 테스트는 안했다ㅎ) 확인해보았다..이후 작업에선 코드 이전에 세그먼트 레지스터에 초기화 하는 코드가 필요하다. BIOS가 부트 로더를 실행했을 때 세그먼트 레지스터에는 BIOS가 사용하던 값들이 들어 있기 때문이다. 그럼 당연 엉뚱한 주소로 접근 하기 때문에 결론적으론 초기화를 해야된다.


그렇다면 어떤 레지스터를 초기화 해야될까..  BASH64에서는 0x07C0으로 초기화 했다. 그 이유는 BIOS가 부트 로더를 디스크에서 읽어 메모리에 복사하는 위치가 0x7C00이기 때문이다. 또한 부트 로더의 코드(Code Segment)와 데이터(Data Segment)는 0x7C00부터 512바이트 범위에 존재하므로 CS와 DS세그먼트 레지스터를 모두 0x07C0을 설정하여 부트 로더의 시작을 기준으로 하도록 했으며, ES세그먼트 레지스터는 화면 출력에 관련된 세그먼트로 사용하려고 0xB800을 설정했다. 


// 그냥저냥한 코딩.


화면 정리 및 부팅 메세지 출력

출력하기전에 BIOS가 출력하는 메세지 때문에 지저분하니...일단 부팅 메세지를 지우는 코딩내용을 작성해야된다.


0xB8000 주소부터 4000바이트를 모두 0으로 채우는 방법이다. 하지만 다른 속성까지 모드 0으로 채우면 화면에 출력할 문자는 속성값을 같이 지정 해줘야하는 불편함이 있어 문자부분만 0으로 채우고 속성값은 0이 아닌 다른값으로 채울것이다. 검은색 바탕에 밝은 녹색으로 표시하도록 속성값은 0x0A로 진행하겠다.


그리고 C언어로 코딩된 BIOS 출력 메세지를 삭제하는 ASM은..



이제 그럼 문자열을 출력해보자..



// 출력 구문, 삭제구문 합친 코딩 내용.