9. 부트로더 분석

28
9. 9. 부부부부 부부 부부부부 부부

Upload: trent

Post on 14-Jan-2016

70 views

Category:

Documents


0 download

DESCRIPTION

9. 부트로더 분석. 9. 부트로더 분석. BLOB 실행 흐름 BLOB Memory map BLOB object 구조 주요 소스 코드 분석 BLOB 기능 추가 하기. 메모리. 메모리. 초기화. 초기화. start.S. 하드웨어. 하드웨어. 초기와. 초기와. 시리얼. 시리얼. 초기화. 초기화. main(). 타임머. 타임머. 초기화. 초기화. ,. ,. 커널. 커널. 램디스크를. 램디스크를. 램에. 램에. 복사. 복사. 10. 10. 10. 10. 초간. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 9.  부트로더 분석

9. 9. 부트로더 분석부트로더 분석

Page 2: 9.  부트로더 분석

www.huins.com 2

BLOB 실행 흐름 BLOB Memory map BLOB object 구조 주요 소스 코드 분석 BLOB 기능 추가 하기

9. 9. 부트로더 분석부트로더 분석

Page 3: 9.  부트로더 분석

www.huins.com 3

boot_linux ()

run command

boot_linux () SetClock () Download() Flash() ......

Auto Boot Manual Boot

GetCommand ()

start.S

커널로점프

명령어모드

메모리초기화하드웨어초기와

시리얼초기화타임머초기화커널,램디스크를램에복사

10초간가다린후실행 키가10초안에누렸을때

main()

()

run command

() SetClock Download() Flash() ......

Auto Boot Manual Boot

GetCommand ()

커널로점프

명령어모드

메모리초기화하드웨어초기와

시리얼초기화타임머초기화커널,램디스크를램에복사

10초간가다린후실행 키가10초안에누렸을때

9. 9. 부트로더 분석부트로더 분석

Page 4: 9.  부트로더 분석

www.huins.com 4

0x01,fff,fff

0x00,480,000

0x00,280,000

0x00,080,000

0x00,040,000

0x00,000,000

JFFS2 27.5 Mbytes

ramdisk.gz 2 Mbytes

zImage 2 Mbytes

parameter 256 Kbytes

BLOB 256 kbytes

FLASH ROM (32M)0xa7,fff,fff |

JFFS2

0xa3,000,000 |

ramdisk.gz

0xa0,700,000 |

BLOB main()

0xa0,400,400 |

BLOB down image

0xa0,300,000 |

zImage

0xa0,008,000

0x00,000,000

|

SDRAM (128M)

9. 9. 부트로더 분석부트로더 분석

Page 5: 9.  부트로더 분석

www.huins.com 5

BLOB 는 2 가지 stage 로 구분 된다 . start.S 로 시작하는 하드웨어의 기본적인 초기화를 담당하는 start s

tage Trampoline.S 로 시작하는 실질 적인 기능을 담당하는 rest stage

Start stage flash memory 의 0x0 번지 부터 위치하여 수행된다 . cpu, memory 등 기본적인 하드웨어 초기화 모두 assembly 코드

Rest stage flash memory 의 0x400 번지 부터 위치하고 sdram 으로 copy 된 후

실행 된다 . 실제적인 boot loader 의 기능을 수행한다 . 대부분 c 코드로 구성

9. 9. 부트로더 분석부트로더 분석

Page 6: 9.  부트로더 분석

www.huins.com 6

start-ld-script

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{

. = 0x00000000;

. = ALIGN(4);

.text : { *(.text) }

. = ALIGN(4);

.rodata : { *(.rodata) }

. = ALIGN(4);

.data : { *(.data) }

. = ALIGN(4);

.got : { *(.got) }

. = ALIGN(4);

.bss : { *(.bss) }}

_start(start.S) 를 가장 처음 실행할 루틴으로

지정

9. 9. 부트로더 분석부트로더 분석

Page 7: 9.  부트로더 분석

www.huins.com 7

rest-ld-script

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

ENTRY(_trampoline)

SECTIONS

{

. = (0xa0400400);

. = ALIGN(4);

.text : {

__text_start = .;

*(.text)

__text_end = .;

}

}

9. 9. 부트로더 분석부트로더 분석

Page 8: 9.  부트로더 분석

www.huins.com 8

Makefile

