0% found this document useful (0 votes)
3 views19 pages

Lec 03

Uploaded by

Toriqul Labib
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views19 pages

Lec 03

Uploaded by

Toriqul Labib
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

LEC 03 Md Samin Rahman

BUILD TARGET IMAGES (OS)

In this section, we will look at the


toolchain for building target images, and
introduce a standard object file format—
ELF. As a case study, we will also
examine the image building process for
embedded systems that rely on the QNX
operating system.
Cross-Development Toolchain:
 Figure 2.2 shows the code transformation
process involving a chain of cross-
development tools: cross compiler/assembler,
linker, and dynamic linker
Cross Compiler/Assembler Compilers and
assemblers are essential tools in software
development, especially when dealing with
different hardware and software environments.
Here’s a breakdown of what a cross compiler and a
cross assembler are, how they work, and their
applications:
Native Compiler vs. Cross Compiler:
Native Compiler: A native compiler generates
executable code for the same platform on which it
runs. For example, if you’re compiling code on a
Windows machine and the output is intended to
run on that same Windows machine, you’re using
a native compiler.
Cross Compiler: A cross compiler generates
executable code for a different platform from the
one it is running on. This means you can compile
code on one system (the host) to run on another
system (the target), which might have different
hardware or operating system specifications.
Cross Assembler: A cross assembler is similar to a
cross compiler but works with assembly language
source files. It assembles code for a target platform
different from the one on which the assembler runs.
Why Use a Cross Compiler/Assembler?
Limited Resources on Target Platforms:
Target platforms, such as embedded
systems, often have limited resources and
might not be powerful enough to run a native
compiler. In these cases, a cross compiler can
be used on a more powerful host machine to
generate executable code for the resource-
constrained target system.
Multiple Target Platforms: When a project
needs to run on various target platforms—
such as different processor types, operating
system versions, or even different operating
systems—a cross compiler allows you to set
up a single development environment on the
host machine that can compile code for all
these different targets.
Object Files and Symbol Tables
Object Files: During compilation, the cross
compiler/assembler generates object files. Each
object file contains compiled code and data,
which is a part of the final executable. For
instance, if you compile two source files, you will
get two object files, such as one.o and two.o.
Symbol Tables:
 Each object file includes a symbol table, which is a data
structure that holds information about symbols in the
code. These symbols include:
 Global Symbols: Names of global variables and non-static functions
defined in the compilation unit.
 External Symbols: Symbols with external linkage that are referenced
but defined elsewhere.
 The symbol table helps the compiler and linker locate
and manage symbolic definitions and references. It
includes:
 Global Symbol Definitions: For example, in one source file (one.c),
global symbols might include variables and functions like c, sa, sb, and
main().
 External Symbol References: For symbols defined in other files, such as a
and b() referenced in one.c but defined elsewhere.
 Local Symbols: Local variables with static storage duration,
like temp, are also included in the symbol table but are
only visible within their respective compilation units.
Linker: A linker is a crucial component in the software
development process, responsible for combining
multiple object files into a single executable or
shared object file. This process ensures that the
various pieces of code and data defined across
different files work together seamlessly.
Symbol Resolution is the first major task performed
by the linker. When a linker processes an application,
it needs to resolve symbols with external linkage,
which means identifying where each symbol is
defined and ensuring that all references to these
symbols are correctly matched. Symbols can be
variables or functions defined across different
object files. The linker must also consider symbols from
application-independent libraries, such as standard
functions (e.g., printf) that are used in many programs.
If two variables have the same name but are
defined in different files, the linker differentiates
them using their file context. For instance, if a
variable named sb is declared in both one.c and
two.c, the linker treats these as separate symbols due
to their distinct origins.
Symbol Relocation is the second major task of
the linker. Once the linker has resolved all
symbols and their locations, it adjusts the
addresses of these symbols in the final object
file. During the linking process, the addresses of
symbols may need to be updated to reflect their
actual locations in memory. This adjustment is
managed through a relocation table, which
keeps track of where symbols are placed and
helps the linker modify the binary code
accordingly. Essentially, relocation ensures that
the code and data from different object files are
correctly positioned and referenced in the final
executable.
The linker can produce three different types
of object files:
 Relocatable File:
 Definition: A relocatable file is an intermediate object file
generated by a compiler. It contains machine code but is not
yet linked to other object files or libraries.
 Purpose: This file contains code and data that can be
relocated to different addresses in memory. It is designed to
be linked with other relocatable files to produce an
executable or a shared object file.
 File Extensions: Common extensions include .o (object file) or
.obj.
 Shared Object File:
 Definition: A shared object file is a dynamically linked library
that can be shared among multiple programs. It contains code
and data that can be loaded into memory and used by
applications at runtime.
 Purpose: These files allow code to be reused across different
programs, which can reduce memory usage and disk space.
They also support dynamic linking, where the linking is done at
runtime rather than compile time.
 File Extensions: Common extensions include .so (on Linux) and
.dll (on Windows).
The linker can produce three different types
of object files:
 Executable File:
 Definition: An executable file is a binary file that is
ready to be run by the operating system. It is the final
product after linking all object files and libraries
together.
 Purpose: This file contains the complete machine code
