qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Isaku Yamahata <yamahata@valinux.co.jp>
To: Michael Tokarev <mjt@tls.msk.ru>
Cc: Kevin O'Connor <kevin@koconnor.net>,
	seabios <seabios@seabios.org>, qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] OEM Windows in qemu/kvm again (mini-howto)
Date: Fri, 1 Apr 2011 15:52:21 +0900	[thread overview]
Message-ID: <20110401065221.GC8401@valinux.co.jp> (raw)
In-Reply-To: <4D947AD8.5060205@msgid.tls.msk.ru>

Hi. SLIC table can be fed dynamically by utilize the existing fw_cfg interface.
Something like this. (This requires your qemu patch.)
This is just for showing the idea.

thanks,

diff --git a/src/acpi.c b/src/acpi.c
index 6428d9c..e0815bd 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -627,6 +627,7 @@ acpi_bios_init(void)
     ACPI_INIT_TABLE(build_srat());
 
     u16 i, external_tables = qemu_cfg_acpi_additional_tables();
+    bool slic = false;
 
     for(i = 0; i < external_tables; i++) {
         u16 len = qemu_cfg_next_acpi_table_len();
@@ -635,7 +636,12 @@ acpi_bios_init(void)
             warn_noalloc();
             continue;
         }
-        ACPI_INIT_TABLE(qemu_cfg_next_acpi_table_load(addr, len));
+        struct acpi_table_header *header =
+            qemu_cfg_next_acpi_table_load(addr, len);
+        if (header->signature == SLIC_SIGNATURE) {
+            slic = true;
+        }
+        ACPI_INIT_TABLE(header);
         if (tbl_idx == MAX_ACPI_TABLES) {
             warn_noalloc();
             break;
@@ -654,6 +660,9 @@ acpi_bios_init(void)
     memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx);
 
     build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1);
+    if (slic) {
+        // fix up rsdt->oem_id and check sum
+    }
 
     // Build rsdp pointer table
     memset(rsdp, 0, sizeof(*rsdp));


