IT 그리고 정보보안/Knowledge base

MintOS 부트 로더 제작

plummmm 2021. 4. 12. 22:06
반응형

간단한 부트로더를 제작해보자.

대표적인 부트로더로 리눅스 운영체제 많이 들어가는 GRUB, LILO 등이 있다.

저번에 설명했듯이, 부트로더는 저장 매체 (HDD 등.)에 들어있다고 했다.

 

부트로더는 MBR (Master Boot Record) 라는 곳에 있는 코드이다. 매우 작은 프로그램이다.

MBR은 OS가 설치되어 있는 저장매체 즉, 하드 디스크의 가장 첫번째 섹터를 MBR 이라고 한다.

섹터(Sector)는 굳이 설명을 해야 할까 싶긴한데.. 디스크를 구성하는 데이터의 단위이다. 크기는 512byte

 

부트로더의 가장 큰 역할은

OS 실행에 필요한 환경 설정

OS 이미지를 메모리에 복사

요 두가지 기능이다.

 

부트로더가 아주 많은 기능을 할 것 같이 생겼지만, 하나의 섹터에서 코드가 해봐야 뭐 얼마나 되겠나.

부트로더는 기본적이고 중요한 기능만 수행하도록 제작된다.

 

디스크의 가장 첫번째 섹터가 부트로더가 들어 있는 MBR이라고 했다.

물론 해당 디스크로 부팅을 하려고 할 때만 첫번째 섹터가 부트로더임.

저장소로 이용할 거라면 일반 데이터가 들어가있겠지

 

BIOS가 그럼 어떻게 이게 부트 로더인지 일반 데이터인지 구분할까? 

섹터를 쭈욱 읽다가 마지막 코드가 0x55, 0xAA 일 때 이 놈을 부트로더라고 판단하는 것이다.

 

마지막 코드가 0x55 0xAA 인지 확인하면 이게 부트로더인지 일반 저장 매체 디스크인지 판별할 수 있다.

그럼 부트로더 제작을 해본다.

 

1. 환경 구성 및 makefile

일단 이클립스로 아래와 같이 디렉토리를 구성해준다.

이제 makefile~을 할텐데, 그전에 make에 대해서 잠시 알아보고 가자.

make 프로그램이란, 소스 파일을 이용하여 자동으로 실행파일 또는 라이브러리 파일을 만들어주는 빌드 유틸리티이다.

그냥 쉽게 말해 소스코드 빌드 하는 놈이다.

 

이 make를 사용하기 위해선 각 소스 파일의 의존관계나 빌드 순서, 빌드 옵션 등에 대한 정보가 필요한데,

그것들이 들어있는 파일을 makefile 이라고 한다.

make의 문법은 굉장히 엄격하다. 그래서 진짜 하다가 알 수 없는 오류때문에 빡칠 수가 있다. 조심하자.

 

make 문법에 대해 자세히 말고 간단하게 알아보자. 책 내용을 빼는데 꼭 필요한 것 위주로 알아본다.

일단 내가 전공 과목 배울 때 makefile 작성했던 것이 있는데, (예를 들어 설명하기 쉽게.. )보겠음.

 

 

makefile은 저렇게 생겼다. 저건 리눅스 디바이스 드라이버의 makefile이다.

문법은 Target, Dependency, Command 세가지로 구분할 수 있다.

[Target]: [Dependency]

Command

Command

Command

...

위와 같이 생겨먹었다. 위에서 주의해야 되는 부분이.. command 띄어놓은 곳이 스페이스바가 아니라 <Tab>이다.

어째 보면 이게 진짜 makefile에서 가장 눈 여겨보아야 할 부분. 생소하니까

 

Target : 일반적으로 생성할 파일을 나타내고 특정 레이블을 지정하여 해당 레이블과 관련된 부분만 빌드하는 것 가능.

Dependency : target 생성에 필요한 소스 또는 오브젝트파일 등을 나타낸다.

Command : Dependency에 관련된 파일이 수정되면 실행할 명령을 의미한다.

 

그니까 target을 만들기 위해 필요한 놈들을 dependency로 두고 그걸로 무슨 작업을 하여 상태를 변경할 것인지

command에다가 써주면 된다는 것이다. 이렇게만 놓고 보면 별거아니다. 

 

예제 makefile을 한번 만들어보면서 익숙해져봅시다.. 책에 있는 예제를 사용하겠음

