음.. broneri homebrew project에는 minios를 두지 않으려 했는데 블로그를 두개로 운영하려니 귀찮네요..; (http://minios.tistory.com 는 천천히 없애야겠네요 )



윈도우 시스템은 역시나 예전에 만들어두었던 minigui를 사용하였습니다. 4년이 넘은 코드에 의존하고 있다니 --;

아래는 mini gui가 최초(?)로 사용된 arm rtos 인 usys os의 화면입니다.
이 땐 LCD컨트롤러만 잡으면 기본적으로 linear한 frame buffer가 잡혔지요. 그리고 터치 드라이버를 작성해서 터치로 설정할 수 있게 했었습니다.

어쨋든 Mini-GUI 소스 헤더에  2004/10/18라는 타임 스탬프는 저를 놀라게 하는군요. -_- 세월은 참 빠르구나.. 드뎌 mini fat과 mini gui가 모두 mini os로 이식되는구낭. ㅠ.ㅠ (혼자 감회가 새로움) ㅋㅋ

다시 x86 mini os로 돌아와서.. 문제는 아직 마우스를 잡지 않아서 아무런 컨트롤도 할 수 없다는 것이었습니다. 뜨헉...
어서 마우스를 먼저 잡아야 할것 같네요.

아래는 svga vesa 114h, 800x600x16bpp 입니다.

아래는 svga vesa 111h, 640x480x16bpp입니다.

부팅 시 리얼 모드에서 아래와 같이 먼저 svga를 vesa bios를 이용하여 설정합니다.
;   mov    bx, 0x114 ; ok, 800x600 5:6:5
   mov    bx, 0x111 ; ok, 640x480 5:6:5
   or     bh, 0x40 ; want linear model, clear screen (LFB linear Frame buffer)
   mov   ax, 0x4F02 ; change mode
   int   0x10 ; go
이 때 LFB (linear frame buffer)의 주소가 어디서부터 시작하는지 알아내야 합니다. (VMWare의 경우 두 svga 모드 모두 0xF0000000 번지였습니다. )

따라서 꽁수(?)를 부려서 0x9000번지에 vbe_mode_info 정보를 담아두도록 했습니다.
   mov ax, 0x900
   mov es, ax ; save ModeInfoBlock to 900:0h = 0x9000
   mov ax, 4f01h ; get vbe_mode_info
  ; mov cx, 0x114 ; vbe mode (800x600 5:6:5)
   mov cx, 0x111 ; vbe mode (640x480 5:6:5)
   mov di, 0x0   
   int 0x10

그리곤 32 bit protected kernel의 시작 엔트리가 호출되면 잽싸게 0x9000번지의 소중한(?) 현재 svga설정 값들을 받아왔습니다.

VBEMode* p = (VBEMode*)0x9000;
lfb_width = p->bytes; // 한 줄 scan line의 바이트 수
lfb = p->lfbaddr; // lfb 시작 주소 (젤중요)
lfb_xres = p->xres;
lfb_yres = p->yres;

그리고 최초 kernel의 virtual memory mapping시 lfb 주소 공간도 매핑하도록 추가하였습니다.
void vmm_map_kernel( unsigned char* phys_page_directory )
{
vmm_maps( "boot", phys_page_directory, (unsigned char*)PHYS_BOOT_START, (unsigned char*)VIRT_BOOT_START, PHYS_BOOT_PAGES );
vmm_maps( "bios", phys_page_directory, (unsigned char*)PHYS_BIOS_START, (unsigned char*)VIRT_BIOS_START, PHYS_BIOS_PAGES );
vmm_maps( "kheap", phys_page_directory, (unsigned char*)PHYS_KHEAP_START, (unsigned char*)VIRT_KHEAP_START, PHYS_KHEAP_PAGES );
vmm_maps( "kernel", phys_page_directory, (unsigned char*)PHYS_KERNEL_START, (unsigned char*)VIRT_KERNEL_START, PHYS_KERNEL_PAGES );
vmm_maps( "vmm", phys_page_directory, (unsigned char*)PHYS_VMM_START, (unsigned char*)VIRT_VMM_START, PHYS_VMM_PAGES );

vmm_maps( "lfb", phys_page_directory, (unsigned char*)PHYS_LFB_START, (unsigned char*)VIRT_LFB_START, PHYS_LFB_PAGES );
}
아주 재미있는 것은 아까 받아온 0xF0000000라는 주소는 언뜻보기엔 가상주소같은데 physical 주소라는 것이지요! 

이제 점을 찍을 수 있습니다. 

void my_draw_setpixel( int x, int y, COLOR cr )
{
char* vmem = (char*)lfb;

*((unsigned short*)(vmem + (lfb_width*y) + x * 2)) = cr;

'프로젝트 > minios OS 개발' 카테고리의 다른 글

minios on ipad  (0) 2011.12.07
minios - real IU !!  (1) 2011.02.11
minios x86 homebrew os project  (0) 2008.12.13
IBM VGA programming  (0) 2008.12.13
minios mouse control  (0) 2008.12.13
minios on svga  (0) 2008.12.10
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


티스토리 툴바