Uživatel:FroxDev/Btcode
Z 8.B8 wiki
Obsah |
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