위 예제는 a.c 와 b.c 소스파일을 gcc로 빌드하여 output.exe를 생성하는 makefile이다.

makefile을 저렇게 생성하고 터미널에 $make 명령을 치면 지가 알아서 빌드한다.

그럼 이제 MINT64 용 makefile을 만들어보자. makefile 이라는거 자체가 빌드를 하는 녀석이라고 했다.

 

이게 보면 최상위 디렉토리 makefile이 있고 각각 디렉토리마다 makefile이 존재한다.

최상위 디렉토리의 makefile 같은 경우 각 하위 디렉토리에 있는 makefile을 실행하는 것이다.

 

일단 현재는 부트로더 makefile만 있으므로 부트로더만 작성하도록 한다. 먼저 최상위 디렉토리의 makefile을 만들어보자.

 

위에서 말한대로 이거는 부트로더 makefile만 실행하도록 한다. 그럼 이번에는 부트로더에 makefile을 작성해보자.

00.BootLoader 디렉토리에 생성한다.

이 녀석의 목적은 BootLoader.asm 즉, 부트로더 코드를 컴파일러로 빌드하여 BootLoader.bin 이라는

파일을 생성하는 것이다. 

아직 BootLoader 코드를 작성하지 않았으니 make 해봤자 오류가 난다

 

2. 부트 로더 기본 틀 제작

부트로더를 만들때는 마지막 2바이트에 0x55, 0xAA 넣는거만 지켜주면 BIOS가 "아 이게 부트로더 코드구나" 라고 인지하도록 할 수 있다. 진짜 간단한 부트로더를 만들어 볼건데. 어셈블리로 제작해야된다.

 

부트로더, 멀티태스킹, 멀티코어 관련된 부분은 어셈블리어 사용이 불가피하다.

어셈블리어에 대한 내용은 따로 정리해 둔 부분도 있고하니 따로 언급안하고 넘어감.

 

저번에 말한 BootLoader.asm 파일을 채워넣을 것이다. 한번에 다 할 수 없으니 부분부분 나누어 보겠다.

주석을 달까 했는데 좀 지저분해 보여서 따로 설명하겠음.

 

[ORG 0x00]

코드의 시작 주소를 0x00으로 설정한다.

 

[BITS 16]

아래 코드들은 모두 16비트 코드로 설정한다.

 

SECTION .text

텍스트 영역으로 정의한다.

 

jmp $

while(1) 즉, 현재 위치에서 무한루프를 돌린다는 말.

$ 는 현재 라인의 어드레스를 의미한다.

 

times 510 - ($ - $$) db 0x00

현재 위치에서 510되는 어드레스까지 0x00으로 채움.

times : 다음에 오는 횟수만큼 작업 반복

$$ : 현재 어드레스 가 포함된 영역의 시작주소

$$ : 영역 시작주소를 기준으로 잡은 옵셋값

db 0x00 : Define Byte의 약자로, 뒤에 나오는 값으로 현재 어드레스에 1바이트 크기의 0x00 삽입.

db(1byte), dw(2byte), dd(4byte), dq(8byte)

 

db 0x55

db 0xAA

511, 512 어드레스에 0x55, 0xAA를 삽입.

부트로더를 의미하는 값

 

위에 만들어 놓은걸로만 보면 그냥 무한루프만 도는 부트로더이다.

이제부터 본격적으로 안에 내용을 코딩할텐데.. 일단 먼저 부트로더를 만들고 나서 테스트해볼 환경이 필요하지 않을까?

 

QEMU를 이용해서 테스트를 할 수 있다.

 

방금 만든 허접한 부트로더를 빌드하고 나서 QEMU을 실행시켜보자.

정상적으로 동작한다면 아래와 같은 화면이 나온다.

 

 

3. 텍스트 모드, 화면 구성

QEMU 세팅에 이어 계속해서 부트로더를 만들어봅시다.

과거 16비트 OS 시절에는 부팅 시작시 뭐 환영한다는 메세지 따위가 떳다. 여기에도 그거랑 비슷한걸 적용시켜보자.

비디오 메모리에 접근해서 텍스트 모드의 생긴 와꾸를 내마음대로 바꿀 수 있다.

 

이쪽에 접근하기 위해 어셈블리어로 코딩을 해야 한다.

메모리 관리 기법할 때 16비트 환경 메모리 컨트롤 하는 부분을 제대로 이해 못하면 머라하는지 모를 수도 있다.

 

mov ax, 0xB800

mov ds, ax

 

