Build Process

SBL build process is implemented in top level build script BuildLoader.py. The following diagram illustrates main steps:

digraph buildsteps {
   bgcolor="transparent";
     compound=true;
     node [fontsize=10, shape=rectangle];
     edge [fontsize=10];

     subgraph cluster_steps {
       label="Build Process"; fontsize=11;
       style="filled,rounded"; color="#F0F0F0";

       "Generate Build Configuration" -> "Generate Configuration Data" -> "Invoke EDK II Build Tools \nto Generate Executables" -> "Assemble Generated Files Into \nOne or More Output Images";

     }
}

The generated files are located in Build/ directory.

The SBL image, configuration data, and (generated) helper scripts, are located in Outputs/ directory.

Note

To assist debugging, the build process also generates SlimBootloader.txt file which contains flash layout details for each component in SBL image.

Boot Flow

SBL uses a linear staged boot flow to initialize platform and launch OS. It consists of four stages:

Stage Description
Stage 1A Pre-memory initialization
Stage 1B Initialize main memory
Stage 2 Post memory initialization: initialize CPU, I/O controllers, devices etc.
Payload Load, verify and launch OS images; or perform firmware update
digraph bootflow {
   bgcolor="transparent";
   rankdir=LR;
     compound=true;
     node [fontsize=10, shape=record, style=rounded];
     edge [fontsize=10];

     subgraph cluster_stages {
       label="Boot Stages"; fontsize=11;
       style="filled,rounded"; color="#F0F0F0";

       "Stage 1A" -> "Stage 1B" -> "Stage 2" -> "Payload";

     }
}

Note

When verified boot is enabled, each current stage verifies the next stage before transferring control to the next. If verification fails, SBL halts the system boot.

End-to-End Call Graph

The function call graph in SBL code from reset vector to OS launch.

|SPN| Calling Graph

Platform Initialization

In SBL, board intialization code is located in Platform/<platform_foo> directory. Each stage provides a ‘hook point’ for board specific code. To port a new board, one should implement changes in BoardInit() function for each stage under Platform/<platform_foo>/Library directory:

VOID
BoardInit (
  IN  BOARD_INIT_PHASE  InitPhase
  );

During board initialization, SBL further divides the flow into multiple phases to provide a fine granularity control. These phases are defined in PlatformService.h:

typedef enum {
  PreTempRamInit     = 0x10,
  PostTempRamInit    = 0x20,
  PreConfigInit      = 0x30,
  PostConfigInit     = 0x40,
  PreMemoryInit      = 0x50,
  PostMemoryInit     = 0x60,
  PreTempRamExit     = 0x70,
  PostTempRamExit    = 0x80,
  PreSiliconInit     = 0x90,
  PostSiliconInit    = 0xA0,
  PrePciEnumeration  = 0xB0,
  PostPciEnumeration = 0xC0,
  PrePayloadLoading  = 0xD0,
  PostPayloadLoading = 0xE0,
  EndOfStages        = 0xF0,
  ReadyToBoot        = 0xF8,
  EndOfFirmware      = 0xFF
} BOARD_INIT_PHASE;