SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: What is the difference between bootloader, startup code and bootstrap loader?
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

What is the difference between bootloader, startup code and bootstrap loader?

Ryan Ryan
Last updated: September 16, 2023 3:26 am
Ryan Ryan 7 Min Read
Share
SHARE

When an ARM-based system powers on, there are several key software components that run to initialize the hardware and prepare the system for operation. Understanding the differences between these components – the bootloader, startup code, and bootstrap loader – is important for developers working on low-level software.

Contents
BootloaderStartup CodeBootstrap LoaderComparison of FeaturesBoot Sequence OverviewBootloader and Kernel RelationshipStartup Code and Main Kernel RelationshipConclusion

Bootloader

The bootloader is the first piece of software that runs when the system powers on. Its main responsibilities are:

  • Initializing critical hardware components like RAM, clocks, and the MMU
  • Locating, loading, and passing control to the kernel image
  • Providing a user interface for selecting alternate boot configurations or performing low-level tasks like flashing a new firmware image

The bootloader runs in a special execution environment before the OS has been loaded. It has limited access to hardware resources but enough to accomplish its initialization tasks. On ARM systems, common bootloaders include U-Boot, Barebox, and proprietary vendor bootloaders.

Key properties of the bootloader:

  • Executes first after reset
  • Limited scope and capabilities
  • Only runs during the boot phase
  • Responsible for loading the kernel image

Startup Code

The startup code, also known as bootstrapping code, runs immediately after the kernel image is loaded into memory by the bootloader. Its main responsibilities are:

  • Setting up the C runtime environment
  • Initializing CPUs and core components like the GIC
  • Transferring control to the main() function

The startup code provides a bridge between the bootloader environment and the kernel C environment. It is responsible for completing system initialization so that the kernel can begin executing.

Key properties of the startup code:

  • Executes immediately after the kernel is loaded
  • Written in C/assembly language
  • Runs only once during boot
  • Starts main kernel execution

Bootstrap Loader

The bootstrap loader is a simple piece of code that initializes just enough of the system to load a more fully featured bootloader. Its main responsibilities are:

  • Initializing the RAM interface
  • Configuring static memory controllers
  • Loading the bootloader image from storage into RAM and transferring control to it

The bootstrap loader provides essential early initialization before handing off to more sophisticated boot firmware. It may have hard-coded configurations for the bootloader location, memory setup, and peripherals.

Key properties of the bootstrap loader:

  • Executes first out of reset
  • Minimal initialization and error handling
  • Only task is loading the bootloader
  • May be ROM-based or hard-coded flash

Comparison of Features

While the bootloader, startup code, and bootstrap loader work together to boot the system, they have some key differences:

FeatureBootloaderStartup CodeBootstrap Loader
Execution timeAfter bootstrap loaderAfter bootloaderFirst code executed
Functional scopeBroadLimitedMinimal
Code sizeLargeMediumSmall
Execution durationLongerBriefVery brief
Handoff targetKernel imageKernel entry pointBootloader image

Boot Sequence Overview

Here is a high-level overview of the boot sequence on a typical ARM system using these components:

  1. After reset, the hard-coded bootstrap loader runs first. It initializes RAM and loads the bootloader image into RAM.
  2. The bootloader runs next. It does more complete system initialization and includes features like a user interface. It finds the kernel image and loads it into memory.
  3. The bootloader transfers control to the kernel startup code. The startup code sets up the C environment and kernel entry point.
  4. The startup code hands off to the main() kernel function. At this point, full kernel execution begins.

This sequence ensures the processor initializes in a progressive, modular way until the point where the kernel takes over normal system operation.

Bootloader and Kernel Relationship

The bootloader and kernel have distinct roles in the boot process:

  • The bootloader’s job is to load the kernel image into memory and start execution at the kernel’s entry point.
  • The kernel handles all aspects of system management once it takes control from the bootloader.

Ideally, a cleanly delineated handoff occurs between the bootloader and kernel. The bootloader does not depend on any kernel functions, and the kernel does not rely on any bootloader artifacts being present.

Some key ways the bootloader and kernel differ:

  • The bootloader has limited scope focused on initialization tasks. The kernel has broad system capabilities.
  • The bootloader runs in a restricted execution environment separate from the kernel space.
  • The kernel is designed for long-term robustness. The bootloader only needs to run once.

Keeping the bootloader and kernel modular with well-defined interfaces promotes separation of concerns during system startup.

Startup Code and Main Kernel Relationship

The startup code serves as a bridge between the bootloader and kernel environments:

  • It is invoked by the bootloader and handles any machine-dependent setup the kernel needs before main().
  • It calls main() and transfers control to the kernel’s C entry point.

The startup code is part of the kernel package and provides a consistent, portable way to initialize the kernel C environment across platforms. This helps decouple the kernel from machine-specific details.

Some key aspects of the startup code → main() handoff:

  • The startup code sets up stack pointers, CPU modes, and initialization data structures.
  • main() inherits the execution environment created by the startup code.
  • main() does not call back into the startup code during normal operation.

This clean handoff from bootstrap to bootloader to startup code to kernel is key for portability across ARM-based designs.

Conclusion

The bootloader, startup code, and bootstrap loader each perform specific roles in an ordered sequence to boot an ARM system:

  • The bootstrap loader handles the earliest initialization before loading the bootloader.
  • The bootloader initializes hardware and loads the kernel image.
  • The startup code initializes the kernel’s C environment and transfers control to main().

Understanding the responsibilities and interactions between these software components is important for low-level development, debugging, and optimizing performance on ARM platforms.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article How to Reduce Interrupt Latency in RTOS?
Next Article What is the bootloader and startup code in embedded systems?
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

Selecting a Cortex-M0+ MCU for an Industrial Automation Application

Choosing the right microcontroller unit (MCU) is a crucial decision…

8 Min Read

What size instruction is the cortex M0?

The Cortex-M0 is a 32-bit ARM processor core designed for…

6 Min Read

What is zero wait state memory in Arm Cortex-M series?

Zero wait state memory in Arm Cortex-M series microcontrollers refers…

9 Min Read

ARM Cortex M4 Return from Interrupt

Interrupts are a key part of embedded systems programming on…

8 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account