necessary to execute a program. It can be directly
executed by the operating system to run the program.
 File Extensions: Common extensions include .exe (on
Windows) and no extension or .out (on Linux).
Dynamic Linker: When an object file needs to
be executed, it must be loaded into the
computer's RAM. This task is handled by a
special program called a program interpreter.
The program interpreter is essentially an
executable or shared object file that is capable
of running other programs. It provides the
necessary environment for the object file to
execute by managing its loading and execution
process.
Program Loader: is a basic type of program
interpreter. Its primary job is to load an
executable file into memory and then transfer
control to that file so it can start running. This
approach works well for stand-alone executable
files, which include all the necessary library
routines embedded within them. While this makes
the executable file easier to distribute—since it
does not depend on external libraries—it also
results in larger file sizes and greater memory
usage, as each copy of the executable contains
its own libraries.
In contrast, some programs do not contain all
the library routines directly within the
executable file. Instead, they include only
references to shared library routines. This
means that the actual library files need to be
present on the target system for the program to
run. To handle this, a more sophisticated type of
program interpreter called a dynamic linker is
used.
The dynamic linker performs several tasks:
 Initial Loading: It first loads the entire program into
memory, creating an initial process image. This process
includes setting up the memory space where the
program will run.
 Dynamic Linking: Next, it resolves any symbolic
references in the program by dynamically loading and
binding the required external shared libraries. This step
effectively completes the process image by linking the
necessary libraries at runtime.
 Control Transfer: Finally, the dynamic linker transfers
control to the process, allowing the program to start
execution.
Dynamic linking has significant advantages. One
major benefit is that multiple applications can
share a single copy of a library, which reduces
memory usage and storage requirements.
Additionally, if a shared library is updated with
bug fixes or improvements, all programs using
that library can automatically benefit from
these changes without needing to be
recompiled or redistributed. This makes dynamic
linking a powerful tool for managing software
dependencies and keeping systems up-to-date.
BUILD TARGET IMAGES

Case Study: Building a QNX Image


 A QNX image is a holistic executable file
containing both the QNX operating system and
user applications, designed to run on a specific
target board. This process involves creating a
single integrated image that can be loaded
and executed on the target hardware.
 A QNX image refers to the file or binary that contains a
complete QNX operating system environment, which is
used for embedded systems. QNX is a real-time operating
system known for its reliability and efficiency in handling
time-critical tasks.
 The image is typically written to a storage medium such
as flash memory, a hard drive, or other types of persistent
storage within the embedded device. Once deployed, it
allows the device to boot up and run the QNX operating
system.
A "QNX image" is essentially a single, comprehensive
executable file that combines both user applications
and the QNX operating system. Building a QNX
image for a specific target board involves several
steps to ensure that the software is compatible with
the hardware it will run on. The process typically
begins with obtaining a board support package
(BSP), which is a crucial software component
designed to support the specific hardware design
of the target board. Most commercial evaluation
boards come with a sample BSP, which is highly
beneficial as it saves developers a significant amount
of time and effort that would otherwise be spent
writing low-level software from scratch.
A QNX BSP typically includes an initial program
loader, which is necessary for loading the QNX
operating system onto the board, and a startup
module that contains all the device drivers required
for the hardware. This startup module is essential
because it provides the necessary instructions for
the operating system to communicate effectively with
the various hardware components of the board, such
as the CPU, memory, and input/output devices.
To bring all these components together, a system builder
project is needed. This project serves as a framework for
integrating the different parts of the software and
hardware support. The system builder project is processed
by a utility called "mkifs" (make image filesystem). The
mkifs utility creates a bootable QNX image from the
components specified in a build-script file (often with a
".bld" extension). This script file can be customized to ensure
that the final QNX image contains all the necessary
elements. For example, it includes the startup binary from
the BSP, the QNX kernel, and relevant shared library
objects that are essential for the operating system's core
functions. Additionally, it incorporates application-specific
binaries, which are generated from user projects, and
other relevant libraries and utilities required for the
software to function correctly.
 The startup binary is an executable file that is loaded first when
an embedded system powers up. It initializes the hardware and
sets up the system environment.
 The BSP is a collection of software and configuration files that
support the specific hardware of an embedded system. It includes
drivers, initialization code, and other hardware-specific
components.
 The QNX kernel is the core part of the QNX operating system
that manages system resources and hardware interactions. It
handles process management, memory management, and
hardware communication.
The final QNX image for an embedded system
consists of two main parts: the initial program
loader (provided by the BSP) and the bootable
QNX image created by mkifs. The initial
program loader is responsible for loading the
QNX operating system and user applications into
memory when the embedded system starts up.
Meanwhile, the bootable QNX image contains
all the necessary software components for the
system to operate, including the operating system
kernel, device drivers, user applications, and
various utilities. This comprehensive image
ensures that the embedded system is fully
functional and capable of running the desired
software in a stable and efficient manner.
Transferring an executable file object to the target
system typically involves using a utility known as a
"programmer." This utility is responsible for writing the
executable file to the non-volatile memory (NVM), such
as ROM or flash memory, on the target system. The
process is sometimes referred to as "high-voltage
programming," which ensures that the data is correctly
written to the memory, even if the memory type
requires higher voltage levels to accept new data.
For example, in the process of building a QNX image
for a specific target board, a programmer called SAM-
BA (Software Atmel Microcontroller Boot Assistant) is
used to transfer the final QNX image to the target
board. SAM-BA is a commonly used tool that facilitates
the communication between a development system
and a target board, allowing the transfer of
executable files over various interfaces, such as USB
or serial ports.
Once the executable file object is successfully
transferred and stored in the NVM on the target board,
it becomes accessible to the processor. At this point, the
processor can execute the file, which means the target
platform is ready to run the embedded system
application or operating system contained within the
transferred executable. This process is crucial for
deploying software to embedded systems, ensuring that
the final executable is properly loaded and ready for
operation in the target environment.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy