정보공간_1

[6기 강북 홍진우] 64비트 멀티코어 OS#6 - 화면 버퍼 구성 및 제어 본문

IT 놀이터/Elite Member Tech & Talk

[6기 강북 홍진우] 64비트 멀티코어 OS#6 - 화면 버퍼 구성 및 제어

알 수 없는 사용자 2014. 11. 24. 15:59


 엘리트 멤버 6기, 강북멤버십 23-1기 홍진우입니다.



 지난시간에는 부트로더를 직접 소스로 구성하고 가상으로 Emulation 해보았는데요. 이번 시간에는 OS의 기본기능중 하나인 화면 제어에 대해 공부해 보도록 하겠습니다.



* 필요한 툴은 지난 포스팅과 동일하게 Eclipse CDT, NASM, QEMU 입니다.




1. 화면 제어의 원리


 화면에 문자를 출력하기 위해서는 현재 동작 중인 화면 모드와 관련된 비디오 메모리의 주소값을 알아야 합니다. 비디오 메모리는 모드별로 규약에 맞추어 데이터를 입력하게 되면 화면에 원하는 문자나 그림을 출력하는 구조로 되어 있습니다.


 부팅 후 기본으로 설정되는 화면 모드는 Text 모드 이며, 화면 크기는 80(가로) X 25(세로) Character Set으로 설정되어 있으며, 비디오 메모리 시작 주소는 0xB8000입니다. 또한 화면에 표시하는 한 문자는 문자값 1바이트, 속성값 2바이트를 합해 총 2바이트의 메모리를 가집니다.

 따라서 한 화면의 총 메모리 크기는 80 X 25 X 2 = 4000 바이트를 가지게 됩니다.



[그림1] 비디오 버퍼 메모리 구조



[그림2] 문자 배경색, 전경색 비트필드 구조


 속성값 1바이트(=8비트)는 전경색 하위 4비트, 배경색 4상위 4비트로 구성되어 있습니다. 각 전경색과 배경색은 다시 최상위비트(MSB)는 특수기능 비트로 할당이 되어 있으며, 나머지 3비트는 색생값을 가지고 있습니다. 특수기능은 깜빡임이나 강조효과등을 줄 수 있습니다. 

 자세한 색상과 기능에 대한 설명은 아래 표에 첨부하였습니다.



[그림3] 비디오 메모리 문자열 색상 표




 이를 이용해서 화면 맨 위에 특정 문자를 전경색, 배경색을 설정해 출력하는 코드를 작성해 보겠습니다. 




[그림3] 문자열 출력이 구성된  BootLoader.asm

  

 위의 10,11,13,14 번째 라인이 문자열 출력과 관련된 NASM 어셈블리 코드입니다. AX레지스터에 0xB800을 복사하여, 이를 다시 한번 DS 세그먼트 레지스터에 복사함으로써, 비디오 메모리에 데이터를 기록할 메모리 오프셋을 지정해 줍니다.

 또한, 해당 오프셋으로부터 첫번째 바이트에 문자열 내용을, 두번째 바이트에 색 속성값 데이터를 기록해 줍니다. 아래의 출력창은 해당 부트로더 환경을 빌드하여, QEMU Emulation 한 화면입니다. 

(구체적인 프로젝트  구성이나 빌드 과정에 대해서는 지난번 포스팅에 수록되어있습니다.)




[그림4] 첫문자열이 출력된 콘솔창(QEMU Emulation)




 위의 출력창에서, 지난번에 구성한 부팅화면과 달리, 첫번째 문자에 다른 글자색을 가진 문자가 출력된것을 확인하실 수 있습니다.




2. 세그먼트 레지스터 초기화



  BIOS가 부트 로더를 실행했을 때, 세그먼트 레지스터에는 BIOS가 사용하던 값이 들어 있습니다. 따라서 세그먼트 레지스터를 초기화하여, 화면 버퍼를 제어하는 어드레스에 접근 시, 올바른 어드레스에 접근할 수 있도록, 세그먼트 레지스터를 초기화 하여야 합니다.


 BIOS가 부트로더를 디스크에서 읽어 메모리에 복사하는 위치는 0x7C00입니다. 따라서  세그먼트 레지스터를 0x7C00로 초기화해야합니다. 세그먼트 레지스터를 초기화하는 코드는 아래의 [그림5]에 적용되어 있습니다.




3. 화면 정리 및 부팅 메시지 출력


 QEMU를 처음 실행하면 BIOS가 출력한 메시지 로그가 남아있습니다. 해당 메시지들을 모두 지우고, 원하는 메시지를 화면에 출력할 수 있는 기능을 구현해보도록 하겠습니다. 화면을 깨끗하게 정리하는 가장 간단한 방법은 화면 버퍼의 시작주소인 0xB8000 어드레스를 모두 0으로 채우는 것입니다.


[그림 5]  사용자 부팅 메시지를 반영한 BootLoader.asm


 변경된 소스코드에 대해 설명하자면, 15번째 라인에서 SCREENCLEARLOOP라는 반복문을 구성하여, 비디오 메모리의 모든 내용을 0으로 초기화 합니다. 그리고, 24번째 라인에서, MESSAGELOOP를 구성하여, 비디오 메모리의 내용을 37번째 MESSAGE1의 문자열(Samsumg Software MemberShip!!!) 으로 Write하는 구문으로 이루어져있습니다.



[그림 6] 사용자 부팅메시지가 반영된 부팅화면(QEMU Emulation)



 위 화면과 같이, 이전에 있었던 부팅 로그 메시지가 모두 삭제되고 원하는 문자열을 화면에 출력한것을 확인하실 수 있습니다.



* objdump 



 아마 어셈블리 코드에 익숙하지 않으신 분들도 계실 것입니다. 이를 위해 binutil에는 objdump라는 유틸이 있습니다. C언어로 작성한 코드를 이용해 실행 파일이나 오브젝트 파일과 같은 파일에서 어셈블리어 코드를 자동 추출하는데 사용합니다.

위의 어셈코드를 추출하는데 활용하시면 유용하게 사용하실 수 있습니다.





* 참조 자료 : 64비트 멀티코어 OS 원리와 구조