diff options
-rw-r--r-- | pkgs/os-specific/linux/kvm/86.nix | 5 | ||||
-rw-r--r-- | pkgs/os-specific/linux/kvm/x86_boot_vidmode.patch | 105 |
2 files changed, 106 insertions, 4 deletions
diff --git a/pkgs/os-specific/linux/kvm/86.nix b/pkgs/os-specific/linux/kvm/86.nix index aaf4b12e5d9d5..1b468385f1fa6 100644 --- a/pkgs/os-specific/linux/kvm/86.nix +++ b/pkgs/os-specific/linux/kvm/86.nix @@ -16,10 +16,7 @@ stdenv.mkDerivation rec { # Support the "vga" kernel command line option when using the # -kernel option. - (fetchurl { - url = http://www.mail-archive.com/qemu-commits@nongnu.org/msg00202/qemu.x86_boot_vidmode.patch; - sha256 = "0vf7l0mh0hr7yakxkrz681phmbkav7sa2fw3gf6h56gr28cid5l6"; - }) + ./x86_boot_vidmode.patch ]; configureFlags = "--enable-io-thread"; diff --git a/pkgs/os-specific/linux/kvm/x86_boot_vidmode.patch b/pkgs/os-specific/linux/kvm/x86_boot_vidmode.patch new file mode 100644 index 0000000000000..2ff6dd566c498 --- /dev/null +++ b/pkgs/os-specific/linux/kvm/x86_boot_vidmode.patch @@ -0,0 +1,105 @@ +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 */ |