일단 코드부터 보여드림.

왜 저렇게 됐냐면.. 컬러 텍스트 모드의 메모리 주소가 0xB800:0000 이라는 것을 보여줬었다.

이건 [세그먼트 레지스터 값:OFFSET값] 이라고 했는데, 세그먼트 레지스터 값에 16을 곱해서 offset을 더하면

물리주소가 나온다.

 

최종적으로 접근해야 하는 주소는 0xB8000 물리주소인데, 세그먼트 값이랑 옵셋을 어떻게 쓰든 저 값만 나오면 되지만

누가 봐도 이건 0xB800:0000 으로 하는게 맞지;;

세그먼트 값이랑 옵셋값을 저렇게 셋팅하는 것이 위 코드이다.

이제 ds 레지스터를 이용하여 접근을 했으니까 저 위치부터 값을 변경하면 원하는 텍스트모드 화면을 구성할 수 있을 것이다.

 

mov byte [0x00], 'M'

mov byte [0x01], 0x4A

 

위와 같이 구성하기 위해 저런 코드를 적었다.

0xB800:0000 에 M이라는 글자를 넣고

0xB800:0001 에 빨간 배경에 밝은 녹색을 복사하는 것인데. 딱봤을데 한눈에 안들어온다.

0x4A에서 '4'는 빨간 배경, 'A'는 밝은 녹색.. 헷갈려서 기존에 나와있는 표를 갖고왔다.

 

 

저번 포스트까지 작성했던 코드에 텍스트 모드 화면을 수정한 코드를 넣어보자.

그럼 이제 요기까지 하고 화면이 바뀌는지 확인을 해보자.

잘나온다. 일단 여기까지 화면 모드 (텍스트 모드) 변경하는 것이고, 다음부터 본격적으로 기능적인 부분에 살을 붙이도록 하겠다.

 

4. 세그먼트 초기화 루틴

 일단 위에 만들었던 코드를 보자.

이번 포스팅에서 얘기할 부분은 세그먼트 레지스터의 초기화이다.

세그먼트 레지스터에는 BIOS에서 부르토더를 실행할 때 사용하던 코드들이 들어있다. 그래서 초기화를 해주지않으면

엉뚱한 세그먼트를 가르킬 수도 있다. 그래서 초기화를 꼭 해주어야 한다.

 

그럼 어떤 값으로 세그먼트 레지스터를 초기화 해주어야 할까.

우리가 만드는 MINT64 OS는 0x7C0으로 초기화 해준다.

BIOS에서 부트 코드를 읽어 메모리에 로드하는 위치가 0x7C00 이기 때문임.

 

그리고 부트로더의 코드 세그먼트와 데이터 세그먼트는 0x7C00 에서 512바이트 안의 범위에 존재하니까

CS와 DS 세그먼트 레지스터의 값을 0x7C0 으로 설정할 수 있다. 세그먼트 레지스터가 그 섹션의 범위를 나타내는 것.

64KB는 512Byte

 

CS 레지스터를 제외하고는 mov 명령으로 처리를 할 수 있는데, CS는 그렇게 할 수가 없다.

jmp 명령과 CS 접두사를 이용해야 한다. 코드를 직접 봐야 무슨말인지 알 수 있을 듯 하다.

 

 

한줄 씩 설명을 하겠다.

 

jmp 0x07c0:START

0x07c0으로 시작하는 세그먼트의 START 옵셋으로 점프를 한다.

즉, CS 레지스터에 0x07c0 을 복사하면서 START 레이블로 이동한다는 얘기.

위에 SECTION .text 라고 되어 있으니 이 코드는 자연스럽게 코드 섹션에 있다는 말이지.

 

START:

mov ax, 0x07c0

mov ds, ax

ax 값에 0x07c0 값을 복사하고 그 값을 ds 레지스터에 저장한다.

즉, 데이터 세그먼트의 레지스터 값도 0x07c0으로 설정한다 이말이다.

 

mov ax, 0xB800

mov es, ax

이번에는 es레지스터, 즉, 데이터 세그먼트에 0xB800 값으로 설정하는 것이다.

저번 포스트에서 ds레지스터에 0xB800을 설정하여 비디오 메모리에 접근했는데,

위에서 ds를 사용했으니까 es를 사용하여 접근하도록 코드를 수정한 것.

 

그 밑에는 이전과 같다.

 

실행하면 이전과 결과는 똑같고 단지 세그먼트 초기화를 해주는 것이다.

 