On Thu, Mar 31, 2011 at 05:00:08PM +0400, Michael Tokarev wrote:
> Here's a quick-n-dirty howto about running OEM version
> of windows7 or vista in qemu/kvm, assuming you own a
> computer with pre-installed OEM version of such operating
> system so you have rights to run it there.
> 
> Windows 7 & Vista OEM activation are based on a special
> OEM marker in BIOS in a form of one ACPI table named SLIC.
> The idea is to take content of that table from your computer
> and present it in the virtual machine.
> 
> This table can be taken directly from /sys/firmware/acpi/tables/SLIC
> (it's a small binary file), and hopefully qemu will be able
> to use that directly (I submitted a patch to do that a few
> days ago).
> 
> But there's on caveat still: windows apparently checks not only
> the SLIC table/marker, but also verifies that the Vendor ID
> fields in SLIC and RSDT tables matches each other.  So just
> presenting SLIC into a VM isn't enough, one have to modify
> at least two fields in RSDT table too.
> 
> And since there's no way currently to do that using qemu
> command line, I took another approach and modified seabios
> code a bit.  Here's a small howto to do that "at home".
> 
> 1) First of all, you need seabios source code appropriate
>    for your qemu/kvm.  See http://www.seabios.org/ for that.
>    Also you need tools to recompile it, obviously.
> 
> 2) after getting and extracting seabios sources, cd to
>    the source directory.
> 
> 3) You need to build slic table to be used by a C compiler,
>    like this:
> 
>     xxd -i /sys/firmware/acpi/tables/SLIC |
>      grep -v len |
>      sed 's/unsigned char.*/static char SLIC[] = {/' >
>      src/acpi-slic.hex
> 
>   this produces file src/acpi-slic.hex with content like
>   this:
> 
>     static char SLIC[] = {
>      0x53, 0x4c, 0x49, 0x43, 0x76, 0x01, ...
>     };
> 
> 4) apply the following patch to src/acpi.c:
> 
> ============= cut =============
> --- a/src/acpi.c
> +++ b/src/acpi.c
> @@ -199,4 +199,9 @@ struct srat_memory_affinity
>  #include "acpi-dsdt.hex"
> 
> +#define CONFIG_OEM_SLIC
> +#ifdef CONFIG_OEM_SLIC
> +#include "acpi-slic.hex"
> +#endif
> +
>  static void
>  build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
> @@ -211,4 +216,8 @@ build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
>      h->oem_revision = cpu_to_le32(1);
>      h->asl_compiler_revision = cpu_to_le32(1);
> +#ifdef CONFIG_OEM_SLIC
> +    if (sig == RSDT_SIGNATURE)	// only RSDT is checked by win7 & vista
> +      memcpy(h->oem_id, ((struct acpi_table_header*)SLIC)->oem_id, 14);
> +#endif
>      h->checksum -= checksum(h, len);
>  }
> @@ -627,4 +636,15 @@ acpi_bios_init(void)
>      ACPI_INIT_TABLE(build_srat());
> 
> +#ifdef CONFIG_OEM_SLIC
> +    { void *buf = malloc_high(sizeof(SLIC));
> +      if (!buf)
> +        warn_noalloc();
> +      else {
> +        memcpy(buf, SLIC, sizeof(SLIC));
> +        ACPI_INIT_TABLE(buf);
> +      }
> +    }
> +#endif
> +
>      u16 i, external_tables = qemu_cfg_acpi_additional_tables();
> 
> ============= cut =============
> 
>   The patch above arranges for your SLIC table to be
>   included inside the ("virtual") bios (that table does
>   exactly nothing for the bios itself and for other
>   system components) and also modifies OEM identification
>   information in RSDT table to match SLIC table.
> 
> 5) build the bios as usual by issuing `make' in the top
>    source directory.  You'll get out/bios.bin file.
>    Place it somewhere like /usr/share/qemu/bios-asus.bin
>    or anywhere like you want.
> 
> 6) and finally, specify that bios file when running your
>   preinstalled windows:
> 
>    qemu -hda /dev/sda -bios /usr/share/qemu/bios-asus.bin
>     [...other options...]
> 
>   (But be careful and choose appropriate boot entry, do
>    not boot linux itself in your virtual machine :)
> 
> Something like that.  This is formed as a quick-n-dirty
> howto because there's quite alot of questions lately about
> this very stuff (how to run activated windows in qemu),
> and I wanted to write an instruction so that less
> expirienced people will be able to do that.
> 
> 
> Kevin, do you remember why this code is present in
> acpi.c:
> 
> build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
> {
>     memcpy(h->oem_id, CONFIG_APPNAME6, 6);
>     memcpy(h->oem_table_id, CONFIG_APPNAME4, 4);
>     memcpy(h->asl_compiler_id, CONFIG_APPNAME4, 4);
>     memcpy(h->oem_table_id + 4, (void*)&sig, 4);     <=== this
> 
> To me it looks like we need another #define, like
> CONFIG_APPNAME8, to be used for whole oem_table_id
> field.  And also, maybe made all this stuff configurable
> somehow (starting from the build config in out/autoconf.h
> etc) ?
> 
> Thanks!
> 
> /mjt
> 

-- 
yamahata

      reply	other threads:[~2011-04-01  6:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-31 13:00 [Qemu-devel] OEM Windows in qemu/kvm again (mini-howto) Michael Tokarev
2011-04-01  6:52 ` Isaku Yamahata [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110401065221.GC8401@valinux.co.jp \
    --to=yamahata@valinux.co.jp \
    --cc=kevin@koconnor.net \
    --cc=mjt@tls.msk.ru \
    --cc=qemu-devel@nongnu.org \
    --cc=seabios@seabios.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).