카테고리 없음

Bootloader

twoweeks-within 2024. 11. 29. 18:08


Boot : 시작해서 System을 사용할 수 있는 상태까지의 Sequence
Loader: 뭔가 싣는것
 > ROM에서 RAM으로 뭔가를 싣는 것
>>  Hardware를 정상 사용하도록, 실제 동작이 가능하도록 ROM에서 RAM으로 뭔가를 싣는것

MCP 구성

 

MCP (Multi chip Package) ROM + RAM을 한 package에 담은 chip 
//주로사용 NOR + PSRAM ( NOR MCP ), NAND + SDRAM (NAND MCP) 

 Bootloader가 해야 할 일 > combination에 따라 달라짐

ROM에 담을것 : code, RO (const data), RW 
 // RW: 초기값이 있는 Global 변수 >ROM에 초기값을 담아야함
 //  ZI (Zero Initialized) : 굳이 ROM에 0 담을 필요 X
      > Static 생성X , Dynamic 생성O 
 RAM:  RW, ZI > Variable들> 값을 계속 바꿔줘야함 
  RO >code가 대부분.. MCP의 종류마다 달라짐
    1) NOR MCP: RO는 ROM에서 실행가능 > 복사X
    2) NAND MCP : RO를 ROM에 실행 X ( NAND : XIP 불가) >SDRAM에 복사 > ( XIP 가능)
// XIP : Word단위 Access  > sw Execution 

loading과정 :  ROM > copy > RAM  // ' Bootloader '

MCP에 따라 Loader가 loading해 줘야 하는 것들이 달라짐
 Bootloader :
          NOR MCP : RW, ZI
          NAND MCP : RO, RW, ZI  // RO >XIP 불가하므로 부트로더가 해줘야함

Scatter loading: Load view, Execution view 제공
   1) Load view: Flash (ROM)에 어떻게 담겨 있을 것이냐.
   2) Execution view:  RAM에 어떻게 복사되어서 실행 될 것이냐

Bootloader는 RO, RW, ZI를 어떻게 구분?
  Default Memory Model > Bootloader의 copy동작 // Scatter Loading 사용 X


Linker가 만드는 Symbol (Execution View)

 

RO, RW, ZI 세 개 Section > 각각의 시작 주소와 끝 주소를 Linker가 Symbol로 만들어줌
 ex) RW : Image$$RW$$Base~ Image$$RW$$Limit (정확하게는) Image$$RW$$Limit - 1까지 

 ZI > 0으로 초기화, Image$$ZI$$Base~Image$$ZI$$Limit - 1 까지  >> 0 으로
     Assembly : Symbol 접근 > 양 끝을 |로 막아줌
----------------------------------------------------------------------
ex)
r0, = |Image$$ZI$$Base|
r1, = |Image$$ZI$$Limit|
r2, = 0

begin
str r2, [r0], #4  //  r2 > r0 주소에 저장 > 4만큼 주소증가 ( 다음번지)
cmp r0, r1  // r0 , r1 비교
bne begin // r0, r1 다르면 begin 으로 분기 > 루프반복, 같으면 종료
----------------------------------------------------------------------
 > 초기값이 없는 전역변수가 Default값으로 0을 갖는 비밀! 
 Linker : 초기값이 없는 전역변수를 ZI에 넣어둠 
       > Bootloader:  0으로 채움

armlink:  ZI output section 포함 모든 execution region마다 추가적인 $$ZI$$  symbol 생성
  > ZI: 실제 Load View에는 없지만, Image에는 생성되어야 하는 부분
따로 ZI를 넣지 않은 경우를 제외 > 모든 Region에 $$ZI$$를 init할 수 있도록 Linker가 만듬

 Load는 Base만있음 (Length X) > Load Base <> Image Base 다를 수 있으나 Length는 항상 같음

  Load View에는 ZI가 존재X > Image의 Base와 Length만 있으면됨
 
C file에서도 접근하려면,,
Assembly file : Symbol Access 가능, 적당한 Label > C file접근 
ex) SRAM region의 영역 Access

Load__SRAM__Base
    DCD |Load$$SRAM$$Base|

Image__SRAM__Base
    DCD |Image$$SRAM$$Base|

Image__SRAM__Length
     DCD |Image$$SRAM$$Length|

Image__SRAM__ZI__Base
    DCD |Image$$SRAM$$ZI$$Base|

Image__SRAM__ZI__Length
    DCD |Image$$SRAM$$ZI$$Length|
>>>>>>>>>>>>>