5. 화면 정리 및 메세지 출력

이제 화면 정리 및 부팅 메세지 출력하는 부분을 만들어봅시다.

이전에 부트로더 화면을 보면 지저분하다. 쓸데 없는 말이 많고.

그래서 그 지저분한 화면을 정리하고 원하는 메세지를 출력하는 코드를 넣어보겠음.

 

그 화면 정리하는 것부터 할건데, c코드를 objdump로 어셈코드로 바꾸어 집어넣을 것이다.

예전에 셸코드 만들 때 한번 해본 적이 있어서 대충 기억이 남..

코드를 다 적고 gcc로 컴파일 해야지. objdump로 디스어셈블 하려면 오브젝트 파일 형태로 컴파일해야 한다.

gcc -c 옵션을 주면됨.

 

뒤에 O2 옵션은 말안해도 알겠지만 최적화 옵션임. 고다음에 objdump로 어셈코드를 뽑아내보자. AT&T로 나온다.

 

-d 파라미터를 주면 디스어셈블 하는 옵션이다.

 

하면 요래 나온다. 이걸 이제 우리가 짠 코드에 집어 넣으면 된다.

물론 이걸 보고 그대로 집어넣으면 안됨.. 수정해야지.

 

mov si, 0

si 레지스터를 초기화 한다.

 

mov byte [es:si], 0

비디오 메모리의 문자가 위치하는 어드레스에 0을 복사한다. 문자 표현하는 부분.

mov byte [es:si+1], 0x0A

si+1 은 속성을 나타내는 부분이다. 0x0A 값을 넣으면 밝은 녹색임.

 

add si, 2

그 다음 위치로 넘어간다. 문자+속성 2bit를 넘어야 하니 +2가 된다.

 

cmp si, 80*25*2

jl .clean

루프를 돌면서 텍스트 모드 전체 화면을 전부 밀어버린다.

 

코드를 합치는건 다 하고나서 하겠음. 일단 화면을 지우는 코드를 만들어봤으니 이제 부팅메세지를 출력하는 코드를 만들어보자. 이것도 화면 지우는 거랑 똑같이 하면 된다.

 

위에 한거랑 똑같이 해서 어셈 코드를 만들어보면 아래와 같다.

 

mov si, 0

mov di, 0

si, di 레지스터를 초기화 한다.

 

.msgloop

mov cl, byte [si + message1]

msgloop 루프를 시작한다.

cl 레지스터에 si 레지스터 + message1 주소를 더한 값을 복사한다.

 

cmp cl, 0

je .msgend

cl 레지스터의 값이 0이면 문자 출력을 종료한다. (메세지 끝을 0으로 설정하여 더이상 없으면 0이된다.)

 

mov byte [es:di], cl

cl 레지스터의 값이 0이 아니면(출력할 문자가 있다면) es:di 자리에 cl레지스터의 값을 복사한다.

즉, 0xB800:di 자리에 cl 레지스터 안에 들어있는 값을 출력한다는 말이다.

 

add si, 1

add di, 2

jmp .msgloop

출력이 끝나면 si 레지스터는 다음 cl 레지스터 값을 가르키도록 (다음 문자를 가르키도록)

di 레지스터는 텍스트 모드 화면의 다음 칸을 가르키도록 값을 더해준다.

그리고 다시 루프처음으로 돌아가서 반복한다.

 

.msgend

.message1

db 'MINTOS_Woodong Starting..', 0

메세지를 출력하는 코드이다. 마지막은 0으로 설정한다.

 

이제 이 코드들을 원래 만들었던 곳에 집어넣어 보자.

(아래 message1 앞에 점 빼야한다.) 집어넣고 qemu로 돌려보면,

이렇게 나온다. 부트로더를 다 만든것 같지? 아니다.. 지금 이녀석은 아무런 기능도 못하는 껍데기만 부트로더이다.

 

6. OS 이미지 메모리 로딩

이번에는 부트로더의 OS 이미지 로딩 기능을 추가해보자.

os이미지는 크게 부트로더, IA-32e커널, 보호모드 커널 3가지로 구성된다.

각 부분을 섹터 단위로 정렬 되어 하나의 부팅 이미지 파일로 합친다.

 

첫번째 섹터는 부트 로더가 있으니.. 그 다음 두번째 섹터부터 차례로 읽어 메모리에 로딩 시키면

OS 이미지 로딩 기능이 추가 된 것이라고 볼 수 있다.

