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