extern byte *Image__SRAM__Base;
extern byte *Image__SRAM__Length;
extern byte *Load__SRAM__Base;
extern byte *Image__SRAM__ZI__Base;
extern byte *Image__SRAM__ZI__Length;

 extern 선언 > byte를 가리키는 Pointer Type으로 선언해서 가져다 쓰면 주소를 가리키는 Pointer로씀
// 1바이트 크기의 데이터가 저장된 메모리 주소를 참조

다른 크기 > casting

SRAM의 RW를 초기화 하는 방법

end_point = (dword *) ( (dword) Image__SRAM__Base + (dword) Image__SRAM__Length);
// base + lengh == 주소의 총길이
for ( src = (dword *) Load__SRAM__Base,
     dst = (dword *) Image__SRAM__Base;
     dst < end_point;
     src++, dst++ )
{
     *dst = *src;
}
// 0x400 == (1KB)
  > Image__SRAM__Base의 0x8000 ~ 0x83FF 영역이 Load__SRAM__Base의 데이터로 채워짐

 Load View의 RW > Execution View의 RW로 변환
  >  Boot loader가 해주는 일 : Load View (ROM) > Execution View (RAM)으로 변환 (복사)


최종정리 - System이 제대로 동작 > 기본적인 Hardware 초기화 작업 설정 필요
 > Reset신호 입력 > 시스템초기화 작업 (Clock, Memory Control initialization, Watch dog timer I/O, MMU, 각 mode stack initialization)을 기본적으로 해줌 > main() 과 같은 C로 구성된 함수를 호출

------------------------------------------------------------------------------
1) Power-on 또는 reset switch에 의하여 시스템 reset
2) Reset handler로 pc 이동.
3) Interrupt를 Disable하여 Interrupt가 걸리지 않게 막는다.
4) Watch-dog Timer를 initialization
5) System clock을 initialization and setting
6) Memory controller initialization
7) 각 mode들, 즉, SVC, USR, ABT, IRQ, FIQ, Undef 등의 stack을 initialization
8) NAND MCP : RO/ RW를 Execution 주소에 맞게 제대로 복사
    NOR MCP : RW를 Execution 주소에 맞게 제대로 복사
8) ZI 영역을 0으로 
9) main함수 등의 C함수로 branch하여 System을 Start
------------------------------------------------------------------------------

연습문제,, Memory Budget

어떤 Embedded system에 올릴 image의 compile된 내용을 보니 다음과 같더라.
RO, RW, ZI를 각기 전부 다 더했더니 이렇게 되더라.

Code         RO        RW         ZI          Debug
6373664 12805833 569538 15028594 171448836 Grand Totals
================================================================
Total RO Size(Code + RO Data) 19179497 (18729.98kB)
Total RW Size(RW Data + ZI Data) 15598132 (15232.55kB)
Total ROM Size(Code + RO Data + RW Data) 19749035 (19286.17kB) // 약 18MB
=================================================================

어떻게 우리가 필요한 Memory Size를 산정할 수 있을까?
 Total ROM Size :  Code + RO data + RW data
> NOR MCP를 쓰던 NAND MCP를 쓰던 ROM이 꼭 필요한 양 

RAM의 양? 
NOR MCP : Total RW size  
NAND MCP : Total RO + Total RW > SDRAM
>>>>>
NOR MCP ( NOR + PSRAM)
PSRAM : 14.87MB (RW+ZI), NOR : 18.83MB (RO+RW)필요
NAND MCP (NAND + SDRAM)
SDRAM : 33.16MB (RO+RW+ZI), NAND : 18.83MB (RO+RW) 필요

RO data : 
NOR MCP : NOR,
NAND MCP: SDRAM 

//요즘 NAND MCP가 더 많이 사용 
  > 크기대비 저렴

// 헷갈림 방지
Load = Load View = ROM,
Image = Execution View = RAM


// Bootloader가 하는 일
   Loading +메인시스템이 동작하기 전에 기본적인 하드웨어의 초기화 작업 설정

Reset신호가 입력 > 시스템초기화 작업(Clock configuration, Memory configuration I/O initialization, MMU configuration, 각 Mode Stack 초기화 등)을 기본적으로 해줌

1) Power-on 에 의하여 Reset Vector로 PC가 설정됨
2) Reset handler로 branch
3) 외부의 모든 인터럽트를 받아들이지 않도록 한다.
4) Clock 주파수, PLL등을 초기화 한다.
5) 메모리 제어기를 초기화
6) SVC, USR, ABT, IRQ, FIQ, Undef 등의 stack을 초기화
7) BSS 영역을 초기화 한다.
8) C 함수로 분기하여 메인 프로그램을 시작.