0x7C00 이후에 연속해서 메모리에 복사해도 상관 없지만 우리는 0x10000 (64KB) 부터 복사할 것이다.

그림으로 따져 보면 이러함.

최초에 BIOS가 부트로더를 메모리에 로딩시키고 부트로더가 OS이미지를 메모리에 로딩시키는

뭐 그런 과정을 나타낸 그림이다.

 

디스크의  첫 번째 섹터는 위에서 말했듯이 BIOS가 로딩하니까 부트로더는 두번째 섹터부터 OS이미지 크기 만큼 메모리에 복사하면 된다. 

디스크의 섹터는 섹터 -> 헤드 -> 트랙의 순서로 배열되어 있으니까 순서를 지켜야 한다.

 

섹터 -> 헤드 -> 트랙 순서로 읽는 다는게 무슨 의미인지 알 것이다.

그럼 이 순서대로 디스크를 읽는 기능을 추가하기 위해 먼저 c로 코드를 짜보자. (책에 있는거지만 ㅡㅡ;)

 

이걸 참고하여 어셈코드로 짜야한다.

음.. 주석에 설명을 다 적어 놓았는데, 그냥 포인트는 그거다.

섹터를 먼저 읽어, 처음에는 섹터 2, 헤더 0, 트랙 0 이다. 섹터 2인 이유는 부트로더 다음부터 읽어야 되니까.

거기서 이제 섹터를 18까지 다읽어, 그럼 헤더를 1로 뒤집고 다시 섹터를 1로 설정해 그리고 나서 18까지 또 읽어

헤더를 1로 뒤집고 18까지 다읽으면 이제 헤더, 섹터를 각각 0, 1로 초기화 시키고 트랙번호를 1 증가 시켜.

 

 

7. 스택 초기화, 함수 구현

부트로더에 들어갈 스택을 만들어보자.

부트로더에서 함수를 호출하기 위해서는 반드시 스택을 생성해야 한다.

 

접때 OS이미지 로딩하는 부분을 시작을 0x10000(64KB) 으로 해뒀었다. 0x1000:0000 부터.

그래서  스택 공간은 0x10000 이하가 될 것이다.

 

이렇게 되면 0x0000:0000 ~ 0x0000:FFFF 사이의 주소를 사용하게 될 것임. 고로 SS 세그먼트 값은

0x0000 으로 해야겠지. 그리고 SP, BP 레지스터의 값을 0xFFFE 로 설정하여 스택을 만땅으로 사용할 수 있도록 한다.

 

여기서 이해 안가는 부분이 좀 있긴한데,  스택 영역으로 사용하는 부분이 부트 영역과 겹쳐도 상관이 없는 것인지..

조금 더 찾아보고 확실히 이해가 가면 다시 수정을 하도록 하겠음. 일단 뭐 없고 스택 초기화 코드를 작성해보자.

 

이제 스택을 초기화 했으니, 함수를 구현 해보자. 스택이 있어야 함수 호출이 가능하므로 스택을 만들어 준거다.

메세지를 출력하는 함수를 작성해 볼 것이다.

 

함수에서 사용할 레지스터, 스택 정리, 파라미터 받는 코드 정도 구성하면 된다.

PRINTMESSAGE( iX, iY, pcString); 요래 생긴 녀석을 호출할 것이다.

 

이제 함수가 호출 당하는 쪽의 코드를 보자.. 스택이니까 당연히 프롤로그, 에필로그 과정이 필요하지.

모든 설명은 위에 링크 걸어둔 포스트에 되어 있다.

 

스택의 bp 레지스터가 스택의 기준이 되어 파라미터 값들을 참조할 때 bp + [offset] 으로 참조한다.

그리고 위 링크에도 말했듯이.. 스택에 함수 호출 전의 레지스터 값들을 집어 넣어주어야 함수 에필로그가 끝나고

그 값들을 다시 복원되어 호출 전후 상태가 같아야 한다.

그래서 아래와 같은 형태가 기본적으로 어셈블리로 함수 호출 코드를 작성할 때 마치 공식처럼 정형화 되어 있다.

요런 방식으로 함수를 불러내고 또 마지막엔 정리를 한다.

자 그럼 이런 형태를 가지는걸 알았으니까 이제 실제로 PRINTMESSAGE 함수 코드를 작성해보자.

이렇게 함수 구현까지 완료 했다. 이제 지금까지 작성한 코드들을 합쳐 간단한 부트로더를 완성해볼 것이다.

