Uživatel:FroxDev/Btcode

Z 8.B8 wiki

Přejít na:navigace, hledání
Obsah
1 head.S1.1 entry point1.2 exception_matrix • • 2 inthandler.S2.1 IRQ_finder • • 3 setup.c3.1 init_arch3.2 setup_arch • • 4 traps.c4.1 flush_icache4.2 flush_dcache • • 5 main.c5.1 start_kernel5.2 user_interrupt5.3 check_system_image5.4 uart1_init5.5 set_bridge_clock • • 6 ethInt_8186.c6.1 eth_driver_object_init6.2 eth_startup6.3 eth_hw_reset6.4 eth_desc_init6.5 SetOwnByNic6.6 eth_interrupt • • 7 string.c7.1 memcmp7.2 memcpy • • 8 init.c8.1 serial_outc • • 9 flash.c9.1 flashinit9.2 check_eth_setting9.3 flashread • • 10 misc.c10.1 prom_printf10.2 vsprintf10.3 SprintF • • 11 irq.c11.1 exception_init11.2 set_except_vector11.3 clear_cp0_status11.4 do_reserved11.5 init_IRQ11.6 request_IRQ11.7 setup_IRQ11.8 free_IRQ11.9 mask_IRQ11.10 unmask_IRQ11.11 ExceptionToIrq_setup11.12 change_cp0_status11.13 irq_dispatch11.14 do_IRQ • • 12 monitor.c12.1 check_cpu_speed12.2 timer_interrupt12.3 timer_init12.4 monitor • • 13 eth_tftpd.c13.1 tftpd_entry • •
head.S entry point • vloží do registru sp adresu na strukturu init_task_union, resp. na její poslední volné místo • vynuluje prostor pro statické proměnné bootloaderu, následovaný za code segmentem • zavolá init_arch() • exception_matrix • přečte registr CP0_CAUSE a podle kódu výjimky zavolá příslušný handler v poli exception_handlers • inthandler.S IRQ_finder • SAVE_ALL - zjednodušeně řečeno uloží stav procesoru do nového zásobníku • CLI - zastaví další přerušení a přepne se do kernel módu • přečte registry CP0_CAUSE a CP0_STATUS, vybere pouze bity čekajících přerušení a uloží do t2 • do argumentů a0, a1 uloží obsah registrů GISR a GIMR, opět vybere do a0 bity čekajících • pokud je zde čekající přerušení (t2 != 0) tak skáče na irq_dispatch() s argumenty a0, a1 • jinak do registru UART_THR vloží znak m a tuhne pomocí cyklu • RESTORE_ALL_AND_RET - zjednodušeně řečeno načte původní stav procesoru před přerušením a končí instrukcí ret • setup.c init_arch • v registru CP0_STATUS vypne mód 64bit a ostatní koprocesory, zapne pouze CP0 • start_kernel() • setup_arch • nastaví ST0_BEV v CP0_STATUS na 0 - bootstrap mode a zapne přerušení 0, 2, 3, 4, 5 ??ST0_BEV význam? • traps.c flush_icache • za zastavených přerušení nastaví druhý bit CP0_XCONTEXT na 0 a pak na 1 ?? efekt? • flush_dcache • za zastavených přerušení nastaví první bit CP0_XCONTEXT na 0 a pak na 1 ?? efekt? • main.c start_kernel • flush_icache() a flush_dcache() • setup_arch() • exception_init() • init_IRQ() • rtl_outl - GPIO F data - 0 • check_cpu_speed() - uloží do lokální proměnné • set_bridge_clock() na zjištěnou rychlost • rtl_outl - GPIO F data - 1 • cli - vypne všechna přerušení • uart1_init() na zjištenou rychlost • flashinit() • check_eth_setting() • prom_printf() - přivítání, verze • nastaví GPIO A - 2, 3, 7, 8 na output a 1 - LEDky ??svítí červená? • check_system_image() pro tři různé offsety ve flash paměti, vybere se ten funkční • když je obraz v pořádku a user_interrupt(3sec) vrací 0, tak • přečtení celé hlavičky obrazu • flashread() - překopírování obrazu do SDRAM na určenou adresu • znovu ověří user_interrupt(0), zda uživatel nezmáčknul reset během načítání obrazu, ale tentokrát bez čekání • zastaví všechna přerušení pomocí GIMR0 • nastaví GPIO A-2 na output a 1 - červená stále svítí • prom_printf() - oznámení skoku na systém • cli - zastaví přerušení i v koprocesoru • flush_icache() a flush_dcache() • skok na počátek obrazu linuxu, bez návratu • • jinak při user_interrupt() vypíše prom_printf() escape a nastaví GPIOA-2 na output a 0 • dále pro oba případy (poškozený obraz, user_interrupt) • eth_driver_object_init() • eth_startup(0) • sti - zapnutí všech přerušení • tftpd_entry() • monitor() • • user_interrupt • nastaví GPIOA-0 na vstup • spustí druhý časovač na odpočet tří sekund • provádí smyčku dokud časovač není 0 • ověří zda jsou data na UARTu, když jo tak je přečte, pokud je tam ESC, tak vrací 0 • ověří zda na GPIOA-0 je 0, když ano, tak nastaví časovač na 1sec a po tu dobu musí být reset stisknutý, aby vrátilo 1 • • jinak vrací 0 • check_system_image • přečte hlavičku firmwaru a ověří podpis memcmp() - první 4 bajty, když nesedí tak prom_printf() error • spočítá kontrolní součet pro celou délku obrazu, když nesedí, tak prom_printf() error • pokud nedojde k chybě tak vrací počáteční adresu obrazu • uart1_init • rtl_outb - UART_LCR - 8bit words, no parity, one stop bit • rtl_outb - UART_DLM, UART_DLL - nastasvení baudrate v závislosti na rychlosti cpu • rtl_outb - UART_LCR, UART_FCR - vypnutí FIFO a reset, znovu nastavení 8bit words • prázdná smyčka, 4096 opakování • rtl_outb - UART_FCR, UART_MCR - vynulování, disable flow control • prom_printf() - oznámení načtení uart • set_bridge_clock • nastaví v registru BDGCR hodnoty dělení rychlosti jednotlivých sběrnic, v závislosti na rychlosti cpu a hodnoty 0xBD01010C ??význam? • ethInt_8186.c eth_driver_object_init • inicializuje pole ETH[0] odpovídajícími hodnotami • vynuluje ETH0_rx_buf a ETH0_tx_buf • eth_startup • eth_hw_reset(0) • eth_desc_init(0) • request_IRQ() na funkci eth_interrupt() • eth_hw_reset • memcpy() - zkopíruje si MAC adresu do lokální proměnné • prohodí pořadí bajtů v MAC adrese a vepíše ji do NIC_ID • pomocí registru NIC_CR resetuje ethernet čip a počká 0xffff cyklů • do NIC_MAR píše ffffffffffffffff • nastavuje velikost gap v NIC_TCR • v NIC_RCR zapíná příjem všech paketů • nastavení módu v NIC_MII na full 100Mbit • v NIC_RXRINGNO nastaví 64 deskriptorů • do NIC_TXFDPL vloží adresu na frontu tx, po převodu na fyzickou adresu • to samé s NIC_RXFDP, fronta rx • NIC_IMR a NIC_ISR - zapnout a vynulovat všechna přerušení • konfigurace NIO_IOCMD - nastavení rx a tx front atd. • eth_desc_init • nastaví buffer pro každý z deskriptorů rx, SetOwnByNic() nastaví hlavičku • SetOwnByNic • na základě předaných parametrů nastaví hlavičku pro rx deskriptor • eth_interrupt • pokračuje ovládáním ethernet ovladače, POKRAČOVÁNÍ! • string.c memcmp • porovná všechny bajty daných dvou polí a vrací 0 při shodě • memcpy • zkopíruje obsah jednoho pole do druhého • init.c serial_outc • počká 3210 cyklů na vyprázdnění transmitter bufferu u UART0 (rtl_inb UART_LSR) • rtl_outb - UART_THR - vepíše žádaný znak do UARTu • pokud vepsaný znak je LF, tak je vepsáno ještě CR • flash.c flashinit • vepíše na adresy 0xBExxxxxx několik hodnot ??význam? • přečte první čtyři bajty na 0xBE000000 - id výrobce a zařízení • vypíše to pomocí prom_printf() • ověří podle tabulky typů paměti zda se jedná o známý typ • když ne, tak prom_printf() chyba a ukončí funkci • • jinak jede dál, nastaví registr MCR správně podle zjištěného typu paměti • zkusí za první flash pamětí najít druhou, vepíše několik hodnot ??význam? • přečte idčka a ověří zda se shodují s první pamětí, když ano, tak se zdvojnásobí velikosti • vypíše celkovou velikost paměti - prom_printf() • inicializuje strukturu map podle tabulkových hodnot • check_eth_setting • pro RTL8186 neprovádní nic • flashread • když potřebná délka je 0 vrací hned 1 • pokud zdrojová adresa není zarovnána na 16 bitů, je potřeba první a poslední bajt přečíst zvlášť • jinak po dvou bajtech kopíruje pomocí memcpy() • misc.c prom_printf • vsprintf() - pouze předání argumentů, buffer je null • vsprintf • projde celý řetězec fmt pro každý znak, dokud není null • když přečtený znak není %, tak • když buffer není null, tak se do něj tento znak vloží • jinak se na daný znak volá putchar - serial_outc() • • jinak se pomocí zjednodušených algoritmů přečtou znaky a vyhodnotí, využívá funkci SprintF() • vrací počet vepsaných znaků • SprintF • vsprintf() - stejné argumenty • irq.c exception_init • clear_cp0_status - bit ST0_BEV • set_except_vector() - vepíše do všech vyjímkových handlerů (32) funkci do_reserved() • memcpy() - zkopíruje kód exception_matrix na adresu 0x80000080 - místo příjmu výjimky • flush_icache() • sti - zapíná přerušení • set_except_vector • vloží adresu na danou metodu na určený index pole exception_handlers - ovladače pro chytání jednotlivých výjimek • clear_cp0_status • na označené bity v masce uloží hodnotu 0 • do_reserved • prom_printf() - vypíše chybu a uvízne v nekonečném cyklu • init_IRQ • ExceptionToIrq_setup() • request_IRQ • ověří jestli číslo přerušení je menší než jejich počet - 64, jinak vrací -1 • vloží předané dev_id do předané struktury • setup_IRQ() na dané hodnoty • unmask_IRQ() na dané číslo přerušení • vrací hodnotu GIMR0 • setup_IRQ • save_and_cli • do pole irq_action nastaví na příslušný index přerušení zadanou strukturu • restore_flags • free_IRQ • mask_IRQ() • mask_IRQ • vypne bit přerušení v GIMR0 • unmask_IRQ • zapne přerušení daného čísla v GIMR0 - speciální registr pro konfiguraci přerušení • ExceptionToIrq_setup • change_cp0_status() - CP0_IM - vypíná přerušení • set_except_vector() - jako handler pro výjimky typu přerušení nastavuje IRQ_finder • change_cp0_status() - zapíná přerušení • change_cp0_status • podle masky aktualizuje hodnotu v registru CP0_STATUS • irq_dispatch • pro každé validní id přerušení 0-6 provede do_IRQ() • do_IRQ • pokud příslušné pole ve struktuře irq_action není null, tak se zavolá handler z této struktury • jinak prom_printf() s irq číslem a zatuhneme • monitor.c check_cpu_speed • request_IRQ() - žádá o timer interrupt na strukturu irq_timer, kde je handler timer_interrupt() • timer_init() • algoritmicky spočítá, kolik instrukcí je provedeno v jednom 10ms bloku • vypne přerušení timeru (registry TCCNR, TCIR) • free_IRQ() - uvolní timer interrupt • vrací rychlost procesoru v MHz • timer_interrupt • inkrementuje jiffies • timer_init • zapne nultý časovač jako timer, nastaví data na 35B60, čili 10ms a zapne přerušení (registry TCCNR, TC0DATA, TCIR) • monitor • pokračuje sledováním vstupu ze sériového portu - POKRAČOVÁNÍ! • eth_tftpd.c tftpd_entry • inicializace pole arptable_tftp, server jako 192.168.1.6, klient jako 192.168.1.116 • nastavení bootState na init • inicializace struktury nic, sdílí pole s ethernet driverem • block_expected na 0 - číslo následujícího bloku dat • one_tftp_lock na 0 • it_is_EOF na 0 - není poslední blok • address_to_store na 0x80300000 • file_length_to_server, file_length_to_client - délka přijatého souboru přes tftp - 0 • SERVER_port na 2098 •
Navigace
Nástroje