Based on http://www.mail-archive.com/qemu-commits@nongnu.org/msg00202/qemu.x86_boot_vidmode.patch. diff -Nupr qemu/hw/pc.c qemu-new/hw/pc.c --- qemu/hw/pc.c 2009-05-26 16:10:44.000000000 +0800 +++ qemu-new/hw/pc.c 2009-05-26 17:17:25.000000000 +0800 @@ -593,6 +593,78 @@ static long get_file_size(FILE *f) return size; } +static uint16_t hato16i(char *hex) +{ + uint16_t integer = 0; + if(hex[1] == 'x') + hex += 2; + + while(*hex != '\0'){ + integer = (integer<<4); + + if(*hex >= 0x30 && *hex <= 0x39){ /*0~9*/ + integer += *hex - 0x30; + }else if(*hex >= 0x61 && *hex <= 0x66){ /*a~f*/ + integer += *hex - 0x61 + 0xa; + }else if(*hex >= 0x41 && *hex <= 0x46){ /*A~F*/ + integer += *hex - 0x41 + 0x1; + }else + break; + + hex++; + } + return integer; +} + +static uint16_t ato16i(char *dec) +{ + uint16_t integer = 0; + + while(*dec != '\0'){ + integer *= 10; + + if(*dec >= 0x30 && *dec <= 0x39){ /*0~9*/ + integer += *dec - 0x30; + }else + break; + + dec++; + } + return integer; +} + +static int get_vga_mode(const char* kernel_cmdline, uint16_t *vga_mode) +{ + char mode[7]; + int i = 0; + char *p = strstr(kernel_cmdline, "vga="); + if(p == NULL) + return 1; + + p += 4; + + while(*p != ' ' && *p != '\0' && i < 6) { + mode[i] = *p; + i++; + p++; + } + mode[i] = 0; + + if(!strncmp(mode, "ask", 3)){ + *vga_mode = 0xfffd; + }else if(!strncmp(mode, "normal",6)){ + *vga_mode = 0xffff; + }else if(!strncmp(mode, "ext", 3)){ + *vga_mode = 0xfffe; + }else if(!strncmp(mode, "0x", 2)){//in hexdecimal + *vga_mode = hato16i(mode); + }else //in decimal + *vga_mode = ato16i(mode); + + return 0; +} + + static void load_linux(target_phys_addr_t option_rom, const char *kernel_filename, const char *initrd_filename, @@ -605,6 +676,7 @@ static void load_linux(target_phys_addr_ uint16_t real_seg; int setup_size, kernel_size, initrd_size, cmdline_size; uint32_t initrd_max; + uint16_t vid_mode; uint8_t header[1024]; target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr; FILE *f, *fi; @@ -683,6 +755,12 @@ static void load_linux(target_phys_addr_ if (protocol >= 0x200) header[0x210] = 0xB0; + /*parse cmdline and set vga mode*/ + if(!get_vga_mode(kernel_cmdline, &vid_mode)){ + header[0x1fa] = vid_mode&0xff; + header[0x1fb] = (vid_mode&0xff00)>>8; + } + /* heap */ if (protocol >= 0x201) { header[0x211] |= 0x80; /* CAN_USE_HEAP */