Bootloader study

이재하·2023년 6월 19일
0
  1. 개요

부트로더 사전적 정의

부트로더란 운영체제가 시동되기 이전에 미리 실행되면서
커널이 올바르게 시동되기 위해 필요한 모든 관련 작업을 마무리하고
최종적으로 운영 체제를 시동시키기 위한 목적을 가진 프로그램을 말한다.

즉 임베디드 보드에 전원이 인가되었을 때, 메모리, 하드웨어(네트워크, 프로세서 속도, 인터럽트), 코드/데이터/스택 영역의 설정 및 초기화를 진행하며 커널을 메모리에 적재하여 커널을 실행시키는 역할을 한다.

임베디드 시스템에서 커널이 로딩되고 실행되는 대략적인 과정은 위와 같다.

  1. 부팅 정차

실제 퀄컴, 삼성 등 여러 chip 제조사들에서 제작 하는 ㅊ립 내부에 초기 부팅 과정을 수행하는 코드가 남긴다. Cpu 칩 내부에서 초기 과정을 거쳐 실제 end user 단에서 보이는 uboot 이라던지 등의 우리가 익숙한 부트로더가 수행되는 것.

====
BL2

====
BL1

====
BL0

BL0와 BL1은 Chip Vendor 사에서 제작 및 release 하는 코드 영역이다. 대표적으로 퀼컴, 삼성 등이 있으며 해당 벤더사에서 만드는 CPU가 동작하기 위한 기본 영역이라고 보면된다.

