def _init_elf_file(pd_el, image, pd_namespace, machine, pools, bootinfo, pd, kernel): elf = UnpreparedElfFile(filename=os.path.join(pd_el._path, pd_el.file)) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." segment_els = pd_el.find_all_children("segment") segs = collect_elf_segments(elf, image.PROGRAM, segment_els, pd_el.name, [], pd_namespace, image, machine, pools) segs_ms = [bootinfo.record_segment_info(pd_el.name, seg, image, machine, pools) for seg in segs] for seg_ms in segs_ms: pd.attach_memsection(seg_ms) # Record any patches being made to the program. patch_els = pd_el.find_children("patch") collect_patches(elf, patch_els, os.path.join(pd_el._path, pd_el.file), image) # Collect threads in the PD. elf = pd.elf = elf.prepare(image.wordsize, image.endianess) return elf, segs
def collect_extension_element(extension_el, pd, namespace, rp_elf, image, machine, bootinfo, pools): # New namespace for objects living in the extension. extn_namespace = namespace.add_namespace(extension_el.name) elf = None start = None name = None physpool = getattr(extension_el, 'physpool', None) pager = getattr(extension_el, 'pager', None) direct = getattr(extension_el, 'direct', None) # Push the overriding pools for the extension. image.push_attrs(physical=physpool, pager=pager, direct=direct) if hasattr(extension_el, "file"): elf = UnpreparedElfFile(filename=extension_el.file) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." segment_els = extension_el.find_children("segment") segs = collect_elf_segments(elf, image.EXTENSION, segment_els, extension_el.name, extn_namespace, image, machine, pools) segs_ms = [ bootinfo.record_segment_info(extension_el.name, seg, image, machine, pools) for seg in segs ] for seg_ms in segs_ms: pd.attach_memsection(seg_ms) # Record any patches being made to the program. patch_els = extension_el.find_children("patch") collect_patches(elf, patch_els, extension_el.file, image) start = elf.entry_point name = extension_el.file if hasattr(extension_el, "start"): start = extension_el.start name = extension_el.name # If no file is supplied, look for symbols in the root # program. if elf is None: elf = rp_elf elf = elf.prepare(elf.wordsize, elf.endianess) start = start_to_value(start, elf) bootinfo.add_elf_info(name=name, elf_type=image.EXTENSION, entry_point=start) image.pop_attrs()
def collect_xml(self, iguana_el, ignore_name, namespace, machine, pools, kernel, image): """Handle an Iguana Server Compound Object""" cell = \ kernel.register_cell(iguana_el.name, iguana_el.kernel_heap, max_caps = getattr(iguana_el, "caps", None)) # New namespace for objects living in the root program's PD. ig_namespace = namespace.add_namespace(iguana_el.name) self.namespace = ig_namespace self.s_namespace = self.namespace self.name = iguana_el.name self.space = \ cell.register_space(self.namespace, "MAIN", is_privileged = True, max_clists = getattr(iguana_el, "clists", None), max_spaces = getattr(iguana_el, "spaces", None), max_mutexes = getattr(iguana_el, "mutexes", None), max_threads = getattr(iguana_el, "threads", None), plat_control = \ getattr(iguana_el, "platform_control", False)) self.setup_bootinfo_pools(namespace, pools) self.setup_device_namespace(namespace, machine) self.env = CellEnvironment(iguana_el.name, self.namespace, machine, image, kernel, self.space.mappings) cell.env = self.env pd = weaver.cells.iguana.bootinfo.RootServerPD(iguana_el.name, ig_namespace) # Declare the default memory pools. def_virtpool = getattr(iguana_el, "virtpool", pools.get_default_virtual_pool()) def_physpool = getattr(iguana_el, "physpool", pools.get_default_physical_pool()) def_pager = getattr(iguana_el, "pager", None) def_direct = getattr(iguana_el, "direct", None) # Record any IRQs that are assigned to Iguana for irq_el in iguana_el.find_children("irq"): self.space.register_irq(irq_el.value) self.bootinfo.set_system_default_attrs(def_virtpool, def_physpool, image, def_pager, def_direct) # Iguana is not aware of segment ids. # The old mapping API uses segment 0 for all mapping ops. # Segment 0 needs to cover all of physical memory. # Subsequent segments will be created but never used, # but must still be mapped! # XXX: VVVVV THIS IS PURE EVIL VVVVV physpool_attrs = \ image.new_attrs(self.s_namespace.add_namespace("physpool_hack")) physpool_attrs.phys_addr = 0 #first_phys_base physpool_attrs.size = 0xfffff000 #first_phys_end physpool_attrs.attach = PF_R | PF_W | PF_X physpool_attrs.cache_policy = 0xff # XXX: Define me properly physpool_attrs.mem_type = physpool_attrs.unmapped self.space.register_mapping(physpool_attrs) # XXX: ^^^^^ THIS IS PURE EVIL ^^^^^ filename = os.path.join(iguana_el._path, iguana_el.file) elf = UnpreparedElfFile(filename=filename) pd.set_default_pools(image, self.bootinfo) # Collect the object environment pd.add_env_ms(image, ig_namespace, machine, pools) env, extra_ms = \ collect_environment_element(iguana_el.find_child('environment'), ig_namespace, machine, pools, image, self.bootinfo) segment_els = iguana_el.find_children("segment") segs = collect_elf_segments(elf, image.ROOT_PROGRAM, segment_els, filename, [], ig_namespace, image, machine, pools) self.elf_prog_segments = segs for seg in segs: self.space.register_mapping(seg.attrs) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." # Find out which version of libokl4 that iguana was built # against sym = elf.find_symbol("okl4_api_version") if sym == None: raise MergeError("Unable to locate the symbol 'okl4_api_version' " "in file \"%s\". Cells must link with libokl4." % filename) self.api_version = elf.get_value(sym.value, sym.size, elf.endianess) if self.api_version == None: raise MergeError("Unable to read the symbol 'okl4_api_version' in " "file \"%s\". Cells must link with libokl4." % filename) # Record any patches being made to the program. patch_els = iguana_el.find_children("patch") for patch in getattr(Iguana_el, "extra_patches", []): addr = get_symbol(elf, patch[0], True) if addr == None: continue addr = int(addr[0])+ int(patch[1]) new_patch = Patch_el(address=hex(addr), bytes=patch[2], value=patch[3]) patch_els.append(new_patch) collect_patches(elf, patch_els, filename, image) for extension_el in iguana_el.find_children("extension"): if not ignore_name.match(extension_el.name): collect_extension_element(extension_el, pd, ig_namespace, elf, image, machine, self.bootinfo, pools) # Collect the main thread. The root program can only have one # thread, so this call chiefly is used to collect information # about the stack. # # The stack is not set up as a memsection, so it is not put in the # object environment. if not hasattr(iguana_el, 'priority'): iguana_el.priority = 255 thread = collect_thread(elf, iguana_el, ignore_name, ig_namespace, image, machine, pools, self.space, entry = elf.entry_point, name = 'iguana', namespace_thread_name = "main", cell_create_thread = True) pd.add_thread(thread) # Collect the heap. Is there no element, create a fake one for # the collection code to use. # # The heap is not set up as a memsection, so it is not put in the # object environment. heap_el = iguana_el.find_child('heap') if heap_el is None: heap_el = ParsedElement('heap') heap_ms = collect_memsection_element(heap_el, ignore_name, ig_namespace, image, machine, pools) pd.attach_heap(heap_ms) self.space.register_mapping(heap_ms.ms.attrs) self.space.register_mapping(thread.get_stack().get_ms().attrs) self.elf_segments.extend([pd.env_ms.get_ms(), thread.get_stack().get_ms(), heap_ms.get_ms()] + [ms.get_ms() for ms in extra_ms]) pd.add_environment(env) pd.utcb_size = image.utcb_size self.bootinfo.add_rootserver_pd(pd) # And now parse the programs and pd's collect_program_pd_elements(iguana_el, ignore_name, ig_namespace, image, machine, self.bootinfo, pools, kernel, cell)
def collect_xml(self, kernel_el, kernel_heap_size, namespace, image, machine, pools): """Collect the attributes of the kernel element.""" (elf, kernel_file, kernel_tmp) = get_kernel_file(kernel_el, machine) if elf.elf_type != ET_EXEC: raise MergeError, \ "All the merged ELF files must be of EXEC type." # New namespace for objects living in the kernel. kernel_namespace = namespace.add_namespace('kernel') # We setup our kernel type depending on the api version number kern_ver = check_api_versions(elf) if kern_ver == NANO_KERNEL_API_VERSION: self.kernel = NanoKernel(elf, kernel_namespace, machine) else: self.kernel = MicroKernel(kernel_namespace) assert self.total_threads is None self.total_threads = self.kernel.ABSOLUTE_MAX_THREADS # Record the default pools for cells to use if they don't have # defaults set. virtpool = getattr(kernel_el, "virtpool", None) physpool = getattr(kernel_el, "physpool", None) image.set_attrs_stack(def_virt=virtpool, def_phys=physpool) pools.set_default_pools(virtpool, physpool) segment_els = kernel_el.find_children("segment") patch_els = kernel_el.find_children("patch") machine.set_cache_attributes(elf) image.set_kernel(elf) segs = collect_elf_segments(elf, image.KERNEL, segment_els, 'kernel', self.kernel.segment_drops, kernel_namespace, image, machine, pools) # Set base segment self.base_segment = self.kernel.get_base_segment(elf, segs, image) if self.base_segment.attrs.phys_addr is not None and \ (self.base_segment.attrs.phys_addr & ((1024 * 1024) - 1)) != 0: raise MergeError("Physical address of %s must be 1MB aligned!" % self.base_segment.attrs.abs_name()) elf = elf.prepare(elf.wordsize, elf.endianess) # The extra_patches attr may be added by a plugin. for patch in getattr(Kernel_el, "extra_patches", []): addr = get_symbol(elf, patch[0], True) if addr != None: addr = int(addr[0]) + int(patch[1]) new_patch = Patch_el(address=hex(addr), bytes=patch[2], value=patch[3]) patch_els.append(new_patch) collect_patches(elf, patch_els, kernel_file, image) # Collect the config elements, some of these relate to # heap and thread array, so do it first config_el = kernel_el.find_child("config") if config_el is not None: for option in config_el.find_children("option"): self.add_config(option.key, option.value) heap_attrs = image.new_attrs( namespace.root.add_namespace("kernel_heap")) heap_attrs.align = machine.kernel_heap_align heap_el = kernel_el.find_child("heap") if heap_el is not None: heap_attrs.phys_addr = getattr(heap_el, 'phys_addr', heap_attrs.phys_addr) heap_attrs.size = getattr(heap_el, 'size', heap_attrs.size) heap_attrs.align = getattr(heap_el, 'align', heap_attrs.align) # Override the size with the command line value, if present. if kernel_heap_size != 0: heap_attrs.size = kernel_heap_size # Nano needs a heap size set early on # Micro remains unassigned since it will get dynamically calculated later if not heap_attrs.size and isinstance(self.kernel, NanoKernel): heap_attrs.size = self.kernel.DEFAULT_KERNEL_HEAP_SIZE self.heap = image.set_kernel_heap(heap_attrs, machine, pools, self.base_segment.segment, isinstance(self.kernel, NanoKernel)) image.add_group(machine.kernel_heap_proximity, (self.base_segment, self.heap)) self.register_heap(heap_attrs) if isinstance(self.kernel, MicroKernel): image.utcb_size = self.kernel.get_utcb_size(elf, image) self.collect_use_devices(kernel_el, image, machine, pools) if kernel_tmp: kernel_tmp.close()
def collect_pd_element(pd_el, ignore_name, namespace, image, machine, bootinfo, pools): """Collect the attributes of a PD element.""" # New namespace for objects living in the PD. pd_namespace = namespace.add_namespace(pd_el.name) pd = weaver.bootinfo.PD(pd_el.name, pd_namespace, image, machine, pools) virtpool = getattr(pd_el, 'virtpool', None) physpool = getattr(pd_el, 'physpool', None) direct = getattr(pd_el, 'direct', None) pd.set_platform_control(getattr(pd_el, "platform_control", False)) if hasattr(pd_el, 'pager'): pager = make_pager_attr(pd_el.pager) else: pager = None # Push the overriding attributes for the pd. image.push_attrs(virtual = virtpool, physical = physpool, pager = pager, direct = direct) pd.set_default_pools(image, bootinfo) # Collect the object environment env = collect_environment_element(pd_el.find_child('environment'), pd_namespace, machine, pools, image, bootinfo) if hasattr(pd_el, "file"): elf = PreparedElfFile(filename=pd_el.file) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." segment_els = pd_el.find_all_children("segment") segs = collect_elf_segments(elf, image.PROGRAM, segment_els, pd_el.name, pd_namespace, image, machine, pools) segs_ms = [bootinfo.record_segment_info(pd_el.name, seg, image, machine, pools) for seg in segs] for seg_ms in segs_ms: pd.attach_memsection(seg_ms) # Record any patches being made to the program. patch_els = pd_el.find_children("patch") collect_patches(elf, patch_els, image) # Collect threads in the PD. for thread_el in pd_el.find_children('thread'): if not ignore_name.match(thread_el.name): thread = collect_thread(elf, thread_el, ignore_name, pd_namespace, image, machine, pools, entry = "_thread_start") pd.add_thread(thread) # Record the thread and its stack in the environment. env.add_entry(key = thread.get_name(), cap_name = thread.get_name() + '/master') env.add_entry(key = thread.get_name() + "/STACK", cap_name = thread.get_name() + '/stack/master', attach = thread.get_stack().get_attrs().attach) # Collect memsections in the PD. for ms_el in pd_el.find_children('memsection'): if not ignore_name.match(ms_el.name): ms = collect_memsection_element(ms_el, ignore_name, pd_namespace, image, machine, pools) pd.attach_memsection(ms) image.add_group(0, [ms.get_ms()]) env.add_entry(key = ms.get_name(), cap_name = ms.get_name() + '/master', attach = ms.get_attrs().attach) # Collect any zones in the program. for zone_el in pd_el.find_children('zone'): (zone, non_zone_ms) = \ collect_zone_element(zone_el, ignore_name, pd_namespace, pools, image, bootinfo, machine) pd.attach_zone(zone) # Attach zones that aren't part of the zone to the program. for ms in non_zone_ms: pd.attach_memsection(ms) image.add_group(0, [ms.get_ms()]) env.add_entry(key = ms.get_name(), cap_name = ms.get_name() + '/master', attach = ms.get_attrs().attach) pd.add_environment(env) bootinfo.add_pd(pd) image.pop_attrs()
def collect_program_element(program_el, ignore_name, namespace, image, machine, bootinfo, pools): """Collect the attributes of a program element.""" # New namespace for objects living in the program's PD. prog_namespace = namespace.add_namespace(program_el.name) pd = weaver.bootinfo.PD(program_el.name, prog_namespace, image, machine, pools) elf = UnpreparedElfFile(filename=program_el.file) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." bootinfo.add_elf_info(name = program_el.file, elf_type = image.PROGRAM, entry_point = elf.entry_point) pd.elf = elf virtpool = getattr(program_el, 'virtpool', None) physpool = getattr(program_el, 'physpool', None) direct = getattr(program_el, 'direct', None) pd.set_platform_control(getattr(program_el, "platform_control", False)) if hasattr(program_el, 'pager'): pager = make_pager_attr(program_el.pager) else: pager = None # Push the overriding attributes for the program. image.push_attrs(virtual = virtpool, physical = physpool, pager = pager, direct = direct) pd.set_default_pools(image, bootinfo) # Collect the object environment env = collect_environment_element(program_el.find_child('environment'), prog_namespace, machine, pools, image, bootinfo) segment_els = program_el.find_all_children("segment") segs = collect_elf_segments(elf, image.PROGRAM, segment_els, program_el.name, prog_namespace, image, machine, pools) segs_ms = [bootinfo.record_segment_info(program_el.name, seg, image, machine, pools) for seg in segs] for seg_ms in segs_ms: pd.attach_memsection(seg_ms) # Record any patches being made to the program. patch_els = program_el.find_children("patch") collect_patches(elf, patch_els, program_el.file, image) # Collect the main thread. thread = collect_thread(elf, program_el, ignore_name, prog_namespace, image, machine, pools, entry = elf.entry_point, name = program_el.name, namespace_thread_name = "main") pd.add_thread(thread) pd.set_server_thread(thread) # Add the virtual device elements # Virtual devices always get added to the global namespace because they # should be globally unique server_spawn_nvdevs = 0 dev_ns = namespace.root.get_namespace("dev") if dev_ns is None: raise MergeError, "Device namespace does not exist!" for v_el in program_el.find_children('virt_device'): virt_dev = pd.add_virt_dev(v_el.name, program_el.name, pd, thread, server_spawn_nvdevs) create_alias_cap(virt_dev, dev_ns) server_spawn_nvdevs += 1 # Record the main thread and its stack in the environment. env.add_entry(key = "MAIN", cap_name = 'main/master') env.add_entry(key = "MAIN/STACK", cap_name = 'main/stack/master', attach = thread.get_stack().get_attrs().attach) # If marked, sure that the program is exported to every # environment so that it can be found by other programs. # if hasattr(program_el, 'server'): bootinfo.add_server( key = program_el.server, cap_name = prog_namespace.abs_name('main') + '/stack/master') # Collect remaining threads. elf = pd.elf = pd.elf.prepare(image.wordsize, image.endianess) for thread_el in program_el.find_children('thread'): if not ignore_name.match(thread_el.name): thread = collect_thread(elf, thread_el, ignore_name, prog_namespace, image, machine, pools, entry = "_thread_start") pd.add_thread(thread) # Record the thread and its stack in the environment. env.add_entry(key = thread.get_name(), cap_name = thread.get_name() + '/master') env.add_entry(key = thread.get_name() + "/STACK", cap_name = thread.get_name() + '/stack/master', attach = thread.get_stack().get_attrs().attach) # Collect any other memsections in the program. for ms_el in program_el.find_children('memsection'): if not ignore_name.match(ms_el.name): ms = collect_memsection_element(ms_el, ignore_name, prog_namespace, image, machine, pools) pd.attach_memsection(ms) image.add_group(0, [ms.get_ms()]) env.add_entry(key = ms.get_name(), cap_name = ms.get_name() + '/master', attach = ms.get_attrs().attach) # Collect any zones in the program. for zone_el in program_el.find_children('zone'): (zone, non_zone_ms) = \ collect_zone_element(zone_el, ignore_name, prog_namespace, pools, image, bootinfo, machine) pd.attach_zone(zone) # Attach memsections that aren't part of the zone to the program. for ms in non_zone_ms: pd.attach_memsection(ms) image.add_group(0, [ms.get_ms()]) env.add_entry(key = ms.get_name(), cap_name = ms.get_name() + '/master', attach = ms.get_attrs().attach) # Collect the heap. Is there no element, create a fake one for # the collection code to use. heap_el = program_el.find_child('heap') if heap_el is None: heap_el = ParsedElement('heap') heap_ms = collect_memsection_element(heap_el, ignore_name, prog_namespace, image, machine, pools) pd.attach_heap(heap_ms) image.add_group(0, [heap_ms.get_ms()]) # Fill env with default values. env.add_entry(key = "HEAP", cap_name = 'heap/master', attach = heap_ms.get_attrs().attach) env.add_entry(key = "HEAP_BASE", base = heap_ms) env.add_entry(key = "HEAP_SIZE", value = heap_ms.get_attrs().size) pd.add_environment(env) bootinfo.add_pd(pd) image.pop_attrs()
def collect_xml(self, kernel_el, kernel_heap_size, namespace, image, machine, pools): """Collect the attributes of the kernel element.""" (elf, kernel_file, kernel_tmp) = get_kernel_file(kernel_el, machine) if elf.elf_type != ET_EXEC: raise MergeError, \ "All the merged ELF files must be of EXEC type." # New namespace for objects living in the kernel. kernel_namespace = namespace.add_namespace('kernel') # We setup our kernel type depending on the api version number kern_ver = check_api_versions(elf) if kern_ver == NANO_KERNEL_API_VERSION: self.kernel = NanoKernel(elf, kernel_namespace, machine) else: self.kernel = MicroKernel(kernel_namespace) assert self.total_threads is None self.total_threads = self.kernel.ABSOLUTE_MAX_THREADS # Record the default pools for cells to use if they don't have # defaults set. virtpool = getattr(kernel_el, "virtpool", None) physpool = getattr(kernel_el, "physpool", None) image.set_attrs_stack(def_virt = virtpool, def_phys = physpool) pools.set_default_pools(virtpool, physpool) segment_els = kernel_el.find_children("segment") patch_els = kernel_el.find_children("patch") machine.set_cache_attributes(elf) image.set_kernel(elf) segs = collect_elf_segments(elf, image.KERNEL, segment_els, 'kernel', self.kernel.segment_drops, kernel_namespace, image, machine, pools) # Set base segment self.base_segment = self.kernel.get_base_segment(elf, segs, image) if self.base_segment.attrs.phys_addr is not None and \ (self.base_segment.attrs.phys_addr & ((1024 * 1024) - 1)) != 0: raise MergeError("Physical address of %s must be 1MB aligned!" % self.base_segment.attrs.abs_name()) elf = elf.prepare(elf.wordsize, elf.endianess) # The extra_patches attr may be added by a plugin. for patch in getattr(Kernel_el, "extra_patches", []): addr = get_symbol(elf, patch[0], True) if addr != None: addr = int(addr[0])+ int(patch[1]) new_patch = Patch_el(address=hex(addr), bytes=patch[2], value=patch[3]) patch_els.append(new_patch) collect_patches(elf, patch_els, kernel_file, image) # Collect the config elements, some of these relate to # heap and thread array, so do it first config_el = kernel_el.find_child("config") if config_el is not None: for option in config_el.find_children("option"): self.add_config(option.key, option.value) heap_attrs = image.new_attrs(namespace.root.add_namespace("kernel_heap")) heap_attrs.align = machine.kernel_heap_align heap_el = kernel_el.find_child("heap") if heap_el is not None: heap_attrs.phys_addr = getattr(heap_el, 'phys_addr', heap_attrs.phys_addr) heap_attrs.size = getattr(heap_el, 'size', heap_attrs.size) heap_attrs.align = getattr(heap_el, 'align', heap_attrs.align) # Override the size with the command line value, if present. if kernel_heap_size != 0: heap_attrs.size = kernel_heap_size # Nano needs a heap size set early on # Micro remains unassigned since it will get dynamically calculated later if not heap_attrs.size and isinstance(self.kernel, NanoKernel): heap_attrs.size = self.kernel.DEFAULT_KERNEL_HEAP_SIZE self.heap = image.set_kernel_heap(heap_attrs, machine, pools, self.base_segment.segment, isinstance(self.kernel, NanoKernel)) image.add_group(machine.kernel_heap_proximity, (self.base_segment, self.heap)) self.register_heap(heap_attrs) if isinstance(self.kernel, MicroKernel): image.utcb_size = self.kernel.get_utcb_size(elf, image) self.collect_use_devices(kernel_el, image, machine, pools) if kernel_tmp: kernel_tmp.close()
def collect_extension_element(extension_el, pd, namespace, rp_elf, image, machine, bootinfo, pools): # New namespace for objects living in the extension. extn_namespace = namespace.add_namespace(extension_el.name) elf = None start = None name = None physpool = getattr(extension_el, 'physpool', None) pager = getattr(extension_el, 'pager', None) direct = getattr(extension_el, 'direct', None) # Push the overriding pools for the extension. image.push_attrs(physical = physpool, pager = pager, direct = direct) if hasattr(extension_el, "file"): elf = UnpreparedElfFile(filename=extension_el.file) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." segment_els = extension_el.find_children("segment") segs = collect_elf_segments(elf, image.EXTENSION, segment_els, extension_el.name, extn_namespace, image, machine, pools) segs_ms = [bootinfo.record_segment_info(extension_el.name, seg, image, machine, pools) for seg in segs] for seg_ms in segs_ms: pd.attach_memsection(seg_ms) # Record any patches being made to the program. patch_els = extension_el.find_children("patch") collect_patches(elf, patch_els, extension_el.file, image) start = elf.entry_point name = extension_el.file if hasattr(extension_el, "start"): start = extension_el.start name = extension_el.name # If no file is supplied, look for symbols in the root # program. if elf is None: elf = rp_elf elf = elf.prepare(elf.wordsize, elf.endianess) start = start_to_value(start, elf) bootinfo.add_elf_info(name = name, elf_type = image.EXTENSION, entry_point = start) image.pop_attrs()
def collect_rootprogram_element(parsed, ignore_name, namespace, image, machine, bootinfo, pools): """Handle an Iguana Server Compound Object""" # Find the tag root_program_el = parsed.find_child("rootprogram") assert(root_program_el is not None) # New namespace for objects living in the root program's PD. rp_namespace = namespace.add_namespace('rootprogram') pd = weaver.bootinfo.RootServerPD('rootserver', rp_namespace, image, machine, pools) # Declare the default memory pools. def_virtpool = getattr(root_program_el, "virtpool", None) def_physpool = getattr(root_program_el, "physpool", None) def_pager = getattr(root_program_el, "pager", None) def_direct = getattr(root_program_el, "direct", None) bootinfo.set_system_default_attrs(def_virtpool, def_physpool, image, def_pager, def_direct) elf = UnpreparedElfFile(filename=root_program_el.file) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." # Record the entry point of the root program so that the kernel # can start it. image.kconfig.set_rootserver_entry(elf.entry_point) pd.set_default_pools(image, bootinfo) # Collect the object environment env = collect_environment_element(root_program_el.find_child('environment'), rp_namespace, machine, pools, image, bootinfo) segment_els = root_program_el.find_children("segment") collect_elf_segments(elf, image.ROOT_PROGRAM, segment_els, root_program_el.file, rp_namespace, image, machine, pools) # Record any patches being made to the program. patch_els = root_program_el.find_children("patch") for p in getattr(RootProgram_el, "extra_patches", []): addr = get_symbol(elf, p[0], True) if addr == None: continue addr = int(addr[0])+ int(p[1]) new_patch = Patch_el(address=hex(addr), bytes=p[2], value=p[3]) patch_els.append(new_patch) collect_patches(elf, patch_els, root_program_el.file, image) for extension_el in root_program_el.find_children("extension"): if not ignore_name.match(extension_el.name): collect_extension_element(extension_el, pd, rp_namespace, elf, image, machine, bootinfo, pools) # Collect the main thread. The root program can only have one # thread, so this call chiefly is used to collect information # about the stack. # # The stack is not set up as a memsection, so it is not put in the # object environment. thread = collect_thread(elf, root_program_el, ignore_name, rp_namespace, image, machine, pools, entry = elf.entry_point, name = 'rootprogram', namespace_thread_name = "main") pd.add_thread(thread) # Collect the heap. Is there no element, create a fake one for # the collection code to use. # # The heap is not set up as a memsection, so it is not put in the # object environment. heap_el = root_program_el.find_child('heap') if heap_el is None: heap_el = ParsedElement('heap') heap_ms = collect_memsection_element(heap_el, ignore_name, rp_namespace, image, machine, pools) pd.attach_heap(heap_ms) image.add_group(0, [heap_ms.get_ms()]) pd.add_environment(env) bootinfo.add_rootserver_pd(pd)
def collect_xml(self, okl4_el, ignore_name, namespace, machine, pools, kernel, image): """Handle an Iguana Server Compound Object""" self.cell = \ kernel.register_cell(okl4_el.name, okl4_el.kernel_heap, max_caps = getattr(okl4_el, "caps", None), max_priority = getattr(okl4_el, "max_priority", None)) self.name = okl4_el.name self.namespace = namespace.add_namespace(self.name) self.space = \ self.cell.register_space(self.namespace, "MAIN", is_privileged = True, max_clists = getattr(okl4_el, "clists", None), max_spaces = getattr(okl4_el, "spaces", None), max_mutexes = getattr(okl4_el, "mutexes", None), max_threads = getattr(okl4_el, "threads", None), max_priority = getattr(okl4_el, "max_priority", None), plat_control = \ getattr(okl4_el, "platform_control", False)) image.push_attrs(virtual=getattr(okl4_el, "virtpool", None), physical=getattr(okl4_el, "physpool", None), pager=make_pager_attr(getattr(okl4_el, "pager", None)), direct=getattr(okl4_el, "direct", None)) (self.def_virtpool, self.def_physpool) = image.current_pools() self.collect_mutexes(okl4_el, self.namespace, self.space) env_el = okl4_el.find_child("environment") self.env = CellEnvironment(okl4_el.name, self.namespace, machine, image, kernel, self.space.mappings) if env_el != None: self._collect_environment(env_el, self.env) # Set these up now even though we can't actually assign values # till later self.phys_attrs = image.new_attrs( self.namespace.add_namespace("default_physpool")) self.phys_attrs.attach = PF_R | PF_W | PF_X self.phys_attrs.mem_type = self.phys_attrs.unmapped mapping = self.space.register_mapping(self.phys_attrs) self.env.add_physmem_segpool_entry("MAIN_PHYSMEM_SEGPOOL", mapping) self.virt_attrs = image.new_attrs( self.namespace.add_namespace("default_virtpool")) self.env.add_virtmem_pool_entry("MAIN_VIRTMEM_POOL", self.virt_attrs) self.space.utcb = image.new_attrs( self.namespace.add_namespace("main_utcb_area")) self.space.utcb.attach = PF_R filename = os.path.join(okl4_el._path, okl4_el.file) self.elf = UnpreparedElfFile(filename=filename) if self.elf.elf_type != ET_EXEC: raise MergeError("All the merged ELF files must be of EXEC type.") # Find out which version of libokl4 that the cell was built # against sym = self.elf.find_symbol("okl4_api_version") if sym == None: raise MergeError( "Unable to locate the symbol 'okl4_api_version' in file \"%s\". Cells must link with libokl4." % filename) self.api_version = self.elf.get_value(sym.value, sym.size, self.elf.endianess) if self.api_version == None: raise MergeError( "Unable to read the symbol 'okl4_api_version' in file \"%s\". Cells must link with libokl4." % filename) self.env.add_elf_info_entry(os.path.basename(okl4_el.file), image.PROGRAM, self.elf.entry_point) segment_els = okl4_el.find_children("segment") segs = collect_elf_segments(self.elf, image.PROGRAM, segment_els, filename, [], self.namespace, image, machine, pools) self.elf_prog_segments = segs for seg in segs: self.env.add_elf_segment_entry( okl4_el.name + '.' + seg.attrs.ns_node.name, seg.segment) seg_ns = seg.attrs.ns_node mapping = self.space.register_mapping(seg.attrs) self.add_standard_mem_caps(seg_ns, mapping, seg.attrs) patch_els = okl4_el.find_children("patch") collect_patches(self.elf, patch_els, filename, image) # Record any IRQs that are assigned to the initial program. for irq_el in okl4_el.find_children("irq"): self.space.register_irq(irq_el.value) self.env.add_device_irq_list("NO_DEVICE", [irq_el.value for irq_el \ in okl4_el.find_children("irq")]) # Collect the implicit thread if not hasattr(okl4_el, 'priority'): okl4_el.priority = kernel.kernel.MAX_PRIORITY threads = [] threads.append( self.collect_thread(self.elf, okl4_el, self.namespace, image, machine, pools, kernel, self.space, self.elf.entry_point, "main", True)) # FIXME: Need to check up on actual entry point's for thread_el in okl4_el.find_children("thread"): threads.append( self.collect_thread(self.elf, thread_el, self.namespace, image, machine, pools, kernel, self.space, "thread_start", cell_create_thread=True)) device_mem = \ self.collect_use_devices(okl4_el, self.space, self.namespace, image, machine, pools) memsection_objs = \ self.collect_memsections(okl4_el, self.space, self.namespace, image, machine, pools) # Collect all data for any extra spaces defined in the XML for space_el in okl4_el.find_children("space"): space_ns = self.namespace.add_namespace(space_el.name) space = self.cell.register_space(space_ns, space_el.name, max_priority = getattr(space_el, "max_priority", \ getattr(okl4_el, "max_priority", None))) image.push_attrs(virtual=getattr(space_el, "virtpool", None), physical=getattr(space_el, "physpool", None), pager=make_pager_attr( getattr(space_el, "pager", None)), direct=getattr(space_el, "direct", None)) for thread_el in space_el.find_children("thread"): threads.append( self.collect_thread(self.elf, thread_el, space_ns, image, machine, pools, kernel, space, "thread_start", cell_create_thread=True)) self.collect_mutexes(space_el, space_ns, space) device_mem.extend( self.collect_use_devices(space_el, space, space_ns, image, machine, pools)) memsection_objs.extend( self.collect_memsections(space_el, space, space_ns, image, machine, pools)) self.env.add_kspace_entry(space_el.name + "_KSPACE", space) space.utcb = image.new_attrs( space_ns.add_namespace(space_el.name + "_utcb_area")) space.utcb.attach = PF_R # Weave a kclist for the main space. main_kclist = self.env.add_kclist_entry("MAIN_KCLIST", self.cell) # Weave the root kspace object. main_kspace = self.env.add_kspace_entry("MAIN_KSPACE", self.space) # Weave the root protection domain object. self.env.add_pd_entry("MAIN_PD", self.space, main_kspace, 32, machine.min_page_size(), self.elf) # Find heap and add it heap_el = okl4_el.find_child('heap') if heap_el is None: heap_el = ParsedElement('heap') heap_attr = collect_memobj_attrs(heap_el, self.namespace, image, machine) if heap_attr.size == None: heap_attr.size = DEFAULT_HEAP_SIZE self.heap_ms = image.add_memsection(heap_attr, machine, pools) self.cell.heap = self.heap_ms.attrs mapping = self.space.register_mapping(self.heap_ms.attrs) self.add_standard_mem_caps(heap_attr.ns_node, mapping, heap_attr) self.elf_segments = \ [thread.get_stack_ms() for thread in threads] + \ [self.heap_ms] + memsection_objs + device_mem self.env.add_kernel_info_entry(0, 0, kernel) # Add command line arguments commandline_el = okl4_el.find_child("commandline") if commandline_el is not None: args = [ arg_el.value for arg_el in commandline_el.find_children("arg") ] else: args = [] self.env.add_arg_list(args) self.cell.env = self.env
def collect_kernel_element(parsed, kernel_heap_size, namespace, image, machine, pools): """Collect the attributes of the kernel element.""" kernel_el = parsed.find_child("kernel") if kernel_el is None: return # New namespace for objects living in the kernel. kernel_namespace = namespace.add_namespace('kernel') # Will the kernel be run execute in place? do_xip = hasattr(kernel_el, 'xip') and kernel_el.xip physpool = None if hasattr(kernel_el, 'physpool'): physpool = kernel_el.physpool # Push the overriding physical pool for the kernel. image.push_attrs(physical=physpool) segment_els = kernel_el.find_children("segment") patch_els = kernel_el.find_children("patch") elf = UnpreparedElfFile(filename=kernel_el.file) #elf = PreparedElfFile(filename=kernel_el.file) if elf.elf_type != ET_EXEC: raise MergeError, \ "All the merged ELF files must be of EXEC type." image.set_kernel(elf) segs = collect_elf_segments(elf, image.KERNEL, segment_els, 'kernel', kernel_namespace, image, machine, pools) elf = elf.prepare(elf.wordsize, elf.endianess) base_segment = None if do_xip: (addr, size) = get_symbol(elf, '__phys_addr_ram') image.patch(addr, size, segs[1]) base_segment = segs[1] (addr, size) = get_symbol(elf, '__phys_addr_rom') image.patch(addr, size, segs[0]) else: sdata = get_symbol(elf, '__phys_addr_ram', may_not_exist=True) if sdata is not None: (addr, size) = sdata image.patch(addr, size, segs[0]) base_segment = segs[0] # The extra_patches attr may be added by a plugin. for patch in getattr(Kernel_el, "extra_patches", []): addr = get_symbol(elf, patch[0], True) if addr != None: addr = int(addr[0]) + int(patch[1]) new_patch = Patch_el(address=hex(addr), bytes=patch[2], value=patch[3]) patch_els.append(new_patch) collect_patches(elf, patch_els, kernel_el.file, image) dynamic_attrs = image.new_attrs(None) dynamic_attrs.align = machine.kernel_heap_align max_threads = DEFAULT_KERNEL_MAX_THREADS dynamic_el = kernel_el.find_child("dynamic") if dynamic_el is not None: max_threads = getattr(dynamic_el, 'max_threads', max_threads) dynamic_attrs.align = getattr(dynamic_el, 'align', dynamic_attrs.align) dynamic_attrs.size = max_threads * get_tcb_size(elf, image) array = image.add_kernel_array(dynamic_attrs, pools) image.add_group(machine.kernel_heap_proximity, (base_segment, array)) image.patch(get_symbol(elf, "tcb_array")[0], machine.word_size / 8, array) image.patch( get_symbol(elf, "num_tcbs")[0], machine.word_size / 8, max_threads) heap_attrs = image.new_attrs(None) heap_attrs.size = DEFAULT_KERNEL_HEAP_SIZE heap_attrs.align = machine.kernel_heap_align heap_el = kernel_el.find_child("heap") if heap_el is not None: heap_attrs.phys_addr = getattr(heap_el, 'phys_addr', heap_attrs.phys_addr) heap_attrs.size = getattr(heap_el, 'size', heap_attrs.size) heap_attrs.align = getattr(heap_el, 'align', heap_attrs.align) # Override the size with the command line value, if present. if kernel_heap_size != 0: heap_attrs.size = kernel_heap_size heap = image.set_kernel_heap(heap_attrs, pools) image.add_group(machine.kernel_heap_proximity, (base_segment, heap)) config_el = kernel_el.find_child("config") if config_el is not None: for option in config_el.find_children("option"): image.kconfig.add_config(option.key, option.value) image.pop_attrs()
def collect_kernel_element(parsed, kernel_heap_size, namespace, image, machine, pools): """Collect the attributes of the kernel element.""" kernel_el = parsed.find_child("kernel") if kernel_el is None: return # New namespace for objects living in the kernel. kernel_namespace = namespace.add_namespace('kernel') # Will the kernel be run execute in place? do_xip = hasattr(kernel_el, 'xip') and kernel_el.xip physpool = None if hasattr(kernel_el, 'physpool'): physpool = kernel_el.physpool # Push the overriding physical pool for the kernel. image.push_attrs(physical = physpool) segment_els = kernel_el.find_children("segment") patch_els = kernel_el.find_children("patch") elf = UnpreparedElfFile(filename=kernel_el.file) #elf = PreparedElfFile(filename=kernel_el.file) if elf.elf_type != ET_EXEC: raise MergeError, \ "All the merged ELF files must be of EXEC type." image.set_kernel(elf) segs = collect_elf_segments(elf, image.KERNEL, segment_els, 'kernel', kernel_namespace, image, machine, pools) elf = elf.prepare(elf.wordsize, elf.endianess) base_segment = None if do_xip: (addr, size) = get_symbol(elf, '__phys_addr_ram') image.patch(addr, size, segs[1]) base_segment = segs[1] (addr, size) = get_symbol(elf, '__phys_addr_rom') image.patch(addr, size, segs[0]) else: sdata = get_symbol(elf, '__phys_addr_ram', may_not_exist=True) if sdata is not None: (addr, size) = sdata image.patch(addr, size, segs[0]) base_segment = segs[0] # The extra_patches attr may be added by a plugin. for patch in getattr(Kernel_el, "extra_patches", []): addr = get_symbol(elf, patch[0], True) if addr != None: addr = int(addr[0])+ int(patch[1]) new_patch = Patch_el(address=hex(addr), bytes=patch[2], value=patch[3]) patch_els.append(new_patch) collect_patches(elf, patch_els, kernel_el.file, image) dynamic_attrs = image.new_attrs(None) dynamic_attrs.align = machine.kernel_heap_align max_threads = DEFAULT_KERNEL_MAX_THREADS dynamic_el = kernel_el.find_child("dynamic") if dynamic_el is not None: max_threads = getattr(dynamic_el, 'max_threads', max_threads) dynamic_attrs.align = getattr(dynamic_el, 'align', dynamic_attrs.align) dynamic_attrs.size = max_threads * get_tcb_size(elf, image) array = image.add_kernel_array(dynamic_attrs, pools) image.add_group(machine.kernel_heap_proximity, (base_segment, array)) image.patch(get_symbol(elf, "tcb_array")[0], machine.word_size / 8, array) image.patch(get_symbol(elf, "num_tcbs")[0], machine.word_size / 8, max_threads) heap_attrs = image.new_attrs(None) heap_attrs.size = DEFAULT_KERNEL_HEAP_SIZE heap_attrs.align = machine.kernel_heap_align heap_el = kernel_el.find_child("heap") if heap_el is not None: heap_attrs.phys_addr = getattr(heap_el, 'phys_addr', heap_attrs.phys_addr) heap_attrs.size = getattr(heap_el, 'size', heap_attrs.size) heap_attrs.align = getattr(heap_el, 'align', heap_attrs.align) # Override the size with the command line value, if present. if kernel_heap_size != 0: heap_attrs.size = kernel_heap_size heap = image.set_kernel_heap(heap_attrs, pools) image.add_group(machine.kernel_heap_proximity, (base_segment, heap)) config_el = kernel_el.find_child("config") if config_el is not None: for option in config_el.find_children("option"): image.kconfig.add_config(option.key, option.value) image.pop_attrs()
def collect_rootprogram_element(parsed, ignore_name, namespace, image, machine, bootinfo, pools): """Handle an Iguana Server Compound Object""" # Find the tag root_program_el = parsed.find_child("rootprogram") assert (root_program_el is not None) # New namespace for objects living in the root program's PD. rp_namespace = namespace.add_namespace('rootprogram') pd = weaver.bootinfo.RootServerPD('rootserver', rp_namespace, image, machine, pools) # Declare the default memory pools. def_virtpool = getattr(root_program_el, "virtpool", None) def_physpool = getattr(root_program_el, "physpool", None) def_pager = getattr(root_program_el, "pager", None) def_direct = getattr(root_program_el, "direct", None) bootinfo.set_system_default_attrs(def_virtpool, def_physpool, image, def_pager, def_direct) elf = UnpreparedElfFile(filename=root_program_el.file) if elf.elf_type != ET_EXEC: raise MergeError, "All the merged ELF files must be of EXEC type." # Record the entry point of the root program so that the kernel # can start it. image.kconfig.set_rootserver_entry(elf.entry_point) pd.set_default_pools(image, bootinfo) # Collect the object environment env = collect_environment_element( root_program_el.find_child('environment'), rp_namespace, machine, pools, image, bootinfo) segment_els = root_program_el.find_children("segment") collect_elf_segments(elf, image.ROOT_PROGRAM, segment_els, root_program_el.file, rp_namespace, image, machine, pools) # Record any patches being made to the program. patch_els = root_program_el.find_children("patch") for p in getattr(RootProgram_el, "extra_patches", []): addr = get_symbol(elf, p[0], True) if addr == None: continue addr = int(addr[0]) + int(p[1]) new_patch = Patch_el(address=hex(addr), bytes=p[2], value=p[3]) patch_els.append(new_patch) collect_patches(elf, patch_els, root_program_el.file, image) for extension_el in root_program_el.find_children("extension"): if not ignore_name.match(extension_el.name): collect_extension_element(extension_el, pd, rp_namespace, elf, image, machine, bootinfo, pools) # Collect the main thread. The root program can only have one # thread, so this call chiefly is used to collect information # about the stack. # # The stack is not set up as a memsection, so it is not put in the # object environment. thread = collect_thread(elf, root_program_el, ignore_name, rp_namespace, image, machine, pools, entry=elf.entry_point, name='rootprogram', namespace_thread_name="main") pd.add_thread(thread) # Collect the heap. Is there no element, create a fake one for # the collection code to use. # # The heap is not set up as a memsection, so it is not put in the # object environment. heap_el = root_program_el.find_child('heap') if heap_el is None: heap_el = ParsedElement('heap') heap_ms = collect_memsection_element(heap_el, ignore_name, rp_namespace, image, machine, pools) pd.attach_heap(heap_ms) image.add_group(0, [heap_ms.get_ms()]) pd.add_environment(env) bootinfo.add_rootserver_pd(pd)
def collect_xml(self, okl4_el, ignore_name, namespace, machine, pools, kernel, image): """Handle an Iguana Server Compound Object""" self.cell = \ kernel.register_cell(okl4_el.name, okl4_el.kernel_heap, max_caps = getattr(okl4_el, "caps", None), max_priority = getattr(okl4_el, "max_priority", None)) self.name = okl4_el.name self.namespace = namespace.add_namespace(self.name) self.space = \ self.cell.register_space(self.namespace, "MAIN", is_privileged = True, max_clists = getattr(okl4_el, "clists", None), max_spaces = getattr(okl4_el, "spaces", None), max_mutexes = getattr(okl4_el, "mutexes", None), max_threads = getattr(okl4_el, "threads", None), max_priority = getattr(okl4_el, "max_priority", None), plat_control = \ getattr(okl4_el, "platform_control", False)) image.push_attrs( virtual = getattr(okl4_el, "virtpool", None), physical = getattr(okl4_el, "physpool", None), pager = make_pager_attr(getattr(okl4_el, "pager", None)), direct = getattr(okl4_el, "direct", None)) (self.def_virtpool, self.def_physpool) = image.current_pools() self.collect_mutexes(okl4_el, self.namespace, self.space) env_el = okl4_el.find_child("environment") self.env = CellEnvironment(okl4_el.name, self.namespace, machine, image, kernel, self.space.mappings) if env_el != None: self._collect_environment(env_el, self.env) # Set these up now even though we can't actually assign values # till later self.phys_attrs = image.new_attrs(self.namespace.add_namespace("default_physpool")) self.phys_attrs.attach = PF_R | PF_W | PF_X self.phys_attrs.mem_type = self.phys_attrs.unmapped mapping = self.space.register_mapping(self.phys_attrs) self.env.add_physmem_segpool_entry("MAIN_PHYSMEM_SEGPOOL", mapping) self.virt_attrs = image.new_attrs(self.namespace.add_namespace("default_virtpool")) self.env.add_virtmem_pool_entry("MAIN_VIRTMEM_POOL", self.virt_attrs) self.space.utcb = image.new_attrs(self.namespace.add_namespace("main_utcb_area")) self.space.utcb.attach = PF_R filename = os.path.join(okl4_el._path, okl4_el.file) self.elf = UnpreparedElfFile(filename=filename) if self.elf.elf_type != ET_EXEC: raise MergeError("All the merged ELF files must be of EXEC type.") # Find out which version of libokl4 that the cell was built # against sym = self.elf.find_symbol("okl4_api_version") if sym == None: raise MergeError("Unable to locate the symbol 'okl4_api_version' in file \"%s\". Cells must link with libokl4." % filename) self.api_version = self.elf.get_value(sym.value, sym.size, self.elf.endianess) if self.api_version == None: raise MergeError("Unable to read the symbol 'okl4_api_version' in file \"%s\". Cells must link with libokl4." % filename) self.env.add_elf_info_entry(os.path.basename(okl4_el.file), image.PROGRAM, self.elf.entry_point) segment_els = okl4_el.find_children("segment") segs = collect_elf_segments(self.elf, image.PROGRAM, segment_els, filename, [], self.namespace, image, machine, pools) self.elf_prog_segments = segs for seg in segs: self.env.add_elf_segment_entry(okl4_el.name + '.' + seg.attrs.ns_node.name, seg.segment) seg_ns = seg.attrs.ns_node mapping = self.space.register_mapping(seg.attrs) self.add_standard_mem_caps(seg_ns, mapping, seg.attrs) patch_els = okl4_el.find_children("patch") collect_patches(self.elf, patch_els, filename, image) # Record any IRQs that are assigned to the initial program. for irq_el in okl4_el.find_children("irq"): self.space.register_irq(irq_el.value) self.env.add_device_irq_list("NO_DEVICE", [irq_el.value for irq_el \ in okl4_el.find_children("irq")]) # Collect the implicit thread if not hasattr(okl4_el, 'priority'): okl4_el.priority = kernel.kernel.MAX_PRIORITY threads = [] threads.append(self.collect_thread(self.elf, okl4_el, self.namespace, image, machine, pools, kernel, self.space, self.elf.entry_point, "main", True)) # FIXME: Need to check up on actual entry point's for thread_el in okl4_el.find_children("thread"): threads.append(self.collect_thread(self.elf, thread_el, self.namespace, image, machine, pools, kernel, self.space, "thread_start", cell_create_thread = True)) device_mem = \ self.collect_use_devices(okl4_el, self.space, self.namespace, image, machine, pools) memsection_objs = \ self.collect_memsections(okl4_el, self.space, self.namespace, image, machine, pools) # Collect all data for any extra spaces defined in the XML for space_el in okl4_el.find_children("space"): space_ns = self.namespace.add_namespace(space_el.name) space = self.cell.register_space(space_ns, space_el.name, max_priority = getattr(space_el, "max_priority", \ getattr(okl4_el, "max_priority", None))) image.push_attrs( virtual = getattr(space_el, "virtpool", None), physical = getattr(space_el, "physpool", None), pager = make_pager_attr(getattr(space_el, "pager", None)), direct = getattr(space_el, "direct", None)) for thread_el in space_el.find_children("thread"): threads.append(self.collect_thread(self.elf, thread_el, space_ns, image, machine, pools, kernel, space, "thread_start", cell_create_thread = True)) self.collect_mutexes(space_el, space_ns, space) device_mem.extend( self.collect_use_devices(space_el, space, space_ns, image, machine, pools)) memsection_objs.extend( self.collect_memsections(space_el, space, space_ns, image, machine, pools)) self.env.add_kspace_entry(space_el.name + "_KSPACE", space) space.utcb = image.new_attrs(space_ns.add_namespace(space_el.name + "_utcb_area")) space.utcb.attach = PF_R # Weave a kclist for the main space. main_kclist = self.env.add_kclist_entry("MAIN_KCLIST", self.cell) # Weave the root kspace object. main_kspace = self.env.add_kspace_entry("MAIN_KSPACE", self.space) # Weave the root protection domain object. self.env.add_pd_entry("MAIN_PD", self.space, main_kspace, 32, machine.min_page_size(), self.elf) # Find heap and add it heap_el = okl4_el.find_child('heap') if heap_el is None: heap_el = ParsedElement('heap') heap_attr = collect_memobj_attrs(heap_el, self.namespace, image, machine) if heap_attr.size == None: heap_attr.size = DEFAULT_HEAP_SIZE self.heap_ms = image.add_memsection(heap_attr, machine, pools) self.cell.heap = self.heap_ms.attrs mapping = self.space.register_mapping(self.heap_ms.attrs) self.add_standard_mem_caps(heap_attr.ns_node, mapping, heap_attr) self.elf_segments = \ [thread.get_stack_ms() for thread in threads] + \ [self.heap_ms] + memsection_objs + device_mem self.env.add_kernel_info_entry(0, 0, kernel) # Add command line arguments commandline_el = okl4_el.find_child("commandline") if commandline_el is not None: args = [arg_el.value for arg_el in commandline_el.find_children("arg")] else: args = [] self.env.add_arg_list(args) self.cell.env = self.env