본문 바로가기
OS

[32bit] 부트섹터에서 프로그램 꺼내기(2)

by 올리고당 2021. 7. 27.

목차

 


곧 부트로더가 될 프로그램

일단 해봅시다!

boot1.asm 파일을 다음과 같이 작성해주세요.

 

boot1.asm

 


코드 설명

Q1. mov ds, cs는 불가능 한가? : CPU 내부 구조적인 문제로, 세그먼트 레지스터의 값을 바꾸려면, 범용 레지스터를 거쳐야 합니다. - 인텔 매뉴얼 vol.1 6-16page 6.3.1.1 절 참고. 

 

Q2. 비디오 메모리 세그먼트 

16비트 세그먼트:오프셋 방식으로 표현할 수 있는 주소는 0000:0000 ~ FFFF:FFFF입니다. 이 중 모두를 RAM이 사용하는 것이 아니라, 다른 주변장치에도 주소가 할당되어 있습니다. 어느 기기에 어느 주소가 할당되었는지에 대한 분포를 나타낸 것을 메모리 맵이라 합니다.

 

메모리 맵 ( 참고도서 36페이지 발췌 )

 

실습 코드에서는 컬러 텍스트 모드 비디오 메모리를 사용할 것입니다. 위의 그림과 같이 B800:0000 ~ BFFF:FFFF에 할당됩니다. 어떤 방식으로 할당되는지 궁금하신 분은 여기에서 좀 더 자세한 정보를 얻으실 수 있습니다.

 

 

Q3. 글자 색과 배경 색

 

컬러 텍스트 모드 비디오 메모리 영역에서는 화면에 글자를 표현하는데 2바이트를 사용합니다.

 

문자와 배경, 글자 색( 참고도서 37페이지 발췌 )
색상표( 참고도서 37페이지 발췌 )

 

Q4. dw 0xAA55 : 바이오스에게 부트로더의 마지막을 알려주는 바이트입니다. 입력하지 않으면, 바이오스가 부트 가능한 디스크가 없다고 에러 메시지를 보냅니다.

 

Q6. jmp 0x07c0:start 명령어 실행 시, cs와 ip가 바뀌는가?

jmp 명령어의 오퍼랜드로 세그먼트:오프셋 방식의 주소가 오면, cs를 세그먼트 값으로, ip를 오프셋 값으로 변경합니다.

- 인텔 매뉴얼 vol3. 82페이지 참고

 

Q7. 초기에 cs를 0x07c0로 설정하는 이유는?

바이오스가 부팅 가능한 장치( bootable device )를 찾으면, 부트 섹터( boot sector )를 메모리의 0x7c00으로 로드합니다. 그 후, 바이오스가 ip 값을 0x7c00으로 바꾸어줍니다. 위의 코드에서는 바뀐 ip값을 그대로 사용하는 대신, cs값과 ip값을 재설정하였습니다. 물론 ( line 4 ) 명령어 없이 ( line 1 )을 [org 0x7c00]으로 설정하고 프로그램을 작성해도 됩니다만, 오프셋을 통해 0x7c00 번지 이전의 메모리를 참조하지 않도록 하기 위해 cs값을 바꾸어 줍니다.

 

times 510-($-$$) db 0 : 현재 위치부터 510번지까지 0으로 채워주는 지시어입니다. 플로피 디스크 섹터 1개의 크기는 512바이트입니다.

 

빈 공간을 0으로 채우는 이유는 컴파일할 때, 코드의 정확한 길이를 인지하여 시간 낭비를 방지하기 위해 작성하는 코드입니다. 전체 코드의 크기가 512바이트를 넘긴다면, 컴파일할 때 에러가 발생합니다. 이런 장치가 없다면, 시뮬레이션할 때 전체 코드가 예상했던 크기를 넘긴다는 것을 발견하게 되어 시간적으로 매우 손해입니다.

 


vmware를 이용한 시뮬레이션

플로피 디스크에 쓸. img 파일을 만들어보겠습니다.

터미널을 열고, 다음 명령어를 실행시켜 주세요.

 

해당 폴더에 들어가 보시면, 잘 생성된 것을 확인할 수 있습니다.

 

만든 .img파일을 vmware로 시뮬레이션하겠습니다.

 

 

결과화면


기계어를 어셈블리어로 : 디스어셈블

cmd에 아래의 명령어를 입력해주세요.

 

 

boot.txt 파일을 열어보면, 바이너리 코드에 대한 좀 더 자세한 정보를 얻을 수 있습니다.

그중에서 1~10 줄만 가져왔습니다.

 

맨 오른쪽의 명령어가 어셈블러를 거쳐 중간 부분의 바이너리 코드로 바뀝니다. 순서대로 플로피 디스크의 부트섹터에 파란 글씨 순으로 저장됩니다. BIOS에 의해 부트 섹터에서 복사되어 RAM에 적재될 때에도, 같은 순서로 적재됩니다.

 


vmware 시뮬레이션 참고

https://itguava.tistory.com/9?category=630867 

 

dw 0xAA55

https://stackoverflow.com/questions/1125025/what-is-the-role-of-magic-number-in-boot-loading-in-linux

 

 


이번 글은 간단한 어셈블리 프로그램을 작성해서, 부트스트랩 과정을 직접 해보았습니다.

다음 글에는 실제로 사용할 부트로더 프로그램을 작성해보겠습니다.

 

감사합니다.