1 / 28

9. 부트로더 분석

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

trent
Download Presentation

9. 부트로더 분석

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 9. 부트로더 분석

  2. 9. 부트로더 분석 • BLOB 실행 흐름 • BLOB Memory map • BLOB object 구조 • 주요 소스 코드 분석 • BLOB 기능 추가 하기 www.huins.com

  3. 메모리 메모리 초기화 초기화 start.S 하드웨어 하드웨어 초기와 초기와 시리얼 시리얼 초기화 초기화 main() 타임머 타임머 초기화 초기화 , , 커널 커널 램디스크를 램디스크를 램에 램에 복사 복사 10 10 10 10 초간 초간 가다린후 가다린후 실행 실행 키가 키가 초안에 초안에 누렸을때 누렸을때 명령어 명령어 모드 모드 run command run command GetCommand GetCommand () () 커널로 커널로 점프 점프 () () SetClock SetClock () Download() Download() Flash() Flash() ...... ...... boot_linux () () boot_linux Auto Boot Auto Boot Manual Boot Manual Boot 9. 부트로더 분석 www.huins.com

  4. 9. 부트로더 분석 SDRAM (128M) FLASH ROM (32M) www.huins.com

  5. 9. 부트로더 분석 • BLOB는 2가지 stage로 구분 된다. • start.S 로 시작하는 하드웨어의 기본적인 초기화를 담당하는 start stage • Trampoline.S로 시작하는실질 적인 기능을 담당하는 rest stage • Start stage • flash memory의 0x0번지 부터 위치하여 수행된다. • cpu, memory 등 기본적인 하드웨어 초기화 • 모두 assembly 코드 • Rest stage • flash memory의 0x400번지 부터 위치하고 sdram으로 copy된 후 실행 된다. • 실제적인 boot loader의 기능을 수행한다. • 대부분 c 코드로 구성 www.huins.com

  6. 9. 부트로더 분석 _start(start.S)를 가장 처음 실행할 루틴으로 지정 • 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) } } www.huins.com

  7. 9. 부트로더 분석 • 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 = .; } … } www.huins.com

  8. 9. 부트로더 분석 • 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) www.huins.com

  9. 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 $@ … www.huins.com

  10. BLOB-start (1Kbyte) BLOB-rest (63Kbyte) 9. 부트로더 분석 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 BLOB www.huins.com

  11. 9. 부트로더 분석 • 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 www.huins.com

  12. 9. 부트로더 분석 • 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 … www.huins.com

  13. 9. 부트로더 분석 • 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 www.huins.com

  14. 9. 부트로더 분석 • 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 www.huins.com

  15. 9. 부트로더 분석 • 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 www.huins.com

  16. 9. 부트로더 분석 • 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; www.huins.com

  17. 9. 부트로더 분석 • 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 적재 www.huins.com

  18. 9. 부트로더 분석 • 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"); } www.huins.com

  19. 9. 부트로더 분석 • 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 */ www.huins.com

  20. 9. 부트로더 분석 • 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);} /* 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 } /* rest-ld-script */ … . = ALIGN(4); .initlist : { __initlist_start = .; *(.initlist) __initlist_end = .; } www.huins.com

  21. 9. 부트로더 분석 • 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); www.huins.com

  22. 9. 부트로더 분석 • 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 } www.huins.com

  23. 9. 부트로더 분석 • init_command()/commands.c /* rest-ld-script */ … . = ALIGN(4); .commandlist : { __commandlist_start = .; *(.commandlist) __commandlist_end = .; } 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); /* 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); www.huins.com

  24. 9. 부트로더 분석 • 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; www.huins.com

  25. 9. 부트로더 분석 • 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]); www.huins.com

  26. 9. 부트로더 분석 • 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; } www.huins.com

  27. 9. 부트로더 분석 • 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); www.huins.com

  28. 9. 부트로더 분석 • 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); www.huins.com

More Related