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()