blob_start_elf32_OBJECTS = start.o testmem.o

blob_rest_elf32_OBJECTS = trampoline.o flashasm.o stack.o testmem2.o \

bootldrpart.o commands.o flash.o initcalls.o linux.o main.o memory.o \

param_block.o partition.o reboot.o uucodec.o scc.o net.o bootp.o tftp.o xmodem.o

blob-start-elf32: $(blob_start_elf32_OBJECTS) $(blob_start_elf32_DEPENDENCIES)

@rm -f blob-start-elf32

$(LINK) $(blob_start_elf32_LDFLAGS) $(blob_start_elf32_OBJECTS) \

$(blob_start_elf32_LDADD) $(LIBS)

blob-rest-elf32: $(blob_rest_elf32_OBJECTS) $(blob_rest_elf32_DEPENDENCIES)

@rm -f blob-rest-elf32

$(LINK) $(blob_rest_elf32_LDFLAGS) $(blob_rest_elf32_OBJECTS) \ $(blob_rest_elf32_LDADD) $(LIBS)

9. 9. 부트로더 분석부트로더 분석

Page 9: 9.  부트로더 분석

www.huins.com 9

Makefile (cont’)

blob-start : blob-start-elf32

$(OBJCOPY) $(OCFLAGS) $< $@

blob-rest : blob-rest-elf32

$(OBJCOPY) $(OCFLAGS) $< $@

blob: blob-start blob-rest

rm -f $@

dd if=blob-start of=$@ bs=1k conv=sync

dd if=blob-rest of=$@ bs=1k seek=1

chmod +x $@

9. 9. 부트로더 분석부트로더 분석

Page 10: 9.  부트로더 분석

www.huins.com 10

BLOB-start

(1Kbyte)

BLOB-rest

(63Kbyte)

BLOB

trampoline.o

flashasm.o stack.o

testmem2.o

bootldrpart.o

commands.o flash.o

initcalls.o linux.o

main.o memory.o

param_block.o

partition.o reboot.o

uucodec.o

scc.o net.o

bootp.o tftp.o

xmodem.o

start.o

testmem.o

9. 9. 부트로더 분석부트로더 분석

Page 11: 9.  부트로더 분석

www.huins.com 11

start.S

.text

// Jump vector table as in table 3.1 in [1] g

.globl _start

_start: b reset

b undefined_instruction

b software_interrupt

b prefetch_abort

b data_abort

b not_used

b irq

b fiq

9. 9. 부트로더 분석부트로더 분석

Page 12: 9.  부트로더 분석

www.huins.com 12

start.S reset:

// At the end of the reset sequence, MMU, Icache, Dcache,

// and write buffer are all disabled.

// Also IRQs and FIQs are disabled in the processor's CPSR

// The operating mode is SVC (supervisory mode), and the

// PC is vectored at 0x00000000. A branch in 0x00000000

// brings us directly here.

// PXA255 Initialization

bl init_xscale

// GPIO Initialization

bl init_gpio

// SDRAM Initialization

bl init_mem

normal_boot:

// check the first 1MB of BLOB_START in increments of 4k

9. 9. 부트로더 분석부트로더 분석

Page 13: 9.  부트로더 분석

www.huins.com 13

start.S

relocate:

adr r0, _start

// relocate the second stage loader

add r2, r0, #(64 * 1024) // blob maximum size is 64kB

add r0, r0, #0x400 // skip first 1024 bytes

ldr r1, BLOB_START

copy_loop:

ldmia r0!, {r3-r10}

stmia r1!, {r3-r10}

cmp r0, r2

ble copy_loop

// blob is copied to ram, so jump to it

ldr r0, BLOB_START

mov pc, r0

9. 9. 부트로더 분석부트로더 분석

Page 14: 9.  부트로더 분석

www.huins.com 14

trampoline.S

.text

.globl _trampoline

_trampoline:

/* clear the BSS section */

ldr r1, bss_start

ldr r0, bss_end

sub r0, r0, r1

/* r1 = start address */

/* r0 = #number of bytes */

mov r2, #0

9. 9. 부트로더 분석부트로더 분석

Page 15: 9.  부트로더 분석

www.huins.com 15

trampoline.S

clear_bss:

stmia r1!, {r2}

subs r0, r0, #4

bne clear_bss

/* setup the stack pointer */

ldr r0, stack_end

sub sp, r0, #4

