Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
    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()
Ejemplo n.º 8
0
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()
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
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()
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
0
    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