Š
AparatÅ«rÄ bÅ«s SD karte, kas savienota, izmantojot SPI interfeisu, kÄ arÄ« UART. ProgrammatÅ«ras daÄ¼Ä BootROM tiks aizstÄts ar xip
par sdboot
un faktiski ir pievienoti Å”Ädi ielÄdes posmi (SD kartÄ).
Aparatūras pabeigŔana
TÄtad, uzdevums: jums ir jÄpÄrslÄdzas uz ālieluā kodolu un jÄpievieno UART (no Raspberry) un SD adapteris (mÄs izmantojÄm Catalex karti ar seÅ”Äm tapÄm: GND, VCC, MISO, MOSI, SCK, CS) .
PrincipÄ viss bija pavisam vienkÄrÅ”i. Bet, pirms es to sapratu, es biju nedaudz iemests no vienas puses uz otru: pÄc iepriekÅ”ÄjÄs reizes es nolÄmu, ka atkal man vienkÄrÅ”i jÄiejaucas System
kaut kas kÄ HasPeripheryUART
(un attiecÄ«gi realizÄcija), tas pats SD kartei - un viss bÅ«s gatavs. Tad es nolÄmu redzÄt, kÄ tas tika Ä«stenots "nopietnÄ" dizainÄ. TÄtad, kas tur ir nopietns? Artijs acÄ«mredzot neiederas - briesmonis paliek unleahshed.DevKitConfigs
. Un pÄkÅ”Åi izrÄdÄ«jÄs, ka visur bija daži pÄrklÄjumi, kas tika pievienoti caur parametriem ar taustiÅiem. Es domÄju, ka tas, iespÄjams, ir ļoti elastÄ«gs un konfigurÄjams, bet es gribÄtu vispirms kaut ko palaist... Vai jums nav tas pats, tikai vienkÄrÅ”Äk un kaitinoÅ”Äk? .. Toreiz es saskÄros vera.iofpga.FPGAChip
priekÅ” Microsemi FPGA un uzreiz izjaucu to citÄtiem un mÄÄ£inÄju pÄc analoÄ£ijas izveidot savu implementÄciju, par laimi ir vairÄk vai mazÄk viss āmÄtesplates izkÄrtojumsā vienÄ failÄ.
IzrÄdÄ«jÄs, ka tieÅ”Äm vajag tikai pievienot System.scala
līnijas
class System(implicit p: Parameters) extends RocketSubsystem
...
with HasPeripherySPI
with HasPeripheryUART
...
{
val tlclock = new FixedClockResource("tlclk", p(DevKitFPGAFrequencyKey))
...
}
class SystemModule[+L <: System](_outer: L)
extends RocketSubsystemModuleImp(_outer)
...
with HasPeripheryUARTModuleImp
with HasPeripheryGPIOModuleImp
...
LÄ«nija klases pamattekstÄ System
dts failam pievieno informÄciju par frekvenci, kÄdÄ Å”Ä« mÅ«su SoC daļa darbojas. Cik es saprotu, DTS/DTB ir statisks plug-and-play tehnoloÄ£ijas analogs iegultajÄm ierÄ«cÄm: dts aprakstu koks tiek apkopots binÄrÄ dtb failÄ un bootloader to pÄrsÅ«ta uz kodolu, lai tas varÄtu pareizi konfigurÄt aparatÅ«ra. Interesanti, ka bez lÄ«nijas ar tlclock
viss sintezÄjas perfekti, bet kompilÄjot BootROM (atgÄdinÄÅ”u, tagad Å”is jau bÅ«s sdboot
) nedarbosies - kompilÄcijas procesa laikÄ tas parsÄ dts failu un izveido galveni ar makro TL_CLK
, pateicoties kuriem viÅÅ” varÄs pareizi konfigurÄt frekvenÄu dalÄ«tÄjus ÄrÄjÄm saskarnÄm.
Jums bÅ«s arÄ« nedaudz jÄlabo "vadu instalÄcija":
Platform.scala:
class PlatformIO(implicit val p: Parameters) extends Bundle {
...
// UART
io.uart_tx := sys.uart(0).txd
sys.uart(0).rxd := RegNext(RegNext(io.uart_rx))
// SD card
io.sd_cs := sys.spi(0).cs(0)
io.sd_sck := sys.spi(0).sck
io.sd_mosi := sys.spi(0).dq(0).o
sys.spi(0).dq(0).i := false.B
sys.spi(0).dq(1).i := RegNext(RegNext(io.sd_miso))
sys.spi(0).dq(2).i := false.B
sys.spi(0).dq(3).i := false.B
}
GodÄ«gi sakot, reÄ£istru Ä·Ädes tika pievienotas vienkÄrÅ”i pÄc analoÄ£ijas ar dažÄm citÄm vietÄm sÄkotnÄjÄ kodÄ. VisticamÄk, viÅiem vajadzÄtu aizsargÄties pret dq
? Es vÄl neesmu atradis atbildi, bet Ŕķiet, ka pÄrÄjais kods ir balstÄ«ts tikai uz Å”Ädu savienojumu.
Fiziski es vienkÄrÅ”i pieŔķīru konstrukcijas tapas brÄ«vajiem kontaktiem uz bloka un pÄrvietoju sprieguma izvÄles džemperi uz 3.3 V.
SD adapteris
Skats no augŔas:
Skats no apakŔas:
Programmatūras atkļūdoŔana: rīki
Vispirms parunÄsim par pieejamajiem atkļūdoÅ”anas rÄ«kiem un to ierobežojumiem.
Minicom
PirmkÄrt, mums bÅ«s kaut kÄ jÄizlasa bootloader un kodola izvade. Lai to izdarÄ«tu operÄtÄjsistÄmÄ Linux (Å”ajÄ gadÄ«jumÄ ar RaspberryPi), mums ir nepiecieÅ”ama programma Minicom. VispÄrÄ«gi runÄjot, derÄs jebkura programma, kas darbojas ar seriÄlo portu.
LÅ«dzu, Åemiet vÄrÄ, ka startÄÅ”anas laikÄ porta ierÄ«ces nosaukums ir jÄnorÄda kÄ -D /dev/ttyS0
- pÄc opcijas -D
. Nu, galvenÄ informÄcija: lai izietu, izmantojiet Ctrl-A, X
. Man tieÅ”Äm bija gadÄ«jums, kad Ŕī kombinÄcija nedarbojÄs - tad jÅ«s varat vienkÄrÅ”i teikt no blakus esoÅ”Äs SSH sesijas killall -KILL minicom
.
Ir vÄl viena funkcija. KonkrÄti, RaspberryPi ir divi UART, un abus portus jau var kaut kam pielÄgot: viens Bluetooth, otrs pÄc noklusÄjuma izvada kodola konsoli. Par laimi, Å”o uzvedÄ«bu var ignorÄt
AtmiÅas pÄrrakstÄ«Å”ana
Atkļūdojot, lai pÄrbaudÄ«tu hipotÄzi, man dažreiz tas bija jÄdara ielÄdÄjiet sÄknÄÅ”anas programmu (atvainojiet) RAM tieÅ”i no resursdatora. VarbÅ«t to var izdarÄ«t tieÅ”i no GDB, bet beigÄs gÄju pa vienkÄrÅ”u ceļu: nokopÄju vajadzÄ«go failu uz Raspberry, pÄrsÅ«tÄ«ju arÄ« portu 4444 caur SSH (telnet no OpenOCD) un izmantoju komandu load_image
. Kad to dari, Ŕķiet, ka viss ir sasalis, bet patiesÄ«bÄ "tas neguļ, tas tikai lÄni mirgo": Tas lejupielÄdÄ failu, tas tikai dara to ar Ätrumu pÄris kilobaiti sekundÄ.
PÄrtraukuma punktu uzstÄdÄ«Å”anas iezÄ«mes
Daudziem cilvÄkiem, iespÄjams, par to nav jÄdomÄ, atkļūdojot parastÄs programmas, taÄu pÄrtraukuma punkti ne vienmÄr ir iestatÄ«ti aparatÅ«rÄ. Dažreiz pÄrtraukuma punkta iestatÄ«Å”ana ietver Ä«paÅ”u instrukciju Ä«slaicÄ«gu pierakstÄ«Å”anu pareizajÄ vietÄ tieÅ”i maŔīnas kodÄ. PiemÄram, Å”Ädi darbojÄs mana standarta komanda b
GDB. TÄlÄk ir norÄdÄ«ts tÄlÄk.
- BootROM iekÅ”Ä nevar likt punktu, jo ROM
- Varat iestatÄ«t pÄrtraukuma punktu kodam, kas tiek ielÄdÄts RAM no SD kartes, taÄu jums jÄgaida, lÄ«dz tas tiek ielÄdÄts. PretÄjÄ gadÄ«jumÄ mÄs nepÄrrakstÄ«sim koda daļu, bet ielÄdÄtÄjs pÄrrakstÄ«s mÅ«su pÄrtraukuma punktu
Esmu pÄrliecinÄts, ka varat tieÅ”i lÅ«gt izmantot aparatÅ«ras pÄrtraukumpunktus, taÄu to skaits tik un tÄ ir ierobežots.
Ätra BootROM nomaiÅa
SÄkotnÄjÄ atkļūdoÅ”anas stadijÄ bieži vien ir vÄlme salabot BootROM un mÄÄ£inÄt vÄlreiz. Bet pastÄv problÄma: BootROM ir daļa no FPGA ielÄdÄtÄ dizaina, un tÄ sintÄze ir dažu minÅ«Å”u jautÄjums (un tas notiek pÄc gandrÄ«z tÅ«lÄ«tÄjas paÅ”a BootROM attÄla kompilÄcijas no C un Assembler...). Par laimi, patiesÄ«bÄ viss daudz ÄtrÄk: darbÄ«bu secÄ«ba ir Å”Äda:
- atjaunot bootrom.mif (es pÄrgÄju uz MIF, nevis HEX, jo man vienmÄr bija dažas problÄmas ar HEX, un MIF ir Alter vietÄjais formÄts)
- in Quartus teikt
Processing -> Update Memory Initialization File
- uz vienuma Assembler (uzdevumu kreisajÄ kolonnÄ) komandu SÄkt no jauna
Viss par visu ā pÄris desmiti sekunžu.
SD kartes sagatavoŔana
Viss Å”eit ir salÄ«dzinoÅ”i vienkÄrÅ”s, taÄu jums ir jÄbÅ«t pacietÄ«gam un jÄbÅ«t apmÄram 14 Gb diska vietas:
git clone https://github.com/sifive/freedom-u-sdk
git submodule update --recursive --init
make
PÄc tam jums jÄievieto tÄ«ra vai drÄ«zÄk tÄda, kurÄ nav nekÄ nepiecieÅ”amÄ, SD karte un jÄizpilda
sudo make DISK=/dev/sdX format-boot-loader
ā¦ Kur sdX
ā kartei pieŔķirtÄ ierÄ«ce. UZMANÄŖBU: dati kartÄ tiks dzÄsti, pÄrrakstÄ«ti un vispÄr! Diez vai ir vÄrts veikt visu montÄžu no apakÅ”as sudo
jo tad visi celtnes artefakti piederÄs root
, un montÄža bÅ«s jÄveic no apakÅ”as sudo
pastÄvÄ«gi.
RezultÄts ir karte, kas atzÄ«mÄta GPT ar Äetriem nodalÄ«jumiem, no kuriem vienÄ ir FAT ar uEnv.txt
un bootable attÄlu FIT formÄtÄ (tajÄ ir vairÄki apakÅ”attÄli, katrs ar savu lejupielÄdes adresi), otrs nodalÄ«jums ir tukÅ”s, tas ir paredzÄts formatÄt Ext4 for Linux. VÄl divas sadaļas - noslÄpumains: U-Boot dzÄ«vo vienÄ (tÄ nobÄ«de, cik saprotu, ir iekodÄta BootROM), otrÄ, Ŕķiet, tÄ vides mainÄ«gie dzÄ«vo, bet es tos vÄl neizmantoju.
Pirmais līmenis, BootROM
Tautas gudrÄ«ba vÄsta: "Ja programmÄÅ”anÄ ir dejoÅ”ana ar tamburÄ«nu, tad elektronikÄ ir arÄ« dejoÅ”ana ar ugunsdzÄÅ”amo aparÄtu." Runa nav pat par to, ka reiz es gandrÄ«z sadedzinÄju dÄli, nolemjot, ka "Nu, GND ir tikpat zems lÄ«menis." (acÄ«mredzot, rezistors galu galÄ nesÄpÄs...) Tas vairÄk ir par to, ka, ja rokas no turienes neaug, tad elektronika nebeidz sagÄdÄt pÄrsteigumus: pielodÄjot savienotÄju uz plates, joprojÄm nevarÄju pareizi pielodÄt kontaktus - video redzams, kÄ lodÄjums tieÅ”i izplatÄs. pa visu savienojumu, vienkÄrÅ”i uzklÄjiet lodÄmuru, Man viÅÅ” nejauÅ”i "iesita". Nu, varbÅ«t lodÄmurs nebija piemÄrots lodÄmura temperatÅ«rai, varbÅ«t vÄl kaut kas... VispÄr, kad ieraudzÄ«ju, ka man jau ir ducis kontaktu, padevos un sÄku atkļūdot. Un tad tas sÄkÄs noslÄpumaini: Es pievienoju RX/TX no UART, ielÄdÄju programmaparatÅ«ru - tÄ saka
INIT
CMD0
ERROR
Nu viss ir loÄ£iski - es nepievienoju SD kartes moduli. Izlabojam situÄciju, ielÄdÄjam programmaparatÅ«ru... Un klusums... KÄpÄc es nepÄrdomÄju, bet tikko atvÄrÄs mazÄ kastÄ«te: viena no moduļa tapÄm bija jÄpievieno VCC. ManÄ gadÄ«jumÄ modulis atbalstÄ«ja 5V strÄvas padevei, tÄpÄc, divreiz nedomÄjot, es pievienoju vadu, kas nÄk no moduļa, pretÄjÄ dÄļa pusÄ. RezultÄtÄ greizi pielodÄtais savienotÄjs kļuva Ŕķībs, un UART kontakts vienkÄrÅ”i tika zaudÄts. facepalm.jpg KopumÄ "slikta galva nedod atpÅ«tu kÄjÄm", un lÄ«kas rokas nedod atpÅ«tu galvai ...
RezultÄtÄ es redzÄju ilgi gaidÄ«to
INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING /
TurklÄt tas kustas un iekrauÅ”anas indikators griežas. Uzreiz atceros skolas laikus un nesteidzÄ«go MinuetOS ielÄdi no disketes. Ja vien piedziÅa nesasmalcina.
ProblÄma ir tÄda, ka pÄc BOOT ziÅojuma nekas nenotiek. Tas nozÄ«mÄ, ka ir pienÄcis laiks izveidot savienojumu, izmantojot OpenOCD ar Raspberry, ar resursdatora GDB, un redzÄt, kas tas ir.
PirmkÄrt, savienoÅ”ana, izmantojot GDB, to uzreiz parÄdÄ«ja $pc
(programmu skaitÄ«tÄjs, paÅ”reizÄjÄs instrukcijas adrese) lido uz 0x0
- tas, iespÄjams, notiek pÄc vairÄkÄm kļūdÄm. TÄpÄc uzreiz pÄc ziÅojuma izsniegÅ”anas BOOT
Pievienosim bezgalÄ«gu cilpu. Tas viÅu uz kÄdu laiku aizkavÄs...
diff --git a/bootrom/sdboot/sd.c b/bootrom/sdboot/sd.c
index c6b5ede..bca1b7f 100644
--- a/bootrom/sdboot/sd.c
+++ b/bootrom/sdboot/sd.c
@@ -224,6 +224,8 @@ int main(void)
kputs("BOOT");
+ while(*(volatile char *)0x10000){}
+
__asm__ __volatile__ ("fence.i" : : : "memory");
return 0;
}
Å Äds viltÄ«gs kods tiek izmantots āuzticamÄ«bas labadā: kaut kur dzirdÄju, ka bezgalÄ«ga cilpa ir nenoteikta uzvedÄ«ba, taÄu kompilators diez vai uzminÄs (atgÄdinu, ka saskaÅÄ ar 0x10000
atrodas BootROM).
Å Ä·iet, ko gan citu gaidÄ«t - skarbi iegulti, kÄdi tur pirmkodi? Bet iekÅ”Ä
(gdb) file builds/zeowaa-e115/sdboot.elf
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from builds/zeowaa-e115/sdboot.elf...done.
Jums vienkÄrÅ”i jÄlejupielÄdÄ nevis MIF fails vai tvertne, bet gan sÄkotnÄjÄ versija ELF formÄtÄ.
Tagad, ar n-to mÄÄ£inÄjumu, jÅ«s varat uzminÄt adresi, kurÄ izpilde turpinÄsies (tas ir vÄl viens iemesls, kÄpÄc kompilatoram nevajadzÄtu uzminÄt, ka cilpa ir bezgalÄ«ga). Komanda
set variable $pc=0xADDR
ļauj lidojuma laikÄ mainÄ«t reÄ£istra vÄrtÄ«bu (Å”ajÄ gadÄ«jumÄ paÅ”reizÄjÄs instrukcijas adresi). Ar tÄs palÄ«dzÄ«bu jÅ«s varat mainÄ«t atmiÅÄ ierakstÄ«tÄs vÄrtÄ«bas (un atmiÅas kartÄtos reÄ£istrus).
Galu galÄ es nonÄcu pie secinÄjuma (neesmu pÄrliecinÄts, kurÅ” ir pareizs), ka mums ir "nepareizas sistÄmas SD kartes attÄls", un mums ir jÄiet nevis uz paÅ”u lejupielÄdÄto datu sÄkumu, bet gan uz 0x89800
baiti tÄlÄk:
diff --git a/bootrom/sdboot/head.S b/bootrom/sdboot/head.S
index 14fa740..2a6c944 100644
--- a/bootrom/sdboot/head.S
+++ b/bootrom/sdboot/head.S
@@ -13,7 +13,7 @@ _prog_start:
smp_resume(s1, s2)
csrr a0, mhartid
la a1, dtb
- li s1, PAYLOAD_DEST
+ li s1, (PAYLOAD_DEST + 0x89800)
jr s1
.section .rodata
IespÄjams, to ietekmÄja arÄ« tas, ka, tÄ kÄ pa rokai nebija liekas 4Gb kartes, paÅÄmu 2Gb un pÄc nejauŔības principa nomainÄ«ju to Makefile. DEMO_END=11718750
par DEMO_END=3078900
(nemeklÄjiet jÄgu konkrÄtÄ nozÄ«mÄ - tÄdas nav, vienkÄrÅ”i tagad attÄls ir ievietots kartÄ).
Otrais līmenis, U-Boot
Tagad vÄl ākrÄ«tamā, bet jau esam Ä«stajÄ vietÄ 0x0000000080089a84
. Te gan jÄatzÄ«st: patiesÄ«bÄ prezentÄcija neiet āar visÄm pieturÄmā, bet gan ir daļÄji uzrakstÄ«ta āpÄcā, tÄpÄc Å”eit jau paspÄju ievietot pareizo dtb failu no mÅ«su SoC, izlabot to iestatÄ«jumos HiFive_U-Boot
mainīgs CONFIG_SYS_TEXT_BASE=0x80089800
(nevis 0x08000000
), lai lejupielÄdes adrese atbilstu faktiskajai adresei. Tagad mÄs ielÄdÄjam nÄkamÄ lÄ«meÅa karti, citu attÄlu:
(gdb) file ../freedom-u-sdk/work/HiFive_U-Boot/u-boot
(gdb) tui en
Un mÄs redzam:
ā304 /* ā
ā305 * trap entry ā
ā306 */ ā
ā307 trap_entry: ā
ā308 addi sp, sp, -32*REGBYTES ā
>ā309 SREG x1, 1*REGBYTES(sp) ā
ā310 SREG x2, 2*REGBYTES(sp) ā
ā311 SREG x3, 3*REGBYTES(sp) ā
TurklÄt mÄs pÄrejam starp 308. un 309. rindiÅÄm. Un tas nav pÄrsteidzoÅ”i, Åemot vÄrÄ to $sp
slÄpjas jÄga 0xfffffffe31cdc0a0
. DiemžÄl tas arÄ« pastÄvÄ«gi āaizbÄgā 307. rindas dÄļ. TÄpÄc mÄÄ£inÄsim iestatÄ«t pÄrtraukuma punktu plkst. trap_entry
, un pÄc tam atgriezieties pie 0x80089800
(U-Boot ieejas punkts), un cerÄsim, ka pirms pÄrlÄkÅ”anas nav nepiecieÅ”ams pareizi iestatÄ«t reÄ£istrus... IzskatÄs, ka tas darbojas:
(gdb) b trap_entry
Breakpoint 1 at 0x80089a80: file /hdd/trosinenko/fpga/freedom-u-sdk/HiFive_U-Boot/arch/riscv/cpu/HiFive/start.S, line 308.
(gdb) set variable $pc=0x80089800
(gdb) c
Continuing.
Breakpoint 1, trap_entry () at /hdd/trosinenko/fpga/freedom-u-sdk/HiFive_U-Boot/arch/riscv/cpu/HiFive/start.S:308
(gdb) p/x $sp
$4 = 0x81cf950
Steka rÄdÄ«tÄjs ir tik, atklÄti sakot: tas norÄda, apejot RAM vispÄr (ja vien mums, protams, vÄl nav adreÅ”u tulkoÅ”anas, bet cerÄsim uz vienkÄrÅ”u iespÄju).
MÄÄ£inÄsim aizstÄt rÄdÄ«tÄju ar 0x881cf950
. RezultÄtÄ mÄs nonÄkam pie secinÄjuma, ka handle_trap
zvanÄ«ja un zvanÄ«ja, un tajÄ paÅ”Ä laikÄ mÄs ieejam _exit_trap
ar argumentu epc=2148315240
(decimÄldaļÄs):
(gdb) x/10i 2148315240
0x800cb068 <strnlen+12>: lbu a4,0(a5)
0x800cb06c <strnlen+16>: bnez a4,0x800cb078 <strnlen+28>
0x800cb070 <strnlen+20>: sub a0,a5,a0
0x800cb074 <strnlen+24>: ret
0x800cb078 <strnlen+28>: addi a5,a5,1
0x800cb07c <strnlen+32>: j 0x800cb064 <strnlen+8>
0x800cb080 <strdup>: addi sp,sp,-32
0x800cb084 <strdup+4>: sd s0,16(sp)
0x800cb088 <strdup+8>: sd ra,24(sp)
0x800cb08c <strdup+12>: li s0,0
IestatÄ«t pÄrtraukuma punktu uz strnlen
, mÄs turpinÄm un redzam:
(gdb) bt
#0 strnlen (s=s@entry=0x10060000 "", count=18446744073709551615) at lib/string.c:283
#1 0x00000000800cc14c in string (buf=buf@entry=0x881cbd4c "", end=end@entry=0x881cc15c "", s=0x10060000 "", field_width=<optimized out>, precision=<optimized out>, flags=<optimized out>) at lib/vsprintf.c:265
#2 0x00000000800cc63c in vsnprintf_internal (buf=buf@entry=0x881cbd38 "exception code: 5 , ", size=size@entry=1060, fmt=0x800d446e "s , epc %08x , ra %08lxn", fmt@entry=0x800d4458 "exception code: %d , %s , epc %08x , ra %08lxn", args=0x881cc1a0,
args@entry=0x881cc188) at lib/vsprintf.c:619
#3 0x00000000800cca54 in vsnprintf (buf=buf@entry=0x881cbd38 "exception code: 5 , ", size=size@entry=1060, fmt=fmt@entry=0x800d4458 "exception code: %d , %s , epc %08x , ra %08lxn", args=args@entry=0x881cc188) at lib/vsprintf.c:710
#4 0x00000000800cca68 in vscnprintf (buf=buf@entry=0x881cbd38 "exception code: 5 , ", size=size@entry=1060, fmt=fmt@entry=0x800d4458 "exception code: %d , %s , epc %08x , ra %08lxn", args=args@entry=0x881cc188) at lib/vsprintf.c:717
#5 0x00000000800ccb50 in printf (fmt=fmt@entry=0x800d4458 "exception code: %d , %s , epc %08x , ra %08lxn") at lib/vsprintf.c:792
#6 0x000000008008a9f0 in _exit_trap (regs=<optimized out>, epc=2148315240, code=<optimized out>) at arch/riscv/lib/interrupts.c:92
#7 handle_trap (mcause=<optimized out>, epc=<optimized out>, regs=<optimized out>) at arch/riscv/lib/interrupts.c:55
#8 0x0000000080089b10 in trap_entry () at /hdd/trosinenko/fpga/freedom-u-sdk/HiFive_U-Boot/arch/riscv/cpu/HiFive/start.S:343
Backtrace stopped: frame did not save the PC
Å Ä·iet, _exit_trap
vÄlas sniegt atkļūdoÅ”anas informÄciju par notikuÅ”o izÅÄmumu, bet viÅÅ” nevar. TÄtad, kaut kÄ mÅ«su avoti atkal netiek parÄdÄ«ti. set directories ../freedom-u-sdk/HiFive_U-Boot/
PAR! Tagad parÄdÄ«ts!
PalaidÄ«sim to vÄlreiz un no steka izsekojam sÄkotnÄjÄs problÄmas cÄloni, kas izraisÄ«ja pirmo kļūdu (mcause == 5
). Ja pareizi sapratu rakstīto Load access fault
. Šķiet, ka iemesls ir Ŕeit
arch/riscv/cpu/HiFive/start.S:
call_board_init_f:
li t0, -16
li t1, CONFIG_SYS_INIT_SP_ADDR
and sp, t1, t0 /* force 16 byte alignment */
#ifdef CONFIG_DEBUG_UART
jal debug_uart_init
#endif
call_board_init_f_0:
mv a0, sp
jal board_init_f_alloc_reserve
mv sp, a0
jal board_init_f_init_reserve
mv a0, zero /* a0 <-- boot_flags = 0 */
la t5, board_init_f
jr t5 /* jump to board_init_f() */
$sp
ir tÄda pati nepareiza nozÄ«me, un iekÅ”Ä board_init_f_init_reserve
rodas kļūda. Å Ä·iet, ka tas ir vaininieks: mainÄ«gais ar nepÄrprotamu nosaukumu CONFIG_SYS_INIT_SP_ADDR
. Tas ir definÄts failÄ HiFive_U-Boot/include/configs/HiFive-U540.h
. KÄdÄ brÄ«dÄ« pat iedomÄjos, varbÅ«t, nu, vajadzÄtu pielikt klÄt procesoram boot loader - varbÅ«t bÅ«tu vieglÄk procesoru nedaudz salabot? Bet tad es redzÄju, ka tas vairÄk atgÄdina artefakts no lÄ«dz galam nepabeigtam#if 0
-specifiskus iestatÄ«jumus citai atmiÅas konfigurÄcijai, un varat mÄÄ£inÄt to izdarÄ«t:
diff --git a/include/configs/HiFive-U540.h b/include/configs/HiFive-U540.h
index ca89383..245542c 100644
--- a/include/configs/HiFive-U540.h
+++ b/include/configs/HiFive-U540.h
@@ -65,12 +65,9 @@
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_0
#endif
#if 1
-/*#define CONFIG_NR_DRAM_BANKS 1*/
+#define CONFIG_NR_DRAM_BANKS 1
#define PHYS_SDRAM_0 0x80000000 /* SDRAM Bank #1 */
-#define PHYS_SDRAM_1
- (PHYS_SDRAM_0 + PHYS_SDRAM_0_SIZE) /* SDRAM Bank #2 */
-#define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GB */
-#define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB */
+#define PHYS_SDRAM_0_SIZE 0x40000000 /* 1 GB */
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_0
#endif
/*
@@ -81,7 +78,7 @@
#define CONSOLE_ARG "console=ttyS0,115200 "
/* Init Stack Pointer */
-#define CONFIG_SYS_INIT_SP_ADDR (0x08000000 + 0x001D0000 -
+#define CONFIG_SYS_INIT_SP_ADDR (0x80000000 + 0x001D0000 -
GENERATED_GBL_DATA_SIZE)
#define CONFIG_SYS_LOAD_ADDR 0xa0000000 /* partway up SDRAM */
KÄdÄ brÄ«dÄ« kruÄ·u skaits
Nu, apmÄram, Å”eit ir maza tabula
trosinenko@trosinenko-pc:/hdd/trosinenko/fpga/freedom-u-sdk/HiFive_U-Boot$ git show --name-status
commit 39cd67d59c16ac87b46b51ac1fb58f16f1eb1048 (HEAD -> zeowaa-1gb)
Author: Anatoly Trosinenko <[email protected]>
Date: Tue Jul 2 17:13:16 2019 +0300
Initial support for Zeowaa A-E115FB board
M arch/riscv/Kconfig
A arch/riscv/cpu/zeowaa-1gb/Makefile
A arch/riscv/cpu/zeowaa-1gb/cpu.c
A arch/riscv/cpu/zeowaa-1gb/start.S
A arch/riscv/cpu/zeowaa-1gb/timer.c
A arch/riscv/cpu/zeowaa-1gb/u-boot.lds
M arch/riscv/dts/Makefile
A arch/riscv/dts/zeowaa-1gb.dts
A board/Zeowaa/zeowaa-1gb/Kconfig
A board/Zeowaa/zeowaa-1gb/MAINTAINERS
A board/Zeowaa/zeowaa-1gb/Makefile
A board/Zeowaa/zeowaa-1gb/Zeowaa-A-E115FB.c
A configs/zeowaa-1gb_defconfig
A include/configs/zeowaa-1gb.h
SÄ«kÄku informÄciju var atrast
KÄ izrÄdÄ«jÄs, Å”ajÄ SiFive platÄ dažu ierÄ«Äu reÄ£istriem ir dažÄdas adreses. IzrÄdÄ«jÄs arÄ«, ka U-Boot ir konfigurÄts, izmantojot Kconfig mehÄnismu, kas jau pazÄ«stams no Linux kodola - piemÄram, jÅ«s varat komandÄt make menuconfig
, un jÅ«su priekÅ”Ä parÄdÄ«sies Ärts teksta interfeiss, kurÄ bÅ«s redzami parametru apraksti ?
utt. VispÄr sakopot treÅ”Ä aprakstu no divu dÄļu aprakstiem, izmetot no turienes visÄdas pretenciozas PLL pÄrkonfigurÄcijas (acÄ«mredzot, tas kaut kÄ ir saistÄ«ts ar vadÄ«bu no saimniekdatora caur PCIe, bet tas nav droÅ”i) , es saÅÄmu kÄdu programmaparatÅ«ru, kas piemÄrotos laikapstÄkļos uz Marsa man caur UART sniedza ziÅojumu par to, no kura commit hash tas tika kompilÄts, un par to, cik daudz man ir DRAM (bet es pats ierakstÄ«ju Å”o informÄciju galvenÄ).
VienÄ«gi žÄl, ka pÄc tam plate parasti pÄrstÄja reaÄ£Ät caur procesoru JTAG, un ielÄde no SD kartes manÄ konfigurÄcijÄ diemžÄl nav Ätra. No otras puses, dažreiz BootROM deva ziÅojumu, ka ERROR
, neizdevÄs palaist, un uzreiz parÄdÄ«jÄs U-Boot. Toreiz man atklÄjÄs: acÄ«mredzot pÄc bitu plÅ«smas pÄrstartÄÅ”anas FPGA atmiÅa netiek izdzÄsta, tai nav laika āattrenÄtā utt. ÄŖsÄk sakot, jÅ«s varat vienkÄrÅ”i, kad parÄdÄs ziÅojums LOADING /
izveidojiet savienojumu ar atkļūdotÄju un komandu set variable $pc=0x80089800
, tÄdÄjÄdi apejot Å”o ilgo ielÄdi (protams, pieÅemot, ka pagÄjuÅ”ajÄ reizÄ tas salÅ«za pietiekami agri, ka tam nebija laika ielÄdÄt neko virs sÄkotnÄjÄ koda).
Starp citu, vai tas vispÄr ir normÄli, ka procesors pilnÄ«bÄ sasalst un JTAG atkļūdotÄjs nevar pieslÄgties tam ar ziÅojumiem?
Error: unable to halt hart 0
Error: dmcontrol=0x80000001
Error: dmstatus =0x00030c82
TÄtad, pagaidiet! Å o jau esmu redzÄjis! Kaut kas lÄ«dzÄ«gs notiek, kad TileLink ir strupceļÄ, un es kaut kÄ neuzticos atmiÅas kontroliera autoram - pats to rakstÄ«ju... PÄkÅ”Åi pÄc pirmÄs veiksmÄ«gÄs procesora pÄrbÅ«ves pÄc kontrollera rediÄ£ÄÅ”anas es redzÄju:
INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING
BOOT
U-Boot 2018.09-g39cd67d-dirty (Jul 03 2019 - 13:50:33 +0300)
DRAM: 1 GiB
MMC:
BEFORE LOAD ENVBEFORE FDTCONTROLADDRBEFORE LOADADDRIn: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 3
Uz Ŕo dīvaino līniju iepriekŔ In: serial
nepievÄrsiet uzmanÄ«bu - es mÄÄ£inÄju saprast uz piekÄrtÄ procesora, vai tas pareizi darbojas ar vidi. Ko jÅ«s domÄjat: "Tas ir karÄjies Å”Ädi desmit minÅ«tes"? Vismaz izdevÄs pÄrvietot un doties uz sÄknÄÅ”anas izvÄlni! Neliela atkÄpe: lai gan U-Boot tiek ielÄdÄts pirmajos 2^24 baitos no SD kartes, startÄjot, tas kopÄ sevi uz tÄlÄku adresi, kas ierakstÄ«ta konfigurÄcijas galvenÄ, vai vienkÄrÅ”i uz augstÄkajÄm RAM adresÄm. , un veic ELF pÄrvietoÅ”anu -rakstzÄ«mes, un nodod tur kontroli. TÄtad: izskatÄs, ka izgÄjÄm Å”o lÄ«meni un saÅÄmÄm bonusu, ka procesors pÄc tam nav cieÅ”i nokarÄjies.
TÄtad, kÄpÄc taimeris nedarbojas? IzskatÄs, ka pulkstenis nez kÄpÄc nestrÄdÄ...
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000
Ko darÄ«t, ja pagriežat bultiÅas manuÄli?
(gdb) set variable *0x0200bff8=310000000
(gdb) c
PÄc tam:
Hit any key to stop autoboot: 0
MMC_SPI: 0 at 0:1 hz 20000000 mode 0
SecinÄjums: pulkstenis netikŔķ. IespÄjams, tÄpÄc tastatÅ«ras ievade nedarbojas:
HiFive_U-Boot/cmd/bootmenu.c:
static void bootmenu_loop(struct bootmenu_data *menu,
enum bootmenu_key *key, int *esc)
{
int c;
while (!tstc()) {
WATCHDOG_RESET();
mdelay(10);
}
c = getc();
switch (*esc) {
case 0:
/* First char of ANSI escape sequence 'e' */
if (c == 'e') {
*esc = 1;
*key = KEY_NONE;
}
break;
case 1:
/* Second char of ANSI '[' */
if (c == '[') {
...
ProblÄma izrÄdÄ«jÄs tÄ, ka es biju nedaudz pÄrÄk gudrs: procesora konfigurÄcijai pievienoju atslÄgu:
case DTSTimebase => BigInt(0)
... pamatojoties uz to, ka komentÄrÄ bija teikts "ja nezinÄt, atstÄjiet 0." Un galu galÄ WithNBigCores
Es tikko iestatÄ«ju to uz 1MHz (kÄ, starp citu, tas bija norÄdÄ«ts U-Boot konfigurÄcijÄ). Bet sasodÄ«ts, es esmu veikls un rÅ«pÄ«gs: es nezinu, Å”eit tas ir 25 MHz! Galu galÄ nekas nedarbojas. Es noÅÄmu savus "uzlabojumus" un...
Hit any key to stop autoboot: 0
MMC_SPI: 0 at 0:1 hz 20000000 mode 0
## Unknown partition table type 0
libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND
** No partition table - mmc 0 **
## Info: input data size = 34 = 0x22
Running uEnv.txt boot2...
## Error: "boot2" not defined
HiFive-Unleashed #
JÅ«s pat varat ievadÄ«t komandas! PiemÄram, pÄc nelielas pabakstÄ«Å”anÄs, jÅ«s beidzot varat uzminÄt, lai ieietu mmc_spi 1 10000000 0; mmc part
, samazinot SPI frekvenci no 20MHz lÄ«dz 10MHz. KÄpÄc? Nu konfigurÄcijÄ bija ierakstÄ«ta maksimÄlÄ frekvence 20MHz, un tur joprojÄm ir rakstÄ«ts. Bet, cik es saprotu, saskarnes, vismaz Å”eit, darbojas Å”Ädi: kods sadala aparatÅ«ras vienÄ«bas frekvenci (manÄjais visur ir 25 MHz) ar mÄrÄ·i un iegÅ«st iegÅ«to vÄrtÄ«bu kÄ dalÄ«tÄju attiecÄ«gajÄ vadÄ«klÄ. reÄ£istrÄties. ProblÄma ir tÄda, ka ja priekÅ” 115200Hz UART ir aptuveni tas, kas vajadzÄ«gs, tad, izdalot 25000000 ar 20000000, sanÄk 1, t.i. tas darbosies ar 25MHz. VarbÅ«t tas ir normÄli, bet, ja tiek noteikti ierobežojumi, tas nozÄ«mÄ, ka kÄdam tas ir vajadzÄ«gs (bet tas nav droÅ”i)... KopumÄ ir vieglÄk to nolikt un virzÄ«ties tÄlÄk - tÄlu un, diemžÄl, uz ilgu laiku. 25MHz nav Core i9.
Konsoles izvade
HiFive-Unleashed # env edit mmcsetup
edit: mmc_spi 1 10000000 0; mmc part
HiFive-Unleashed # boot
MMC_SPI: 1 at 0:1 hz 10000000 mode 0
Partition Map for MMC device 0 -- Partition Type: EFI
Part Start LBA End LBA Name
Attributes
Type GUID
Partition GUID
1 0x00000800 0x0000ffde "Vfat Boot"
attrs: 0x0000000000000000
type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
type: data
guid: 76bd71fd-1694-4ff3-8197-bfa81699c2fb
2 0x00040800 0x002efaf4 "root"
attrs: 0x0000000000000000
type: 0fc63daf-8483-4772-8e79-3d69d8477de4
type: linux
guid: 9f3adcc5-440c-4772-b7b7-283124f38bf3
3 0x0000044c 0x000007e4 "uboot"
attrs: 0x0000000000000000
type: 5b193300-fc78-40cd-8002-e86c45580b47
guid: bb349257-0694-4e0f-9932-c801b4d76fa3
4 0x00000400 0x0000044b "uboot-env"
attrs: 0x0000000000000000
type: a09354ac-cd63-11e8-9aff-70b3d592f0fa
guid: 4db442d0-2109-435f-b858-be69629e7dbf
libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND
2376 bytes read in 0 ms
Running uEnv.txt boot2...
15332118 bytes read in 0 ms
## Loading kernel from FIT Image at 90000000 ...
Using 'config-1' configuration
Trying 'bbl' kernel subimage
Description: BBL/SBI/riscv-pk
Type: Kernel Image
Compression: uncompressed
Data Start: 0x900000d4
Data Size: 74266 Bytes = 72.5 KiB
Architecture: RISC-V
OS: Linux
Load Address: 0x80000000
Entry Point: 0x80000000
Hash algo: sha256
Hash value: 28972571467c4ad0cf08a81d9cf92b9dffc5a7cb2e0cd12fdbb3216cf1f19cbd
Verifying Hash Integrity ... sha256+ OK
## Loading fdt from FIT Image at 90000000 ...
Using 'config-1' configuration
Trying 'fdt' fdt subimage
Description: unavailable
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x90e9d31c
Data Size: 6911 Bytes = 6.7 KiB
Architecture: RISC-V
Load Address: 0x81f00000
Hash algo: sha256
Hash value: 10b0244a5a9205357772ea1c4e135a4f882409262176d8c7191238cff65bb3a8
Verifying Hash Integrity ... sha256+ OK
Loading fdt from 0x90e9d31c to 0x81f00000
Booting using the fdt blob at 0x81f00000
## Loading loadables from FIT Image at 90000000 ...
Trying 'kernel' loadables subimage
Description: Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x900123e8
Data Size: 10781356 Bytes = 10.3 MiB
Architecture: RISC-V
OS: Linux
Load Address: 0x80200000
Entry Point: unavailable
Hash algo: sha256
Hash value: 72a9847164f4efb2ac9bae736f86efe7e3772ab1f01ae275e427e2a5389c84f0
Verifying Hash Integrity ... sha256+ OK
Loading loadables from 0x900123e8 to 0x80200000
## Loading loadables from FIT Image at 90000000 ...
Trying 'ramdisk' loadables subimage
Description: buildroot initramfs
Type: RAMDisk Image
Compression: gzip compressed
Data Start: 0x90a5a780
Data Size: 4467411 Bytes = 4.3 MiB
Architecture: RISC-V
OS: Linux
Load Address: 0x82000000
Entry Point: unavailable
Hash algo: sha256
Hash value: 883dfd33ca047e3ac10d5667ffdef7b8005cac58b95055c2c2beda44bec49bd0
Verifying Hash Integrity ... sha256+ OK
Loading loadables from 0x90a5a780 to 0x82000000
Labi, mÄs esam sasnieguÅ”i nÄkamo lÄ«meni, bet tas joprojÄm ir salst. Un dažreiz tas arÄ« apkaisa izÅÄmumus. JÅ«s varat redzÄt mcause, gaidot kodu norÄdÄ«tajÄ adresÄ $pc
un tad si
bÅ«t ieslÄgtam trap_entry
. Pats U-Boot apstrÄdÄtÄjs var izvadÄ«t tikai mcause = 0..4, tÄpÄc esiet gatavs iestrÄgt nepareizÄ sÄknÄÅ”anas gadÄ«jumÄ. Tad es iegÄju konfigurÄcijÄ, sÄku skatÄ«ties, ko mainu, un atcerÄjos: tur iekÅ”Ä conf/rvboot-fit.txt
rakstīts:
fitfile=image.fit
# below much match what's in FIT (ugha)
Labi, sakÄrtosim visus failus, nomainiet kodola komandrindu ar kaut ko lÄ«dzÄ«gu, jo pastÄv aizdomas, ka SIF0
- Ŕī ir izvade kaut kur caur PCIe:
-bootargs=console=ttySIF0,921600 debug
+bootargs=console=ttyS0,125200 debug
MainÄ«sim jaukÅ”anas algoritmu no SHA-256 uz MD5: man nav vajadzÄ«ga kriptogrÄfijas stiprums (it Ä«paÅ”i atkļūdoÅ”anas laikÄ), tas aizÅem Å”ausmÄ«gi ilgu laiku, un, lai ielÄdes laikÄ uztvertu integritÄtes kļūdas, MD5 ir pÄrÄk viegli. KÄds ir gala rezultÄts? IepriekÅ”Äjo lÄ«meni sÄkÄm pabeigt ievÄrojami ÄtrÄk (vienkÄrÅ”Äkas jaukÅ”anas dÄļ), un tika atvÄrts nÄkamais:
...
Verifying Hash Integrity ... md5+ OK
Loading loadables from 0x90a5a758 to 0x82000000
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
chosen {
linux,initrd-end = <0x00000000 0x83000000>;
linux,initrd-start = <0x00000000 0x82000000>;
riscv,kernel-end = <0x00000000 0x80a00000>;
riscv,kernel-start = <0x00000000 0x80200000>;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
};
libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND
chosen {
linux,initrd-end = <0x00000000 0x83000000>;
linux,initrd-start = <0x00000000 0x82000000>;
riscv,kernel-end = <0x00000000 0x80a00000>;
riscv,kernel-start = <0x00000000 0x80200000>;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
};
Loading Kernel Image ... OK
Booting kernel in
3
Bet pulkstenis negriežas...
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000
Ups, izskatÄs, ka pulksteÅa laboÅ”ana izrÄdÄ«jÄs placebo, lai gan man toreiz Ŕķita, ka tas palÄ«dz. NÄ, tas, protams, ir jÄlabo, taÄu vispirms pagriezÄ«sim bultiÅas manuÄli un paskatÄ«simies, kas notiek:
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=1000000
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=2000000
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=3000000
(gdb) c
Continuing.
TikmÄrā¦
Loading Kernel Image ... OK
Booting kernel in
3
2
1
0
## Starting application at 0x80000000 ...
NÄ, es ieÅ”u automatizÄt pulksteni - pretÄjÄ gadÄ«jumÄ viÅÅ” varbÅ«t nolems kalibrÄt taimeri tur!
TikmÄr paÅ”reizÄjÄs instrukcijas adrese norÄda kaut kur
0000000080001c20 <poweroff>:
80001c20: 1141 addi sp,sp,-16
80001c22: e022 sd s0,0(sp)
80001c24: 842a mv s0,a0
80001c26: 00005517 auipc a0,0x5
80001c2a: 0ca50513 addi a0,a0,202 # 80006cf0 <softfloat_countLeadingZeros8+0x558>
80001c2e: e406 sd ra,8(sp)
80001c30: f7fff0ef jal ra,80001bae <printm>
80001c34: 8522 mv a0,s0
80001c36: 267000ef jal ra,8000269c <finisher_exit>
80001c3a: 00010797 auipc a5,0x10
80001c3e: 41e78793 addi a5,a5,1054 # 80012058 <htif>
80001c42: 639c ld a5,0(a5)
80001c44: c399 beqz a5,80001c4a <poweroff+0x2a>
80001c46: 72c000ef jal ra,80002372 <htif_poweroff>
80001c4a: 45a1 li a1,8
80001c4c: 4501 li a0,0
80001c4e: dc7ff0ef jal ra,80001a14 <send_ipi_many>
80001c52: 10500073 wfi
80001c56: bff5 j 80001c52 <poweroff+0x32>
ielÄdÄtÄ Berkeley sÄknÄÅ”anas ielÄdÄtÄjÄ. Mani personÄ«gi mulsina pieminÄÅ”ana htif
ā resursdatora saskarne, ko izmanto kodola piesietai palaiÅ”anai (tas ir, sadarbÄ«bÄ ar resursdatora ARM), es pieÅÄmu, ka tas ir savrups. TomÄr, ja atrodat Å”o funkciju avota kodÄ, varat redzÄt, ka ne viss ir tik slikti:
void poweroff(uint16_t code)
{
printm("Power offrn");
finisher_exit(code);
if (htif) {
htif_poweroff();
} else {
send_ipi_many(0, IPI_HALT);
while (1) { asm volatile ("wfin"); }
}
}
Uzdevums: sÄciet pulksteni
ReÄ£istru meklÄÅ”ana CLINT mÅ«s noved pie
val io = IO(new Bundle {
val rtcTick = Bool(INPUT)
})
val time = RegInit(UInt(0, width = timeWidth))
when (io.rtcTick) { time := time + UInt(1) }
Kas savienojas ar RTC vai noslÄpumaino MockAON, par kuru es sÄkumÄ domÄju: āKas mums Å”eit ir? Vai nav skaidrs? IzslÄgsim to!" TÄ kÄ es joprojÄm nesaprotu, kÄda pulksteÅa maÄ£ija tur notiek, es vienkÄrÅ”i ieviesÄ«Å”u Å”o loÄ£iku System.scala
:
val rtcDivider = RegInit(0.asUInt(16.W)) // Š½Š° Š²ŃŃŠŗŠøŠ¹ ŃŠ»ŃŃŠ°Š¹ ŠæŠ¾Š“Š“ŠµŃŠ¶Ń Š“Š¾ 16ŠŠŃ, Ń Š¾ŠæŃŠøŠ¼ŠøŃŃ :)
val mhzInt = p(DevKitFPGAFrequencyKey).toInt
// ŠŃŠµŠæŠ¾Š»Š¾Š¶ŠøŠ¼, ŃŠ°ŃŃŠ¾ŃŠ° ŃŠ°Š²Š½Š° ŃŠµŠ»Š¾Š¼Ń ŃŠøŃŠ»Ń Š¼ŠµŠ³Š°Š³ŠµŃŃ
rtcDivider := Mux(rtcDivider === (mhzInt - 1).U, 0.U, rtcDivider + 1.U)
outer.clintOpt.foreach { clint =>
clint.module.io.rtcTick := rtcDivider === 0.U
}
Dodamies uz Linux kodolu
Å eit stÄsts jau ir ievilcies un kļuvis nedaudz vienmuļŔ, tÄpÄc aprakstÄ«Å”u to no augÅ”as uz leju:
BBL pieÅÄma FDT klÄtbÅ«tni plkst 0xF0000000
, bet es jau izlaboju! Nu, paskatÄ«simies vÄlreiz... Atradu iekÅ”Ä HiFive_U-Boot/arch/riscv/lib/boot.c, aizvietots ar 0x81F00000
, kas norÄdÄ«ta U-Boot sÄknÄÅ”anas konfigurÄcijÄ.
Tad BBL sÅ«dzÄjÄs, ka nav atmiÅas. Mans ceļŔ bija funkcijÄ mem_prop
, kas iekÅ”Ä riscv-pk/machine/fdt.c: no turienes es uzzinÄju, ka jums ir jÄatzÄ«mÄ fdt ram mezgls kÄ device_type = "memory"
- tad, iespÄjams, procesora Ä£enerators bÅ«s jÄlabo, bet pagaidÄm es to ierakstÄ«Å”u tikai manuÄli - jebkurÄ gadÄ«jumÄ es manuÄli pÄrsÅ«tÄ«ju Å”o failu.
Tagad es saÅÄmu ziÅojumu (nodroÅ”inÄts formatÄtÄ veidÄ ar vagona atgrieÅ”anu):
This is bbl's dummy_payload. To boot a real kernel, reconfigure bbl
with the flag --with-payload=PATH, then rebuild bbl. Alternatively,
bbl can be used in firmware-only mode by adding device-tree nodes
for an external payload and use QEMU's -bios and -kernel options.
Å Ä·iet, ka iespÄjas ir norÄdÄ«tas pÄc vajadzÄ«bas riscv,kernel-start
Šø riscv,kernel-end
DTB, bet nulles tiek parsÄtas. AtkļūdoÅ”ana query_chosen
parÄdÄ«ja, ka BBL mÄÄ£ina parsÄt 32 bitu adresi, bet tas saskaras ar pÄri <0x0 0xADDR>
, un Ŕķiet, ka pirmÄ vÄrtÄ«ba ir vismazÄk nozÄ«mÄ«gie biti. Pievienots sadaļai chosen
chosen {
#address-cells = <1>;
#size-cells = <0>;
...
}
un laboja vÄrtÄ«bu Ä£enerÄÅ”anu: nepievieno 0x0
pirmais elements.
Å Ä«s 100500 XNUMX vienkÄrÅ”Äs darbÄ«bas atvieglos pingvÄ«na kriÅ”anas vÄroÅ”anu:
SlÄpts teksts
Verifying Hash Integrity ... md5+ OK
Loading loadables from 0x90a5a758 to 0x82000000
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
chosen {
linux,initrd-end = <0x83000000>;
linux,initrd-start = <0x82000000>;
riscv,kernel-end = <0x80a00000>;
riscv,kernel-start = <0x80200000>;
#address-cells = <0x00000001>;
#size-cells = <0x00000000>;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
stdout-path = "uart0:38400n8";
};
libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND
chosen {
linux,initrd-end = <0x83000000>;
linux,initrd-start = <0x82000000>;
riscv,kernel-end = <0x80a00000>;
riscv,kernel-start = <0x80200000>;
#address-cells = <0x00000001>;
#size-cells = <0x00000000>;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
stdout-path = "uart0:38400n8";
};
Loading Kernel Image ... OK
Booting kernel in
3
2
1
0
## Starting application at 0x80000000 ...
bbl loader
SIFIVE, INC.
5555555555555555555555555
5555 5555
5555 5555
5555 5555
5555 5555555555555555555555
5555 555555555555555555555555
5555 5555
5555 5555
5555 5555
5555555555555555555555555555 55555
55555 555555555 55555
55555 55555 55555
55555 5 55555
55555 55555
55555 55555
55555 55555
55555 55555
55555 55555
555555555
55555
5
SiFive RISC-V Core IP
[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[ 0.000000] Linux version 4.19.0-sifive-1+ (trosinenko@trosinenko-pc) (gcc version 8.3.0 (Buildroot 2019.02-07449-g4eddd28f99)) #1 SMP Wed Jul 3 21:29:21 MSK 2019
[ 0.000000] bootconsole [early0] enabled
[ 0.000000] Initial ramdisk at: 0x(____ptrval____) (16777216 bytes)
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] Normal [mem 0x00000000c0000000-0x00000bffffffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] On node 0 totalpages: 261632
[ 0.000000] DMA32 zone: 3577 pages used for memmap
[ 0.000000] DMA32 zone: 0 pages reserved
[ 0.000000] DMA32 zone: 261632 pages, LIFO batch:63
[ 0.000000] software IO TLB: mapped [mem 0xbb1fc000-0xbf1fc000] (64MB)
(logotipu parÄda BBL, bet logotipu ar laikspiedoliem parÄda kodols).
Par laimi, es nezinu, kÄ tas ir visur, bet RocketChip, pievienojot atkļūdotÄju, izmantojot JTAG, jÅ«s varat noÄ·ert slazdus no kastes - atkļūdotÄjs apstÄsies tieÅ”i Å”ajÄ brÄ«dÄ«.
Program received signal SIGTRAP, Trace/breakpoint trap.
0xffffffe0000024ca in ?? ()
(gdb) bt
#0 0xffffffe0000024ca in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) file work/linux/vmlinux
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from work/linux/vmlinux...done.
(gdb) bt
#0 0xffffffe0000024ca in setup_smp () at /hdd/trosinenko/fpga/freedom-u-sdk/linux/arch/riscv/kernel/smpboot.c:75
#1 0x0000000000000000 in ?? ()
Backtrace stopped: frame did not save the PC
freedom-u-sdk/linux/arch/riscv/kernel/smpboot.c:
void __init setup_smp(void)
{
struct device_node *dn = NULL;
int hart;
bool found_boot_cpu = false;
int cpuid = 1;
while ((dn = of_find_node_by_type(dn, "cpu"))) {
hart = riscv_of_processor_hartid(dn);
if (hart < 0)
continue;
if (hart == cpuid_to_hartid_map(0)) {
BUG_ON(found_boot_cpu);
found_boot_cpu = 1;
continue;
}
cpuid_to_hartid_map(cpuid) = hart;
set_cpu_possible(cpuid, true);
set_cpu_present(cpuid, true);
cpuid++;
}
BUG_ON(!found_boot_cpu); // < ŠŠ« ŠŠŠ„ŠŠŠŠ¢ŠŠ”Š¬ ŠŠŠŠ”Š¬
}
KÄ teica vecais joks, CPU nav atrasts, darbojas programmatÅ«ras emulÄcija. Nu vai neskrien. Pazudis vienÄ procesora kodolÄ.
/* The lucky hart to first increment this variable will boot the other cores */
atomic_t hart_lottery;
unsigned long boot_cpu_hartid;
Labs komentÄrs iekÅ”Ä linux/arch/riscv/kernel/setup.c - sava veida žoga krÄsoÅ”ana, izmantojot Toma Sojera metodi. VispÄr nez kÄpÄc Å”odien nebija uzvarÄtÄju, balva tiek pÄrcelta uz nÄkamo izlozi...
Å eit es ierosinu beigt jau tÄ garo rakstu.
TurpinÄjums sekos. BÅ«s cÄ«Åa ar viltÄ«gu blakti, kas izdodas paslÄpties, ja lÄnÄm piezagsies tai ar vienu soli.
Teksta lejupielÄdes ekrÄnuzÅÄmums (ÄrÄja saite):
Avots: www.habr.com