/* jump to C code */

bl main

/* if main ever returns we just call it again */

b _trampoline

bss_start: .word __bss_start

bss_end: .word __bss_end

stack_end: .word __stack_end

9. 9. 부트로더 분석부트로더 분석

Page 16: 9.  부트로더 분석

www.huins.com 16

main()/main.c

int main(void){

init_subsystems();

clientIP = inet_addr(CLIENT_IPADDR);

hostIP= inet_addr(HOST_IPADDR);

TimerInit2();

blob_status.paramType = fromFlash; // or download

blob_status.kernelType = fromFlash;

blob_status.ramdiskType = fromFlash;

blob_status.rootType = fromFlash;

blob_status.usrType = fromFlash;

blob_status.downloadSpeed = baud_115200;

blob_status.terminalSpeed = baud_115200;

blob_status.load_ramdisk = 1;

blob_status.cmdline[0] = '\0';

blob_status.boot_delay = 1;

9. 9. 부트로더 분석부트로더 분석

Page 17: 9.  부트로더 분석

www.huins.com 17

main()/main.c

/* parse the core tag, for critical things like terminal speed */

#ifdef PARAM_START

parse_ptag((void *) PARAM_START, &conf);

#endif

/* get the amount of memory */

get_memory_map();

#ifdef PARAM_START

parse_ptags((void *) PARAM_START, &conf);

#endif

/* Load kernel and ramdisk from flash to RAM */

do_reload("blob"); //BLOB_RAM_BASE 에 blob 를 적재

do_reload("kernel"); //KERNEL_RAM_BASE 에 kernel 적재

do_reload("ramdisk"); //RAMDISK_RAM_BASE 에 ramdisk 적재

9. 9. 부트로더 분석부트로더 분석

Page 18: 9.  부트로더 분석

www.huins.com 18

main()/main.c

EthInit();

/* wait 10 seconds before starting autoboot */

SerialOutputString("Autoboot in progress, press any key to stop ");

for(i = 0; i < blob_status.boot_delay; i++) {

serial_write('.');

retval = SerialInputBlock(commandline, 1, 1);

if(retval > 0)

break;

}

if(retval == 0) {

commandline[0] = '\0';

parse_command("boot");

}

9. 9. 부트로더 분석부트로더 분석

Page 19: 9.  부트로더 분석

www.huins.com 19

main()/main.c

/* the command loop. endless, of course */

for(;;) {

DisplayPrompt("boot> ");

/* wait 10 minutes for a command */

numRead = GetCommand(commandline, MAX_COMMANDLINE_LENGTH, 600);

if(numRead > 0) {

if((retval = parse_command(commandline)) < 0 )

printerror(retval, NULL);

}

}

return 0;

} /* main */

9. 9. 부트로더 분석부트로더 분석

Page 20: 9.  부트로더 분석

www.huins.com 20

init_subsystems()/init.c

void init_subsystems(void)

{

int i;

/* call all subsystem init functions */

for(i = INIT_LEVEL_MIN; i <= INIT_LEVEL_MAX; i++)

call_funcs( (initlist_t *)&__initlist_start, (initlist_t *)&__initlist_end, INIT_MAGIC, i);}

/* rest-ld-script */

. = ALIGN(4);

.initlist : {

__initlist_start = .;

*(.initlist)

__initlist_end = .;

}

/* init.h */

#define __init __attribute__((unused, __section__(".initlist")))

#define __initlist(fn, lvl) \

static initlist_t __init_##fn __init = { \

magic: INIT_MAGIC, \

callback: fn, \

level: lvl }

9. 9. 부트로더 분석부트로더 분석

Page 21: 9.  부트로더 분석

www.huins.com 21

call_funcs()/init.c

static void call_funcs(initlist_t *start, initlist_t *end, u32 magic, int level)

{

initlist_t *item;

for(item = start; item != end; item++) {

if(item->magic != magic) {

printerror(EMAGIC, NULL);

return;

}

if(item->level == level) {

/* call function */

item->callback();

}

}

}

/* init.h */

typedef void(*initfunc_t)(void);

typedef struct {

u32 magic;

initfunc_t callback;

int level;

} initlist_t;

/* pxa255_pro.c */

static void pxa255_pro_init_hardware(void)

{

/* select serial driver */

serial_driver = &pxa255_pro_serial_driver;

}

