acpi_physical_address __init acpi_os_get_root_pointer(void) { #ifdef CONFIG_KEXEC if (acpi_rsdp && !secure_modules()) return acpi_rsdp; #endif if (efi_enabled(EFI_CONFIG_TABLES)) { if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) return efi.acpi20; else if (efi.acpi != EFI_INVALID_TABLE_ADDR) return efi.acpi; else { printk(KERN_ERR PREFIX "System description tables not found\n"); return 0; } } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) { acpi_physical_address pa = 0; acpi_find_root_pointer(&pa); return pa; } return 0; }
void __init acpi_initrd_override(void *data, size_t size) { int sig, no, table_nr = 0, total_offset = 0; long offset = 0; struct acpi_table_header *table; char cpio_path[32] = "kernel/firmware/acpi/"; struct cpio_data file; if (data == NULL || size == 0) return; for (no = 0; no < ACPI_OVERRIDE_TABLES; no++) { file = find_cpio_data(cpio_path, data, size, &offset); if (!file.data) break; data += offset; size -= offset; if (file.size < sizeof(struct acpi_table_header)) { pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n", cpio_path, file.name); continue; } table = file.data; for (sig = 0; table_sigs[sig]; sig++) if (!memcmp(table->signature, table_sigs[sig], 4)) break; if (!table_sigs[sig]) { pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n", cpio_path, file.name); continue; } if (file.size != table->length) { pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n", cpio_path, file.name); continue; } if (acpi_table_checksum(file.data, table->length)) { pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n", cpio_path, file.name); continue; } pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n", table->signature, cpio_path, file.name, table->length); all_tables_size += table->length; acpi_initrd_files[table_nr].data = file.data; acpi_initrd_files[table_nr].size = file.size; table_nr++; } if (table_nr == 0) return; if (secure_modules()) { pr_notice(PREFIX "module signing is enforced, ignoring table override\n"); return; } acpi_tables_addr = memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT, all_tables_size, PAGE_SIZE); if (!acpi_tables_addr) { WARN_ON(1); return; } /* * Only calling e820_add_reserve does not work and the * tables are invalid (memory got used) later. * memblock_reserve works as expected and the tables won't get modified. * But it's not enough on X86 because ioremap will * complain later (used by acpi_os_map_memory) that the pages * that should get mapped are not marked "reserved". * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area) * works fine. */ memblock_reserve(acpi_tables_addr, all_tables_size); arch_reserve_mem_area(acpi_tables_addr, all_tables_size); /* * early_ioremap only can remap 256k one time. If we map all * tables one time, we will hit the limit. Need to map chunks * one by one during copying the same as that in relocate_initrd(). */ for (no = 0; no < table_nr; no++) { unsigned char *src_p = acpi_initrd_files[no].data; phys_addr_t size = acpi_initrd_files[no].size; phys_addr_t dest_addr = acpi_tables_addr + total_offset; phys_addr_t slop, clen; char *dest_p; total_offset += size; while (size) { slop = dest_addr & ~PAGE_MASK; clen = size; if (clen > MAP_CHUNK_SIZE - slop) clen = MAP_CHUNK_SIZE - slop; dest_p = early_ioremap(dest_addr & PAGE_MASK, clen + slop); memcpy(dest_p + slop, src_p, clen); early_iounmap(dest_p, clen + slop); src_p += clen; dest_addr += clen; size -= clen; } } }
bool hibernation_available(void) { return ((nohibernate == 0) && !secure_modules()); }
int main(dword_t mb_magic, struct multiboot_info *mbi) { CORBA_Environment env = idl4_default_environment; int i,j,msg[8] = { 0,0x6100,0x0100,0,0,0,0,0 }; struct mod_list *mods; l4_msgdope_t result; Elf32_Phdr *phdr; l4_threadid_t msvr; int mobj, pagerid, tobj; int blockID=0; int found_root=0; int totalBlock=0; init_global_data(); printf("Booter task (%x) starting, pager is %X\n", booter.raw, sigma0.raw); check_multiboot_header(mb_magic,&mbi); printf("Multiboot header found at %X\n", (dword_t) mbi); mods = (mod_list*) mbi->mods_addr; secure_modules(mods, (int)mbi->mods_count); launch_aux_pager(); task[0].active=1; task[0].root.svr.raw=0; task[0].root.obj=0; task[0].memory.svr=sigma0; task[0].memory.obj=DEFAULT_OBJECT; strncpy(task[0].cmdline,(char*)mods[BOOTER_MODULE_NR].cmdline,MAXLENGTH); task[0].task_id=booter; task[0].owner=booter; // ************************************************************************* // *** bootup sequence if (mbi->mods_count < (BOOTER_MODULE_NR+2)) enter_kdebug("nothing to load"); mods = (struct mod_list *) mbi->mods_addr; nexttask = booter; (void)nexttask.id.task++; for (j=BOOTER_MODULE_NR+1;j<(int)mbi->mods_count;j++) { Elf32_Ehdr *file_hdr; // *** check sanity of elf file file_hdr = (Elf32_Ehdr *) mods[j].mod_start; if (file_hdr->e_ident[EI_MAG0] != ELFMAG0 || file_hdr->e_ident[EI_MAG1] != ELFMAG1 || file_hdr->e_ident[EI_MAG2] != ELFMAG2 || file_hdr->e_ident[EI_MAG3] != ELFMAG3) { i=0; while ((i<MAXBLOCKS) && (block[i].active)) i++; if (i<MAXBLOCKS) { block[i].active=1; block[i].phys_addr=(int)mods[j].mod_start; block[i].capacity=((int)mods[j].mod_end-(int)mods[j].mod_start)/512; block[i].blocksize=512; totalBlock++; if (found_root) { char name[20]; sprintf(name,"hd%c",'a'+(blockID++)); directory_link(dev.svr,dev.obj,3,name,&booter,MAXTASKS+i,&env); } } continue; } if (file_hdr->e_type != ET_EXEC) enter_kdebug("unexpected e_type"); if (file_hdr->e_machine != EM_386) enter_kdebug("not an intel binary"); if (file_hdr->e_version != EV_CURRENT) enter_kdebug("version mismatch?"); if (file_hdr->e_flags != 0) enter_kdebug("unexpected flags?"); if (file_hdr->e_phnum <= 0) enter_kdebug("No loadable program sections"); // *** create the task. this will map the trampoline code into page 0 // of the newly created address space printf("Task %d: %s\n",(int)nexttask.id.task,(char*)mods[j].cmdline); l4_task_new(nexttask, 255, 0, 0, auxpager); // *** if the memory server is already running, make it the new task's // pager. (should be replaced by dynamic object creation) if (j>(BOOTER_MODULE_NR+1)) { if (creator_create(memsvr,DEFAULT_OBJECT,sizeof(api_mem)/sizeof(int), (sdword*)&api_mem,&msvr,&mobj,&env)!=ESUCCESS) enter_kdebug("Memory object creation failed"); memory_set_maxpages(msvr,mobj,99999999,&env); memory_attach(msvr,mobj,&nexttask,&env); memory_get_pagerid(msvr,mobj,&pagerid,&env); l4_ipc_send(nexttask,0,TRAMPOLINE_NEW_PAGER,pagerid,0,L4_IPC_NEVER,&result); } else { msvr = sigma0;mobj=DEFAULT_OBJECT; } // *** allocate struct for the task tobj=0; while ((tobj<MAXTASKS) && (task[tobj].active)) tobj++; if (tobj==MAXTASKS) enter_kdebug("Too many tasks"); task[tobj].active=1; if (found_root) { task[tobj].root.svr=root.svr; task[tobj].root.obj=root.obj; } else { task[tobj].root.svr.raw=0; task[tobj].root.obj=0; } task[tobj].memory.svr=msvr; task[tobj].memory.obj=mobj; strncpy(task[tobj].cmdline,(char*)mods[j].cmdline,MAXLENGTH); task[tobj].cmdline[MAXLENGTH-1]=0; task[tobj].task_id=nexttask; task[tobj].owner=booter; // *** parse all the headers phdr = (Elf32_Phdr *) (file_hdr->e_phoff + (unsigned int) file_hdr); for (i=0;i<file_hdr->e_phnum;i++) if (phdr[i].p_type == PT_LOAD) { // *** notify the trampoline l4_ipc_send(nexttask,0,TRAMPOLINE_RECEIVE,(int)phdr[i].p_vaddr, (int)phdr[i].p_filesz,L4_IPC_NEVER,&result); msg[6]=(int)phdr[i].p_filesz; msg[7]=(int)file_hdr + phdr[i].p_offset; // *** send the string ipc. this will cause a bunch of pagefaults, // which will be handled by the child's pager #ifdef DEBUG printf("Copying segment of size %x from address %x to %x\n",msg[6],msg[7],(int)phdr[i].p_vaddr); #endif l4_ipc_send(nexttask,&msg,0,0,0,L4_IPC_NEVER,&result); // *** zero out any bss segments if (phdr[i].p_memsz>phdr[i].p_filesz) { int zero_base = phdr[i].p_vaddr+phdr[i].p_filesz; int zero_size = phdr[i].p_memsz-phdr[i].p_filesz; #ifdef DEBUG printf("Erasing zone at %x, size %x\n",zero_base,zero_size); #endif l4_ipc_send(nexttask,0,TRAMPOLINE_ZERO_ZONE, zero_base,zero_size,L4_IPC_NEVER,&result); } } // *** if this is the memory server, change the pager to sigma0 if (j==(BOOTER_MODULE_NR+1)) l4_ipc_send(nexttask,0,TRAMPOLINE_NEW_PAGER,sigma0.raw,0,L4_IPC_NEVER,&result); // *** start the program #ifdef DEBUG printf("Jumping to program entry point at %x [objID=%d]\n\n",(int)file_hdr->e_entry,tobj); #endif l4_ipc_send(nexttask,0,TRAMPOLINE_LAUNCH,tobj,file_hdr->e_entry,L4_IPC_NEVER,&result); // *** wait until thread leaves the trampoline code for (i=0;i<3;i++) l4_thread_switch(nexttask); // *** flush the trampoline l4_fpage_unmap(l4_fpage((int)&_trampoline,L4_LOG2_PAGESIZE,0,0),L4_FP_FLUSH_PAGE); // *** see about the supported interfaces if (j==(BOOTER_MODULE_NR+1)) { memsvr=nexttask; if (generic_implements(nexttask,DEFAULT_OBJECT,sizeof(api_creator)/sizeof(int),(sdword*)&api_creator,&env)!=EYES) enter_kdebug("Memory server does not support Creator API"); if (creator_can_create(nexttask,DEFAULT_OBJECT,sizeof(api_mem)/sizeof(int),(sdword*)&api_mem,&env)!=EYES) enter_kdebug("Memory server cannot create memory objects"); } if (!found_root) if (generic_implements(nexttask,DEFAULT_OBJECT,sizeof(api_creator)/sizeof(int),(sdword*)&api_creator,&env)==EYES) if (creator_can_create(nexttask,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)==EYES) { root.svr=nexttask;found_root=1; #ifdef DEBUG printf("Found root nameserver (%X), creating /...\n",root.svr.raw); #endif if (creator_create(root.svr,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&root.svr,&root.obj,&env)!=ESUCCESS) enter_kdebug("Root directory creation failed"); if (creator_create(root.svr,DEFAULT_OBJECT,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&dev.svr,&dev.obj,&env)!=ESUCCESS) enter_kdebug("/dev directory creation failed"); if (generic_implements(root.svr,root.obj,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)!=EYES) enter_kdebug("Defective root directory"); if (directory_link(root.svr,root.obj,3,"dev",&dev.svr,dev.obj,&env)!=ESUCCESS) enter_kdebug("Cannot link dev into /"); if (directory_link(dev.svr,dev.obj,7,"tasksvr",&booter,0,&env)!=ESUCCESS) enter_kdebug("Cannot link tasksvr into /dev/"); for (int i=0;i<MAXBLOCKS;i++) if (block[i].active) { char name[20]; sprintf(name,"hd%c",'a'+(blockID++)); directory_link(dev.svr,dev.obj,3,name,&booter,MAXTASKS+i,&env); } for (int k=0;k<MAXTASKS;k++) if ((task[k].active) && (!task[k].root.svr.raw)) { task[k].root.svr=root.svr; task[k].root.obj=root.obj; } #ifdef DEBUG printf("Root creation completed, all servers notified\n\n"); #endif } (void)nexttask.id.task++; } // *** modify the trampoline to work with elf launcher // *** this is BAD magic! int *m1=(int*)(((int)&_m1)+1); int *m2=(int*)(((int)&_m2)+1); *m1=0x04041001; *m2=0x04041001; if (totalBlock) printf("Created %d block device(s)\n",totalBlock); // *** enter server loop booter_server(); }