물론 테스트도 해봐야 겠지. 그건 다음 포스트에서 이어서 하도록하겠음. 

 

8. 최종 부트로더 작성 및 테스트

이제 지금까지 작성한 코드들을 전부다 합쳐서 최종 부트로더를 작성하고

작성한 부트로더를 한번 테스트해보자. 일단 지금까지 작성한 코드를 합쳐야겠지.

지금까지 작성한거를 합쳐보자. 보면 알겠지만 생각보다 길다.

 

한 화면에 캡쳐가 안되서 여러개를 잘라 붙였는데.. 음 나름 이쁘게 잘린거 같다. 

이게 이제 완성된 부트로더 라고 할 수 있는데.. 응? 실행하면 안된다. ㅡㅡ;  os 이미지가 없는데 실행이 될 리가 있나..

일단 그럼 부트로더가 잘 돌아가는지 테스트 할 수 있는 os 이미지를 테스트 용으로 하나 만들어 봐야겠네.

 

테스트용 가상 os 이미지는 이번에만 사용하고.. 실제 OS 이미지를 만들고나면 폐기한다.

그러니 세세하게 구현할 이유가 없음. 다만 섹터별로 0~9까지 번호를 출력하도록 하여

각 섹터들이 정상적으로 호출 되었는지 확인해봐야겠지.

 

기능은 간단하게 구현할 거지만.. 크기는 수백 KB가 되어야 한다. 여기선 512KB(1024 섹터)로 정했다.

1024개나 되는 섹터를 하나하나 다음 섹터로 이동하고 출력하는 코드를 적으려면 굉장히 수고스러울 것 같다

 

그래서 NASM의 전처리기에서는 이러한 작업을 간단하게 해주는 기능을 지원한다.

그래서 첫번째 섹터에 들어갈 코드만 구현해두면 그 뒤에 1023섹터에 대한 코드는 아주 손쉽게 구현할 수 있다.

먼저 첫번째 섹터 코드를 작성해보자.

 

위에 01.Kernel_32bit 디렉토리에 VirtualOS.asm 파일을 생성한다.

이제 이 코드를 가지고 1024섹터를 도는 코드로 확장히켜 보겠다.

nasm에서 제공하는 전처리문이 있는데,  그 친구들을 이용하여 작성할 것이다.

잠깐 전처리문들을 소개하고 넘어가겠다.

 

%rep [반복횟수], %endrep : rep와 endrep 사이에 있는 코드를 반복 횟수 만큼 반복한다.

%assign : 변수 대입

%if, %elif, %else, %endif : 조건문

 

그럼 이걸 가지고 코드를 다시 수정해봅시다.

위에서 설명했듯이 %로 시작하는 것이 전처리문이다. 설명은 주석에 모두 달아두었음.

 

돌려보면.. 솔직한 말로 정말 어이없는게 많다. 일단 % 뒤에오는 숫자들 28라인 41라인 에 있는 %10과 %512

이녀석들을 띄어쓰기 하지 않으면 하나의 명령어로 인식해버린다. 그래서 띄어줘야함..

 

이제 makefile을 수정하고 직접 qemu(케뮤??)로 돌려보자. 잘돌아가는지.

일단 01.Kernel_32bit 디렉토리에 아래와 같이 makefile을 추가하자.

makefile을 새로 작성했으니 최상위 디렉토리에 있는 makefile도 바꿔야겠지.

 

이래 바꾸고 돌려보면 아래와 같이 나온다.

TOTALSECTORCOUNT 값을 1024에서 다른 값으로 바꾸면 찍히는 값이 다르겠지?

근데 이 값을 1~1152 사이로 밖에 못정한다. 왜? OS 이미지가 로딩되는 어드레스가 0x10000이고

그 위로 0xA0000부터는 비디오 메모리로 사용되기 때문이란다.

리얼모드에서 BIOS의 서비스를 최대한 활용하니까 이런 1152섹터 밖에 못쓰는 제한 사항이 생겨버렸다.

반응형

'IT 그리고 정보보안 > Knowledge base' 카테고리의 다른 글

윈도우 부팅 과정 및 OS 기초  (0) 2021.04.13
MintOS 32-bit 보호모드 전환  (0) 2021.04.12
MintOS 부팅 과정  (0) 2021.04.12
OS 메모리 관리 기법  (0) 2021.04.12
레지스터 (Register)  (0) 2021.04.12