__initlist(pxa255_pro_init_hardware, INIT_LEVEL_DRIVER_SELECTION);

9. 9. 부트로더 분석부트로더 분석

Page 22: 9.  부트로더 분석

www.huins.com 22

command.h /* command.h */

typedef int(*commandfunc_t)(int, char *[]);

typedef struct commandlist {

u32 magic;

char *name;

char *help;

commandfunc_t callback;

struct commandlist *next;

} commandlist_t;

#define __command __attribute__((unused, __section__(".commandlist")))

#define __commandlist(fn, nm, hlp) \

static commandlist_t __command_##fn __command = { \

magic: COMMAND_MAGIC, \

name: nm, \

help: hlp, \

callback: fn }

9. 9. 부트로더 분석부트로더 분석

Page 23: 9.  부트로더 분석

www.huins.com 23

init_command()/commands.c commandlist_t *commands;

static void init_commands(void)

{

commandlist_t *lastcommand;

commandlist_t *cmd, *next_cmd;

commands = (commandlist_t *) &__commandlist_start;

lastcommand = (commandlist_t *) &__commandlist_end;

cmd = next_cmd = commands;

next_cmd++;

while(next_cmd < lastcommand) {

cmd->next = next_cmd;

cmd++;

next_cmd++;

}

}

__initlist(init_commands, INIT_LEVEL_OTHER_STUFF);

/* rest-ld-script */

. = ALIGN(4);

.commandlist : {

__commandlist_start = .;

*(.commandlist)

__commandlist_end = .;

}

/* main.c */

static int Flash_erase(int argc, char *argv[])

{ … }

static char erasehelp[] = "erase <start> <len>“ \

"flsah erase \n“ \

"erase <start> <len>, ex) erase 180000 200000\n";

__commandlist(Flash_erase, "erase", erasehelp);

9. 9. 부트로더 분석부트로더 분석

Page 24: 9.  부트로더 분석

www.huins.com 24

parse_command()/commands.c

int parse_command(char *cmdline)

{

commandlist_t *cmd;

int argc, num_commands, len;

char *argv[MAX_ARGS];

parse_args(cmdline, &argc, argv);

/* only whitespace */

if(argc == 0)

return 0;

9. 9. 부트로더 분석부트로더 분석

Page 25: 9.  부트로더 분석

www.huins.com 25

parse_command()/commands.c

num_commands = get_num_command_matches(argv[0]);

/* error */

if(num_commands < 0)

return num_commands;

/* no command matches */

if(num_commands == 0)

return -ECOMMAND;

/* ambiguous command */

if(num_commands > 1)

return -EAMBIGCMD;

len = strlen(argv[0]);

9. 9. 부트로더 분석부트로더 분석

Page 26: 9.  부트로더 분석

www.huins.com 26

parse_command()/commands.c

/* single command, go for it */

for(cmd = commands; cmd != NULL; cmd = cmd->next) {

if(cmd->magic != COMMAND_MAGIC) {

return -EMAGIC;

}

if(strncmp(cmd->name, argv[0], len) == 0) {

/* call function */

return cmd->callback(argc, argv);

}

}

return -ECOMMAND;

}

9. 9. 부트로더 분석부트로더 분석

Page 27: 9.  부트로더 분석

www.huins.com 27

boot_kernel()/linux.c

static int boot_linux(int argc, char *argv[])

{

void (*theKernel)(int zero, int arch) = (void (*)(int, int))KERNEL_RAM_BASE;

/* start kernel */

theKernel(0, ARCH_NUMBER);

SerialOutputString("Hey, the kernel returned! This should not happen.\n");

return 0;

}

static char boothelp[] = "boot [kernel options]\n"

"Boot Linux with optional kernel options\n";

__commandlist(boot_linux, "boot", boothelp);

9. 9. 부트로더 분석부트로더 분석

Page 28: 9.  부트로더 분석

www.huins.com 28

Example (command add)

Static int example_command(int argc, char *argv[])

{

int i;

for( I = 0; I < argc; i++ ){

SerialOutputString(“argv[“);

SerialOutputDec(i);

SerialOutputString(“] = \””);

SerialOutputString(“\”\n”);

}

return 0;

}

static char examplehelp[] = “example command\n”;

__commandlist(example_command, “example”, examplehelp);

9. 9. 부트로더 분석부트로더 분석