IROM : CPU 내부에 존재하는 ROM 영역
IRAM : CPU 내부에 존재하는 RAM 영역// SRAM 이라고 보면 될듯.
OM : Operation Mode으로 부팅모드를 뜻함.
  • BL0(boot-rom or boot loader))

    • iROM에 저장된 코드 영역 - ROM Code

    • 크게 두가지 작업 수행

      • 디바이스 환경 설정과 프라이머리 페리퍼럴의 초기화
        • 다음 부트로더를 위한 디바이스 준비
    • OM pin으로 부터 부팅 매체를 찾아 BL1을 iRAM(SRAM)으로 읽어들인다. (OM pin은 OneNAND, NAND, MoviNAND, eSSD and iNAND 와 같은 booting device 를 결정한다.

    • 이후 제어권을 BL1으로 넘김.

      BL0은 칩제조사가 생산 시점에서 기록하게 된다.
  • BL(first boot lodaer, SPL)

    • 일반적으로 SRAM이 U-boot와 같은 전체 부트로더를 로드하기에 충분히 크지 않기 때문에 필요한 단계.
    • booting device(부팅 매체)처럼 외부 메모리에 저장 되어 있는 코드 영역.
    • NAND/MMC and DRAM controller 등의 초기화 진행.
    • second bootloader 로딩
    • 부팅 장치(nand 나 sd 카드 ) 에 저당된 BL2를 읽어서 메모리로 로딩 & 실행.
    • 이후 제어권을 BL2로 넘김.
    BL1은 2차벤더가 기록하게 되며 삼성 휴대폰의 경우 삼성 모바일 사업부, ORROID의 경우 HARDKERNEL에서 책임을 담당.
    
  • BL2

    • BL2는 일반적으로 u-boot 이나 BLOB, grub과 같은 널리 알려진 boot loder 가 사용됨.
    • cpu, clock, uart, memory 등의 중요한 초기화 작업 수행.
    • 커널을 dram에 올려 os loading 수행
    • 커널로 제어권 넘김.

부팅흐름

  1. 시스템이 리셋되면 iROM 부터 PC가 시작된다.
  • BL0을 수행하는 단계이다. OM pin으로부터 부팅매체를 찾아 디바이스로 부터 BL1을 iSRAM 으로 읽어드린다.
  1. 제어권을 넘겨받은 BL1은 BL2를 로딩한다.
  • BL1을 수행하는 단계로, 부팅 장치(nand나 sd 카드)에 저장된 BL2를 읽어서 메모리로 로딩 & 실행한다.
  1. BL2는 일반적으로 u-boot나 BLOB,grub과 같은 널리 알려진 boot-loader 가 수행되는 단계이다.
  • BL2를 수행하는 단계로 초기화 작업을 수행한 뒤 커널을 메모리에 올려 로딩한다.
  1. 해당 글은 ARM SECURE BOOT PROCEDURE 와 관련된 내용을 자세히 설명한다.


부팅 흐름

  1. ARM CPU의 전원이 켜지면 PC 레지스터가 IC에 내장된 rom 시작 부분을 가리킨다. 이 rom을 BROM(BOOTROM)이라 하며 부팅 장치의 pre loader를 찾아 isram 에 로드한다.
  • BL0 단계이며 isram 에 로드하는 pre-loader 가 bl1인것 같다.
  • 위 그림의 1~3 단계 설명
  1. Pre-lodaer가 dram을 초기화한 후 부트로더의 2단계 코드를 플래시(nand/emmc)에서 dram으로 로드하여 실행한다. 하드웨어 장치 초기화 시스템 메모리 맵 확인 커널 매개변수 설정 등을 수행한다.
  • BL1를 수행하는 단계로, 부팅 장치(nand나 sd 카드)에 저장된 BL2를 읽어서 메모리로 로딩&실행 하는 과정이다.
  1. dram에 올라온 부팅 이미지(ramdisk,kernel 등)의 압축을 해제한 뒤 dram으로 로드하고 uboot 같은 부트로더가 수행된다.
  • BL2를 수행하는 단계

2.3 참고자료 3

  • 부팅흐름
  1. 1단계 : ROM 코드
    부팅 1 단계로 bootrom ROM 코드가 실행된다. 이후 sram 으로 작은 부트코드를 로드한다. 예를 들면 NAND 플래시 메모리, SPI를 통해 연결된 플래시 메모리, MMC 장치의 첫번째 섹터(SD 카드) 등에서 SPL을 읽는다.
  • BL0 단계로 OM pin을 찾아 BL1을 isram에 올리는 과정이다. SPL이 BL1이라고 보면 될 것 같다.
  1. 2단계 : SPL(Secondary Program Loader)
    SPL은 SRAM에서는 전체부트로더를 로드하기에는 충분히 크지 않기 때문에 필요하다. SPL은 TPL을 DRAM에 로드하도록 메모리 컨트롤러 및 필수 부분의 초기화를 수행한다. uboot.bin과 같은 알려진 파일 이름을 사용하여 프로그램을 메모리에 올린다.
  • BL 단계로 BL2를 메모리에 올리는 과정이다.
  1. 3단계 : TPL(Tertiary Program LoadeR)
    U-Boot 또는 barebox와 같은 전체 부트 로더는 간단한 명령 줄 사용자 인터페이스, 커널 이미지를 네트웍 또는 플래시 저장소에서 로드 및 부팅과 같은 유지 관리 작업을 수행한다.커널이 실행 되면 부트로더는 일반적으로 메모리에서 사라지고 시스템 작동에 더이상 참여하지 않는다.
  • BL2 단계로 최종적으로 커널이 로딩되면 그 이후 제어권은 커널이 갖게된다.

System bootup overview

Samsung chip 부팅 과정
부팅과정
1. BL0 : iROM code(boot-rom)
bootrom 즉 irom에 존재하는 코드가 제일 먼저 실행된다. 이후 부팅 매체(nand, mmc, sd)를 찾아 bl1을 isram에 로드한다.

  1. BL1 : first boot loader
    nand/mmc, dram 컨트롤러를 초기화 하고 second boot loader 즉 bl2를 메모리에 로드한다.

  2. BL2 : Second boot loader
    하드웨어 초기화 및 uboot 같은 우리가 아는 부트로더가 실행되며 최종적으로 커널이 메모리에서 부팅되며 제어권을 커널로 넘긴다.



  1. U-boot 구조 분석

실제 우리가 아는 uboot 같은 부트로더가 실행되기 전까지 어떠한 과정을 거쳐서 부팅이 진행되는 지 살펴 보았다. uboot을 자세히 분석하자.

우선 u-boot의 디렉토리 구조를 보면 다음과 같다.

  • arch
    arm, mips, powerpc 등 프로세서 아키텍처별로 서로 다른 디렉터리를 구성하고 있다. 각 아키텍처에 따른 소스를 구성하는 디렉토리. start.S 가 존재

  • board
    board 와 관련된 코드. 보통 제조사가 만든 보드에 대한 코드가 존재.

  • common
    u-boot에서 공통적으로 사용되는 소스를 구현한 디렉토리

  • disk
    디스크 드라이버와 파티션 관련 코드 존재

  • drivers
    gpio, i2c, pci, serial, usb 등 외부 장치의 드라이버 관련 코드 존재.

  • fs
    u-boot에서 지원하는 다양한 파일 시스템에 대한 소스 존재.

  • lib
    모든 아키텍처와 관련된 라이브러디

  • net
    네트워크 관련 코드

  • post
    power on self test 관련 코드

U-boot code sequence

  1. Disable all interrupts
  2. Copy any initialized data from ROM to RAM
  3. Zero the uninitialized data area
  4. Allocate space for and initialize the stack
  5. Initialize the processor's stack pointer
  6. Create and initialize the heap
  7. Execute the initializers for all global data
  8. Enable interrupts
  9. Call main loop

u-boot의 전체 부팅 시퀀스는 위 그림과 같다. 초기에 모든 인터럽트를 disale 시킨 뒤 ROM의 있는 데이터를 RAM으로 복사한다.

그 다음 초기화 되지 않은 영역을 초기화 시키고 스택 초기화를 진행한다. 그 다음 힙 영역과 global 영역들의 초기화 작업을 진행한 뒤 마지막으로 모든 인터럽트를 다시 enable 한 뒤 main_loop으로 이동한다. 결국 다 초기화와 관련된 작업인 것을 알 수 있다. 어떤 초기화를 수행하는 지 좀 더 자세히 살펴보자.

  1. Reset CPU and Hardware
    start.S 파일은 uboot의 entry point이다. start.S에서는 제일 처음 여러가지 인터럽트와 예외를 처리 할 수 있는 vector table을 설정한다.

.global _start
_start : b reset // reset 함수로 분기
ldr pc, _undefined_instruction //
ldr pc, _software_interrupt //
ldr pc, _prefetch_abort //
ldr pc, _data_abort // 예외 상황에 대한 처리 handler table
ldr pc, _not_used //
ldr pc, _irq //
ldr pc, _fiq //

  1. Diable IRQ & FIQ
    start.S 코드에 보면 reset 함수로 제일 처음 분기를 한다. 해당 작업을 의미하는 것으로 보인다.

    reset :
    /*
    set the cpu to SVC32 mode
    /
    mrs r0, cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0x13
    msr cpsr,r0
    ...

  • rest 함수는 주로 다음의 작업을 수행한다.
    • save_boot_param
    • disable FIQ & IRQ
    • SVC 모드로 전환
    • cpu_init_crit 함수 호출 // in lowlevel_init.S
  1. Low Level initialiation
  • cpu_init_crit 수행
    • I,D Cache 무효화
    • MMU Disable
    • Lowlevel_init() - 함수 호출
  • lowlevel_init() - 하드웨어 초기화 역할
    • uart, PMIC, 메모리 등 초기화
    • board_init_f 호출
  1. Setup SP for Early Baord Setup Environment(ASM->C)
  • crt0.S 에 존재하는 _main 함수 호출

    • setup initial stack & global data
    • and jump to C rountine for board init
  • _main 내부의 board_init_f 함수 호출

    • board_init_f()
      • arch_cpu_init // basic arch cpu dependent setup
      • board_early_init_f // early board initialization, UART pin setting
      • timer_init // initilize timer
      • env_init // initialize mmc/sdcard environment
      • init_baudrate // initialize baudrate settings
      • serial_init // serial communication setup
      • console_init_f // stage 1 init of console, configure console from console.c
      • display_banner // say that we are here, print u-boot banner.
      • checkboard // display board info
      • init_func_i2c // initialize I2C
      • dram_init // configure available RAM backs
      • arm_pci_init
  • board_init_f 내부에서 uboot의 text code를 memory 에 옮김.
    기본적인 초기화 수행 이후 현재코드가 실행되고 있는 위치와 실제 u-boot 가 위치해야하는 주소를 비교하여 relocation 여부를 결정한다. 만약 현재 위치가 u boot 의 실제 실행 위치와 다르면 스스로를 실행위치로 복사한다.

  • start.S의 relocate code 함수 호출

0개의 댓글

관련 채용 정보