Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Bootloadery i programy bare metal.

1.118 Aufrufe

Veröffentlicht am

Droga, którą procesor przebywa od włączenia do uruchomienia systemu operacyjnego, jest długa, kręta i pełna pułapek. Prezentacja nakreśla jej przebieg, ze szczególnym uwzględnieniem niełatwych początków uruchamiania systemu. Aplikacja Hello World była pisana na wiele sposobów, a tutaj pojawi się kolejny: Bare Metal.

Veröffentlicht in: Software
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Bootloadery i programy bare metal.

  1. 1. #2 - BarCamp Semihalf System wbudowany? Zrób to sam! Maciej Czekaj
  2. 2. ● Inżynier systemów wbudowanych ● Linux, ARMv7, ARMv8 Kto mówi?
  3. 3. ● … dużych systemów wbudowanych
  4. 4. Quiz #1 Gdzie jest interakcja z OS? 1 #include <stdio.h> 2 #include <stdlib.h> 3 int main(int argc, char **argv) 4 { 5 char *s = (char *) malloc(64); 6 sprintf(s, "Hello, World! argc = %d", argc); 7 puts(s); 8 return 0; 9 }
  5. 5. Plan 1. Co to jest SOC? 2. Co to jest Bootowanie? 3. Przestrzeń adresowa SOC-a 4. Przestrzeń adresowa programu 5. Mój pierwszy program rozruchowy
  6. 6. Plan 1. Co to jest SOC? 2. Co to jest Bootowanie? 3. Przestrzeń adresowa SOC-a 4. Przestrzeń adresowa programu 5. Mój pierwszy program rozruchowy
  7. 7. SOC od środka Kontroler DDR Kontroler FLASH CPU CPU 0 CPU 1 SRAM ROM UART Kontroler SATA... Wewnętrzna szyna danych
  8. 8. SOC a CPU ● SOC = wszystko na jednym krzemie ○ prawie wszystko za wyjątkiem: ■ pamięci trwałej (FLASH) ■ pamięci operacyjnej (DRAM) ■ zasilania ● CPU = budowa modularna ○ peryferia na zewn szynie, n.p. PCI ● Hybrydy: ○ Intel Xeon D ■ - zintegrowany Ethernet 10G ○ Serwerowe ARM-y:, np ThunderX, X-Gene ■ wewnętrzna i zewnętrzna szyna PCI
  9. 9. Alwinner A20
  10. 10. Cubieboard 2
  11. 11. Plan 1. Co to jest SOC? 2. Co to jest Bootowanie? 3. Przestrzeń adresowa SOC-a 4. Przestrzeń adresowa programu 5. Mój pierwszy program rozruchowy
  12. 12. Bootowanie na SOC-u Allwinner A20 Boot 0 Boot 1 U-Boot Linux Boot ROM 48KB SRAM SDSD DDR SD DDR
  13. 13. Dlaczego tak wiele etapów? ● Ekonomia bootowania: ○ ROM ~ kilka KB kodu, ○ SRAM (cache L1) <= 32 Kb ● Elastyczność ○ U-boot nie musi “znać” całego SOC-a ○ Standardowe ładowanie OS ○ Podział S/W na bloki: ■ firmware platformowy ■ loader ■ OS
  14. 14. Plan 1. Co to jest SOC? 2. Co to jest Bootowanie? 3. Przestrzeń adresowa SOC-a 4. Przestrzeń adresowa programu 5. Mój pierwszy program rozruchowy
  15. 15. Co to jest przestrzeń adresowa? CPU SRAM ROM DDR 32 - bitowa szyna danych ● Jedna szyna na wszystkie dane ● Wartość adresu decyduje o przeznaczeniu ● To jest pamięć fizyczna! ● MMU pozwala “przemapować” ma dowolną przestrzeń wirtualną UART (I/O)
  16. 16. Mapa pamięci Allwinner-a A20 DRAM I/O SRAM Boot ROM 3GB = 0xC000 0000 0x0000 0000 1GB = 0x4000 0000 4GB - 64KB= 0xFFFF 0000 48KB = 0x0000 C000 28MB = 0x01C0 0000 4GB
  17. 17. Plan 1. Co to jest SOC? 2. Co to jest Bootowanie? 3. Przestrzeń adresowa SOC-a 4. Przestrzeń adresowa programu 5. Mój pierwszy program rozruchowy
  18. 18. Quiz #2 Gdzie trafią zmienne? static int x[1]; static int y[1] = {0xbabababa}; void foo(const char *s,int *i, int *j) {} void _start(void) { foo("Hello World", y, x); }
  19. 19. Co robi linker? Idx Name Size VMA LMA File off Algn 0 .text 0000004c 00008094 00008094 00000094 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .rodata 0000000c 000080e0 000080e0 000000e0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .data 00000004 000100ec 000100ec 000000ec 2**2 CONTENTS, ALLOC, LOAD, DATA 3 .bss 00000004 000100f0 000100f0 000000f0 2**2 ALLOC <...> Contents of section .text: <...> Contents of section .rodata: 80e0 48656c6c 6f20576f 726c6400 Hello World . Contents of section .data: 100ec babababa .... <...> ENTRY(_start) SECTIONS { . = 0x2000 .text : { hello.o (.text) *(.text) } .rodata : { *(.rodata) } .data : { *(.data) } .bss : { *(.bss COMMON) } }
  20. 20. Plan 1. Co to jest SOC? 2. Co to jest Bootowanie? 3. Przestrzeń adresowa SOC-a 4. Przestrzeń adresowa programu 5. Mój pierwszy program rozruchowy
  21. 21. Wprowadzenie do ARMv7-a http://www.keil.com/support/man/docs/armasm/armasm_dom1359731128950.htm ● Wszystkie rejestry to 32 bity ● Boot w SVC | HYP | Monitor ● Przełączanie trybu: ○ CPSR (status) ○ SP (stos) ○ PC (bieżąca instrukcja)
  22. 22. CPSR - Current Program Status Register SPSR - Saved Program Status Register http://www.freescale.com/files/training_pdf/FTF/2014/americas/WBNR_FTF2014_NET_F0143.pdf?lang_cd=en
  23. 23. Rozruch Allwinner-a A20 Boot0 wyszukuje program Boot1: 1. Jeśli pin diagnostyczny jest włączony, wchodzi do trybu FEL 2. Zewn karta SD 3. NAND Flash 4. 2-ga karta SD 5. SPI Flash 6. FEL
  24. 24. Tryb diagnostyczny USB: FEL $ fel write 0x2000 image.bin $ fel exe 0x2000 1. Boot0 uruchamia programator USB 2. FEL oczekuje na komendy z zewnątrz, np z PC: a. zapis do pamięci bloku danych (może to być obraz programu) b. zapis do pamięci wartości (np. rejestr) c. odczyt z pamięci wartości (np. rejestr) d. skok pod adres (wykonanie programu)
  25. 25. Schemat działania programu rozruchowego 1. Boot ROM wchodzi w FEL 1.1. Zapis programu pod 0x2000 2. Skok do 0x2000 2.1. Przygotowanie minimalnego środowiska uruch. dla C 3. Skok do main()
  26. 26. Szybki kurs asemblera ARM .global _start _start: /* Zablokuj przerwania , ustaw tryb na SVC */ mrs r0, cpsr @ r0 = rejestr specjalny CPSR bic r0, r0, #0x1f @ r0 &= 0x1f, wyczyść CPSR[0-4] orr r0, r0, #0xd3 @ r0 |= 0xd3 FIQ=0 IRQ=0 tryb=SVC msr cpsr,r0 @ CPSR = r0 /* Zachowaj rejestr sp */ mov r0, sp @ sp = r0, r0=stos dla FEL /* Ustaw nowy stos dla funkcji main() */ ldr sp, =stack_top @ sp = adres symbolu stack_top /* Zachowaj na stosie rejestry sp, lr */ push {r0, lr} bl main @ wywołaj funkcję main /* Przyrwóć ze stosu sp, lr */ pop {r0, lr} mov sp, r0 /* Wróć do trybu FEL */ bx lr @ powrót z funkcji /* Pułapka */ end: b end
  27. 27. Stos programowy sp lr stack_top main - 4 ... .data - 8 Stos Boot0 Kod Boot0 ... ...
  28. 28. Funkcja main() void uart_putc( char c) { while (!TX_READY) ; writel(c, UART_THR); } void uart_puts( const char *s) { while (*s) uart_putc(*s++); } void main(void) { uart_init(); uart_puts( "Hello world! nr"); }
  29. 29. Skrypt linkera ENTRY(_start) SECTIONS { . = 0x2000; /* Zaczynaj od 0x2000 */ .text : { start.o (.text) *(.text) } .rodata : { *(.rodata) } .data : { *(.data) } .stack : { . = ALIGN(8); /* Stos wyrównany do 8 */ . = . + 0x400; /* 1KB */ stack_top = .; } .bss ALIGN(4) : { /* .bss wyrównany do 4 */ bss_start = .; *(.bss COMMON) bss_end = ALIGN(4) /* .bss kończy się wyrównaniem do 4 */; } }
  30. 30. Kompilacja arm-linux-gnueabihf-gcc -g -marm -c -o main.o main.c arm-linux-gnueabihf-gcc -c -o start.o start.S arm-linux-gnueabihf-ld -T image-sram.lds -Ttext=0x2000 main.o start.o -o image.elf - Map=image.map arm-linux-gnueabihf-objcopy -O binary image.elf image.bin ● ld - “surowy” linker (gcc dodaje biblioteki + skrypt) ● objcopy - konwersja pliku wykonywalnego
  31. 31. Źródła ● Boot ROM Allwinner-a ○ https://github.com/allwinner-zh/bootloader/tree/master/basic_loader/boot0 ● U-Boot ○ http://git.denx.de/?p=u-boot.git;a=summary ● Linux Sunxi ○ https://linux-sunxi.org/Main_Page
  32. 32. Dziękuję!
  33. 33. UART /* Piny muszą być wysterowane jako pull- up (wartość 2) dla pinów 22 i 23 portu B */ *PB_PULL1 |= (2 << ((22 - 16) * 2)) | (2 << ((23 - 16) * 2)); /* Aktywuj konfigurację szybkości transmisji */ writel(UART_LCR_DLAB, UART_LCR); /* Ustaw prędkość portu na 115200 baud */ writel(0, UART_DLH); writel(BAUD_115200, UART_DLL); /* Wyłącz konf. trasmisji i ustaw: brak parzystości, 1 bit stopu, długość słowa 8 bitów */ writel(LC_8_N_1, UART_LCR); /* Czekaj 100 cykli */ delay(100); } UART_RBR 0x00 UART Receive Buffer Register UART_THR 0x00 UART Transmit Holding Register UART_DLL 0x00 UART Divisor Latch Low Register UART_DLH 0x04 UART Divisor Latch High Register UART_LCR 0x0C UART Line Control Register void uart_init(void) { volatile uint32_t *uart_clock = (uint32_t *) 0x01C2006C; ... /* Włączenie zegara dla urządzenia UART na szynie APB */ *uart_clock &= ~(1 << (16 + UART_PORT)); /* Trzeba odczekać parę cykli zegara */ delay(100); *uart_clock |= (1 << (16 + UART_PORT)); /* Ustaw piny 22 i 23 portu B na UART0 RX & UART0_TX */ *PB2 |= 2 << 28 | 2 << 24;
  34. 34. Typy pamięci w ARMv7-a ● Normal ○ dostęp niedeterministyczny ○ pamieć operacyjna (SRAM,DDR) ● Strongly Ordered ○ dostęp sekwencyjny (I/O, np. operacje DMA) ● Device ○ dostęp z efektami ubocznymi ○ urządzenia i ich rejestry

×