I en har blivit implementerad en mer eller mindre fungerande minneskontroller, nĂ€rmare bestĂ€mt en omslag runt IP Core frĂ„n Quartus, som fungerar som en adapter till TileLink. Idag i artikeln "Portera RocketChip till ett mindre kĂ€nt kinesiskt kort med Cyclone" fĂ„r du se en fungerande konsol. Processen drog ut pĂ„ tiden: jag trodde att jag snabbt skulle kunna starta Linux och gĂ„ vidare, men sĂ„ blev det inte. I denna del föreslĂ„r jag att vi tittar pĂ„ processen för att starta U-Boot, BBL och de trevande försöken att fĂ„ Linux-kĂ€rnan att initieras. Men det finns en konsol â en U-Boot-konsol, som Ă€r ganska avancerad och har mycket av det du förvĂ€ntar dig frĂ„n en fullfjĂ€drad konsol.
I hÄrdvarudelen tillkommer ett SD-kort som Àr anslutet via SPI-grÀnssnitt, samt UART. I mjukvarudelen kommer BootROM att bytas ut mot xip till sdboot och faktiskt lÀggas till följande laddningssteg (pÄ SD-kortet).
FörbÀttring av hÄrdvarudelen
SÄ, uppgiften: vi behöver gÄ över till ett "stort" kÀrn och ansluta UART (frÄn Raspberry) och SD-adapter (en viss platta frÄn Catalex med sex stift: GND, VCC, MISO, MOSI, SCK, CS).
I princip var allt ganska enkelt. Men innan jag insĂ„g det, blev jag lite kastad fram och tillbaka: efter förra gĂ„ngen beslutade jag att det Ă„terigen var dags att bara blanda in i System nĂ„got som HasPeripheryUART (och i implementeringen dĂ€rmed), samma för SD-kortet â och allt skulle vara klart. Sedan beslöt jag mig för att se hur det var implementerat i en "seriös" design. SĂ„, vad har vi hĂ€r av seriöst? Arty verkar inte passa â det Ă„terstĂ„r monstret unleahshed.DevKitConfigs. Och plötsligt upptĂ€ckte jag att det fanns överallt nĂ„gra overlay, som lĂ€ggs till via parameternycklar. Jag misstĂ€nker att detta nog Ă€r mycket flexibelt och konfigurerbart, men jag skulle vilja ha nĂ„got för att starta Ă„tminstone... Har ni nĂ„got liknande, men bara enklare och mer lurt?.. DĂ€r stötte jag pĂ„ vera.iofpga.FPGAChip för Microsemi FPGA och jag punkterade pĂ„ citat och försökte göra min egen implementation genom analogi, eftersom hĂ€r finns mer eller mindre hela "systemkortets" layout i en fil.
Det visade sig verkligen att man bara behövde lÀgga till i System.scala raderna
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
...Rad i klassens kropp System lĂ€gger till information om frekvensen som denna del av vĂ„r SoC arbetar vid, i dts-filen. SĂ„ vitt jag förstĂ„r, Ă€r DTS/DTB en statisk motsvarighet till plug-and-play-teknologi för inbyggda enheter: dtrĂ€dets dts-beskrivning kompileras till en binĂ€r dtb-fil och överförs av bootloadern till kĂ€rnan, sĂ„ att den kan stĂ€lla in hĂ„rdvaran korrekt. Intressant nog, utan raden med tlclock syntetiseras allt bra, men att kompilera BootROM (lĂ„t mig pĂ„minna, nu kommer det att bli sdboot) gĂ„r inte â under kompileringen parser den dts-filen och skapar en header med makrot TL_CLK, som gör att den kan stĂ€lla in frekvensdelarna för externa grĂ€nssnitt korrekt.
Det kommer ocksÄ att krÀvas lite justering av "layouten":
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-kort
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
}Registreringskedjor har, Ă€rligt talat, lagts till helt enkelt som en analogi med vissa andra delar av den ursprungliga koden. De ska troligen skydda mot . Kanske finns det redan nĂ„got skydd i vissa block, men först vill jag kunna starta Ă„tminstone "pĂ„ en kvalitetsnivĂ„". En mer intressant frĂ„ga för mig Ă€r â varför MISO och MOSI hĂ€nger pĂ„ olika dq? ĐŃĐČĐ”Ńа Ń ĐżĐŸĐșа ŃаĐș Đž ĐœĐ” ĐœĐ°ŃŃĐ», ĐœĐŸ, ĐżĐŸŃ
ĐŸĐ¶Đ”, ĐŸŃŃалŃĐœĐŸĐč ĐșĐŸĐŽ ŃаŃŃŃĐžŃŃĐČĐ°Đ”Ń ĐžĐŒĐ”ĐœĐœĐŸ ĐœĐ° ŃаĐșĐŸĐ” ĐżĐŸĐŽĐșĐ»ŃŃĐ”ĐœĐžĐ”.
Fysiskt har jag helt enkelt tilldelat utgÄngarna i designen till lediga kontakter pÄ kontaktdonen och flyttat hopkopplaren för spÀnningsval till 3.3V.
SD-adapter
Ăversikt uppifrĂ„n:

Ăversikt nedifrĂ„n:

Debuggning av programvaran: verktyg
För att börja, lÄt oss diskutera de tillgÀngliga felsökningsverktygen och deras begrÀnsningar.
Minicom
Först mĂ„ste vi pĂ„ nĂ„got sĂ€tt lĂ€sa vad bootloadern och kĂ€rnan skriver ut. För detta i Linux (i detta fall â pĂ„ den som körs pĂ„ RaspberryPi) behöver vi programmet Minicom. Generellt sett, vilket som helst program för arbete med seriell port fungerar.
Observera att nĂ€r du startar, mĂ„ste du ange portens enhetsnamn som -D \/dev\/ttyS0 â efter alternativet , kommer den att lĂ€gga den senaste blocken av masterkedjan i den:. Och den viktigaste informationen: för att avsluta, anvĂ€nd Ctrl-A, X. Jag hade faktiskt en gĂ„ng dĂ„ denna kombination inte fungerade â dĂ„ kan du bara frĂ„n en annan SSH-session sĂ€ga killall -KILL minicom.
Det finns ocksÄ en annan egenskap. Specifikt pÄ Raspberry Pi finns det tvÄ UART:ar, och bÄda portar kan redan vara anpassade för nÄgot: en för Bluetooth, medan den andra som standard visar kÀrnans konsol. Som tur Àr kan detta beteende omkonfigureras. .
MinnesÄterstÀllning.
Vid felsökning har jag ibland behövt för att verifiera hypotesen. ladda bootloadern (ursÀkta) i RAM direkt frÄn vÀrden. Kanske kan det göras direkt frÄn GDB, men jag valde den enklare vÀgen: kopierade den nödvÀndiga filen till Raspberry och vidarebefordrade Àven port 4444 via SSH (telnet frÄn OpenOCD) och anvÀnde kommandot. load_image. NÀr du kör det verkar det som om allt har frusit, men i sjÀlva verket «det sover inte, det blinkar bara lÄngsamt»: det laddar filen, det gör det bara med en hastighet av ett par kilobytar per sekund.
Egenskaper hos att placera breakpoints.
MÄnga kanske aldrig har tÀnkt pÄ detta vid felsökning av vanliga program, men breakpoints sÀtts inte alltid hÄrdvarumÀssigt. Ibland innebÀr det att tillfÀlligt skriva en sÀrskild instruktion pÄ rÀtt plats. direkt i maskinkoden.Till exempel fungerade det sÄ med den standardkommandot b i GDB. HÀr Àr vad som följer av detta:
- du kan inte sÀtta en punkt inne i BootROM eftersom ROM
- det gÄr att sÀtta en breakpoint pÄ koden som laddas in i RAM frÄn SD-kortet, men du mÄste vÀnta tills den har laddats. Annars kommer vi inte att skriva över en bit av koden, utan bootloadern kommer att skriva över vÄr breakpoint.
Jag Àr sÀker pÄ att man tydligt kan be om att anvÀnda hÄrdvarubaserade breakpoints, men de Àr ÀndÄ begrÀnsade i antal.
Snabb omkoppling av BootROM.
I det inledande skedet av felsökningen finns ofta en önskan att fixa BootROM och försöka igen. Men det finns ett problem: BootROM Àr en del av designen som laddas in i FPGA:n, och dess syntes tar nÄgra minuter (och detta efter nÀstan omedelbar kompilering av sjÀlva BootROM-avbildningen frÄn C och assembler...). Som tur Àr Àr allt faktiskt mycket snabbare: sekvensen av ÄtgÀrder Àr sÄdan:
- Ätergenerera bootrom.mif (jag bytte till MIF istÀllet för HEX, eftersom jag alltid hade problem med HEX, medan MIF Àr det ursprungliga ALTERA-formatet)
- i Quartus sÀger
Bearbetning -> Uppdatera minnesinitialiseringsfilen. - i punkten Assembler (i vÀnstra kolumnen Uppgifter) ge kommandot Starta om igen.
Allt som allt - ett par tiotal sekunder.
Förberedelse av SD-kort.
HÀr Àr allt relativt enkelt, men du behöver ha tÄlamod och ungefÀr 14Gb diskutrymme:
git clone https://github.com/sifive/freedom-u-sdk
git submodule update --recursive --init
makeDÀrefter behöver du sÀtta i ett rent, det vill sÀga, utan nÄgot viktigt, SD-kort och utföra
sudo make DISK=/dev/sdX format-boot-loader⊠dĂ€r sdX â enheten som tilldelats kortet. VARNING: Data pĂ„ kortet kommer att raderas, skrivas över och helt enkelt försvinna! Det Ă€r nog ingen bra idĂ© att göra hela byggprocessen som sudo, för dĂ„ kommer alla byggartefakter att tillhöra root, och bygget mĂ„ste göras som sudo konstant.
Resultatet Àr ett kort som Àr partitionerat i GPT med fyra partitioner, dÀr en av dem har FAT med uEnv.txt och en bootbar bild i FIT-format (den innehÄller flera delbilder, var och en med sin laddningsadress), den andra partitionen Àr tom och avsedd att formateras i Ext4 för Linux. De andra tvÄ partitionerna Àr mysteriska: pÄ en lagrar U-Boot (dess förskjutning Àr, sÄvitt jag förstÄr, kodad i BootROM), pÄ den andra verkar dess miljövariabler bo, men jag anvÀnder dem inte Àn.
NivÄ ett, BootROM
Det finns ett ordsprĂ„k som sĂ€ger: "Om det finns dans kring trummor i programmering, sĂ„ Ă€r det Ă€ven med brandslĂ€ckare i elektronik". Det handlar inte ens om att jag en gĂ„ng nĂ€stan brĂ€nde kortet, eftersom jag trodde att "NĂ„vĂ€l, GND Ă€r ju samma som lĂ„g nivĂ„" (ett motstĂ„nd skulle uppenbarligen inte ha skadat...) Det handlar snarare om att om hĂ€nderna inte vĂ€xer frĂ„n rĂ€tt stĂ€lle, fortsĂ€tter elektroniken att överraska: nĂ€r jag lödde kontakten pĂ„ kortet, kunde jag inte fĂ„ kontakterna att löda ordentligt â pĂ„ videoklipp visar de hur lödtennet bara flyter ut över hela anslutningen, bara sĂ€tt lödkolven pĂ„, men hos mig "fastnade" det hur som helst. Ja, kanske lödtennet inte passade temperaturen pĂ„ lödkolven, kanske nĂ„got annat⊠I allmĂ€nhet, nĂ€r jag sĂ„g att jag hade ett dussin kontakter, gav jag upp och började felsöka. Och hĂ€r började det mystiska: jag kopplade RX/TX frĂ„n UART:en, laddade firmware â det stĂ„r
INIT
CMD0
ERRORNĂ„vĂ€l, allt Ă€r logiskt â jag hade inte kopplat in SD-kortmodulen. Jag Ă„tgĂ€rdar situationen, laddar firmware... Och tystnad... Vad jag Ă€n tĂ€nkte pĂ„, men problemet var enkelt: en av benen pĂ„ modulen behövde kopplas till VCC. I mitt fall stöddes 5V för strömförsörjning av modulen, sĂ„ jag, utan att tveka, kopplade den trĂ„d som strĂ€ckte sig frĂ„n modulen till motsatt sida av kortet. Som resultat blev den dĂ„ligt lödda kontakten sned. bara förlorade kontakt med UART. facepalm.jpg I allmĂ€nhet, "en dĂ„lig skalle ger inte benen ro", och sneda hĂ€nder â skallen...
Till slut sÄg jag det lÀngtade i Minicom
INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING /Dessutom rör sig laddningsindikatorn. Det pÄminner mig om skoltiden och den lÄngsamma laddningen av MinuetOS frÄn disketten. Det enda som saknas Àr att diskettstationen inte skrapar.
Problemet Àr att efter meddelandet BOOT hÀnder inget. Det var dags att koppla upp via OpenOCD pÄ Raspberry, med GDB pÄ vÀrden och se vad det handlar om.
För det första visade anslutningen med GDB genast att $pc (programrĂ€knare, adressen för den aktuella instruktionen) flyger ivĂ€g till 0x0 â troligen hĂ€nder detta efter flera fel. SĂ„ snart som meddelandet visas BOOT lĂ€gger vi till en oĂ€ndlig loop. Det kommer att försena det en stund...
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;
}En sÄ hÀr listig kod anvÀnds "för tillförlitlighet": jag har hört nÄgonstans att oÀndliga loopar kan vara Undefined Behavior, och hÀr lÀr kompilatorn knappast förstÄ. 0x10000 Jag pÄminner om att BootROM finns.

Man skulle kunna förvĂ€nta sig, vad förvĂ€ntar man sig â en hĂ„rd inbyggd lösning, vad Ă€r det för kĂ€llkod hĂ€r. Men i debatten var att författa C-kod... Kreks-feks-peks:
(gdb) file builds/zeowaa-e115/sdboot.elf
Ett program debuggas redan.
Ăr du sĂ€ker pĂ„ att du vill Ă€ndra filen? (y eller n) y
LÀser symboler frÄn builds/zeowaa-e115/sdboot.elf... klart.
Det behöver laddas inte MIF-filen eller bin, utan den ursprungliga versionen i ELF-format.
Nu kan man med en viss chans gissa adressen dÀr exekveringen fortsÀtter (detta Àr ytterligare en anledning till varför kompilatorn inte borde ha gissat att loopen Àr oÀndlig). Kommandot
set variable $pc=0xADDRtillĂ„ter att Ă€ndra registrets vĂ€rde pĂ„ sprĂ„ng (i detta fall â adressen för den aktuella instruktionen). Med detta kan man ocksĂ„ Ă€ndra vĂ€rden som sparats i minnet (och minnesmĂ€ppade register).
Till slut kom jag fram till slutsatsen (Àr osÀker pÄ om den Àr korrekt) att vi har "sd-kortavbilden av det systemet", och man ska inte gÄ till början av de laddade data utan till 0x89800 nÄgra byte lÀngre:
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 .rodataDet kan ocksĂ„ ha pĂ„verkats av att jag, utan en onödig 4Gb-kort till hands, tog ett 2Gb-kort och bytte ut det i Makefile med en del trial and error. DEMO_END=11718750 till DEMO_END=3078900 (sök inte efter mening i det specifika vĂ€rdet â det finns inget, det Ă€r bara sĂ„ att bilden nu fĂ„r plats pĂ„ kortet).
NivÄ tvÄ, U-Boot
Nu "faller" vi fortfarande, men har redan nÄtt adressen 0x0000000080089a84. HÀr mÄste jag erkÀnna: faktiskt gÄr redogörelsen inte "med alla stopp", utan skrivs delvis "efterÄt", sÄ hÀr har jag redan lyckats lÀgga till den rÀtta dtb-filen frÄn vÄr SoC, och rÀttat i instÀllningarna. HiFive_U-Boot variabel CONFIG_SYS_TEXT_BASE=0x80089800 (i stÀllet för 0x08000000), sÄ att laddningsadressen överensstÀmmer med den faktiska. Nu laddar vi en karta pÄ nÀsta nivÄ med en annan bild:
(gdb) file ..\/freedom-u-sdk\/work\/HiFive_U-Boot\/u-boot
(gdb) tui enOch vi ser:
â304 * â
â305 * fĂ€lla intĂ€de â
â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) âVi hoppar mellan raderna 308 och 309. Och inte helt ovĂ€ntat, med tanke pĂ„ att i $sp ligger vĂ€rdet 0xfffffffe31cdc0a0. TyvĂ€rr "springer" det Ă€ven bort pĂ„ grund av raden 307. SĂ„ vi provar att sĂ€tta en stopppunkt pĂ„ trap_entry, och sedan Ă„tergĂ„ till 0x80089800 (U-Boots intrĂ€despunkt), och hoppas att det inte krĂ€ver korrekt instĂ€llda register innan övergĂ„ngen... Det verkar fungera:
(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
FortsÀtter.
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 = 0x81cf950En ganska dÄlig stackpekare, fÄr man sÀga: den pekar faktiskt bortom RAM (om vi inte redan har adressöversÀttning, men vi hoppas pÄ det enkla alternativet).
Vi provar att byta pekaren till 0x881cf950. Slutligen kommer vi fram till att handle_trap anropas och anropas, medan vi gÄr in i _exit_trap med argumentet epc=2148315240 (i decimalform):
(gdb) x/10i 2148315240
0x800cb068 : lbu a4,0(a5)
0x800cb06c : bnez a4,0x800cb078
0x800cb070 : sub a0,a5,a0
0x800cb074 : ret
0x800cb078 : addi a5,a5,1
0x800cb07c : j 0x800cb064
0x800cb080 : addi sp,sp,-32
0x800cb084 : sd s0,16(sp)
0x800cb088 : sd ra,24(sp)
0x800cb08c : li s0,0Vi sÀtter en breakpoint pÄ strnlen, fortsÀtter och ser:
(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=, precision=, flags=) 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 x , ra lxn", fmt@entry=0x800d4458 "exception code: %d , %s , epc x , ra lxn", 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 x , ra lxn", 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 x , ra lxn", args=args@entry=0x881cc188) at lib/vsprintf.c:717
#5 0x00000000800ccb50 in printf (fmt=fmt@entry=0x800d4458 "exception code: %d , %s , epc x , ra lxn") at lib/vsprintf.c:792
#6 0x000000008008a9f0 in _exit_trap (regs=, epc=2148315240, code=) at arch/riscv/lib/interrupts.c:92
#7 handle_trap (mcause=, epc=, regs=) 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 PCDet verkar som _exit_trap vill ge debuginformation om den intrÀffade undantaget, men lyckas inte. SÄ, nÄgot visar Äterigen inte kÀllorna. set directories ../freedom-u-sdk/HiFive_U-Boot/ O! Nu visas de!
LÄt oss starta en gÄng till och se pÄ stackspÄret för att hitta orsaken till det ursprungliga problemet som orsakade det första felet (mcause == 5). Om jag förstÄtt rÀtt det som stÄr pÄ sidan 37, sÄ innebÀr detta undantag Ladda Ätkomstfel. Anledningen verkar vara att hÀr
arch/riscv/cpu/HiFive/start.S:
call_board_init_f:
li t0, -16
li t1, CONFIG_SYS_INIT_SP_ADDR
and sp, t1, t0 /* tvinga 16-byte justering */
#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 /* hoppa till board_init_f() */
$sp har det felaktiga vĂ€rdet, och inne i board_init_f_init_reserve uppstĂ„r ett fel. Det verkar som att skulden ligger hos: variabeln med det tydliga namnet CONFIG_SYS_INIT_SP_ADDR. Den definieras i filen HiFive_U-Boot/include/configs/HiFive-U540.hVid nĂ„got tillfĂ€lle övervĂ€gde jag till och med om det vore enklare att justera processorn istĂ€llet för att finjustera bootloadern â men sen insĂ„g jag att det mer liknade ett artefakt frĂ„n ofullstĂ€ndiga instĂ€llningar för en annan minneskonfiguration, och man kan försöka göra sĂ„ hĂ€r:#if 0-
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 */Vid nÄgot tillfÀlle nÄdde antalet workaround:er en kritisk nivÄ. Efter att ha kÀmpat lite kom jag fram till att jag var tvungen att göra en korrekt portering till mitt styrenhet. För detta behöver jag kopiera och justera ett antal filer till vÄr konfiguration.
NÄvÀl, ungefÀr sÄ hÀr
trosinenko@trosinenko-pc:/hdd/trosinenko/fpga/freedom-u-sdk/HiFive_U-Boot$ git show --name-status
commit 39cd67d59c16ac87b46b51ac1fb58f16f1eb1048 (HEAD -> zeowaa-1gb)
Author: Anatoly Trosinenko
Date: Tue Jul 2 17:13:16 2019 +0300
Inledande stöd för Zeowaa A-E115FB kort
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.hDetaljer kan ses i .
Som det visade sig har registren för vissa enheter pĂ„ detta SiFive-kort olika adresser. Det visade sig ocksĂ„ att U-Boot konfigureras med det bekanta Kconfig-mekanismen frĂ„n Linux-kĂ€rnan â till exempel kan man kommandera make menuconfig, och framför dig kommer en anvĂ€ndarvĂ€nlig textbaserad grĂ€nssnitt med beskrivningar av parametrarna. ? Och sĂ„ vidare. SĂ„, genom att sĂ€tta ihop beskrivningarna av de tvĂ„ plattorna skapade jag en beskrivning av den tredje, slĂ€ppte allt pretentiöst kring PLL-omkonfigurationer (det verkar ha nĂ„got att göra med styrning frĂ„n vĂ€rddatorn via PCIe, men jag Ă€r inte sĂ€ker), fick jag en viss firmware som, under rĂ€tt förhĂ„llanden pĂ„ Mars, gav mig ett meddelande via UART om vilken commit-hash den var sammansatt frĂ„n, och hur mycket DRAM jag hade (men den informationen angav jag sjĂ€lv i headern).
TyvĂ€rr, efter detta slutade plattan vanligtvis att svara via processor JTAG, och att ladda frĂ„n SD-kortet Ă€r, tyvĂ€rr, inte snabbt i min konfiguration. Ă
andra sidan gav BootROM ibland ett meddelande att ERROR, det gÄr inte att starta, och i samma veva dök U-Boot upp. Det slog mig dÄ: uppenbarligen, efter omstarten sÄ rensar inte bitstream i FPGA-minnet, det hinner inte "tappas" och sÄ vidare. Kort sagt kan man helt enkelt, nÀr meddelandet LOADING / dyker upp, koppla in debuggern och ge kommandot set variable $pc=0x80089800, pÄ sÄ sÀtt hoppa över den lÄnga uppstarten (naturligtvis med antagandet att det gick sönder tillrÀckligt tidigt förra gÄngen och inte hann ladda nÄgot ovanpÄ originalkoden).
Förresten, Àr det normalt att processorn fryser helt, och JTAG-debuggern inte kan koppla upp sig med meddelandena
Error: unable to halt hart 0
Error: dmcontrol=0x80000001
Error: dmstatus =0x00030c82VĂ€nta lite! Jag har sett detta förut! NĂ„got liknande hĂ€nder vid en dödlĂ„sning av TileLink, och jag litar inte riktigt pĂ„ författaren av minneskontrollern â jag skrev det sjĂ€lv... Plötsligt, efter den första lyckade omkompileringen av processorn efter att jag redigerade kontrollern sĂ„g jag:
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: 3Vid denna mÀrkliga rad framför In: serial Ignorera detta - jag försökte förstÄ hur det fungerar med processorn som hÀnger. Vad betyder "Det har hÀngt i tio minuter"? Har det Ätminstone lyckats relocera sig och gÄ till startmenyn? En liten avstickare: Àven om U-Boot laddas bland de första 2^24 byte frÄn SD-kortet, kopierar det sig sjÀlv lÀngre bort till en adress som antingen Àr skriven i konfigurationshuvudet eller helt enkelt i de högre adresserna av RAM-minnet, gör en relocation av ELF-symboler, och överför kontrollen dit. SÄ hÀr Àr lÀget: det verkar som om det nivÄer passerats och som bonus fÄtt en processor som inte hÀnger helt efter det.
SÄ, varför fungerar inte timern? Det verkar som klockan överhuvudtaget av nÄgon anledning inte tickar...
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000Vad hÀnder om man snurrar visarna manuellt?
(gdb) set variable *0x0200bff8=310000000
(gdb) cDĂ„:
Tryck pÄ valfri tangent för att stoppa autoboot: 0
MMC_SPI: 0 vid 0:1 hz 20000000 lÀge 0Resultat: klockan tickar inte. Troligtvis beror detta pÄ att tangentbordsinmatning inte fungerar:
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:
/* Första tecknet av ANSI escape-sekvensen 'e' */
if (c == 'e') {
*esc = 1;
*key = KEY_NONE;
}
break;
case 1:
/* Andra tecknet av ANSI '[' */
if (c == '[') {
...Problemet visade sig vara att jag överdrivit lite: jag lade till en nyckel i processorconfigurationsfilen:
case DTSTimebase => BigInt(0)⊠med tanke pÄ att det standades "om du inte vet - lÀmna 0". Och dÄ WithNBigCores precis satte den till 1MHz (som för övrigt angavs i U-Boot-konfigurationen). Men jag Àr ju fan noga och pedantisk: dÀr vet jag inte, hÀr 25MHz! I slutÀndan fungerar ingenting. Jag tog bort mina "förbÀttringar" och...
Tryck pÄ valfri tangent för att stoppa autoboot: 0
MMC_SPI: 0 vid 0:1 hz 20000000 lÀge 0
## OkÀnd partionstabellstyp 0
libfdt fdt_path_offset() returnerade FDT_ERR_NOTFOUND
** Ingen partitionstabell - mmc 0 **
## Info: indata storlek = 34 = 0x22
Kör uEnv.txt boot2...
## Fel: "boot2" Àr inte definierad
HiFive-Unleashed #Man kan till och med skriva in kommandon! Till exempel, efter lite pillande kan man Ă€ntligen gissa sig till att skriva mmc_spi 1 10000000 0; mmc part, genom att minska SPI-frekvensen frĂ„n 20 MHz till 10 MHz. Varför? Tja, i konfigurationen var den maximala frekvensen angiven som 20 MHz, och den Ă€r fortfarande den samma dĂ€r. Men sĂ„vitt jag förstĂ„r fungerar grĂ€nssnitten, Ă„tminstone hĂ€r, sĂ„ hĂ€r: koden delar frekvensen av hĂ„rdvarumodulen (hos mig Ă€r det alltid 25 MHz) med den mĂ„linriktade, och sĂ€tter det resulterande vĂ€rdet som dividerare i den aktuella kontrollregistret. Problemet Ă€r att om för 115200 Hz UART skulle vara ungefĂ€r det som behövs, sĂ„ om man exakt delar 25000000 med 20000000 fĂ„r man 1, dvs. det kommer att fungera vid 25 MHz. Kanske Ă€r det okej, men om det finns begrĂ€nsningar sĂ€tts, mĂ„ste det vara nödvĂ€ndigt för nĂ„gon (men det Ă€r inte sĂ€kert)... I allmĂ€nhet Ă€r det lĂ€ttare att sĂ€tta dit det och gĂ„ vidare â lĂ„ngt och tyvĂ€rr för lĂ€nge. 25 MHz Ă€r ingen Core i9 för dig.
KonsolutgÄng
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 0x82000000Okej, vi har nÄtt en ny nivÄ, men det hÀnger fortfarande. Och ibland spottar det ut undantag. Man kan se mcause om man fÄngar koden vid den angivna adressen $pc och efter si hamna pÄ trap_entry. Handlaren i U-Boot kan bara skriva ut för mcause = 0..4, sÄ var beredd pÄ att fastna i en felaktig inlÀsning. HÀr gick jag in i konfigurationen, började kolla vad jag hade Àndrat, och kom ihÄg: dÀr i conf/rvboot-fit.txt stÄr det:
fitfile=image.fit
# nedan mĂ„ste matcha vad som finns i FIT (ugha)LĂ„t oss göra alla filer överensstĂ€mmande, vi ersĂ€tter kommandoraden för kĂ€rnan ungefĂ€r sĂ„ hĂ€r, eftersom det finns misstankar om att SIF0 â Ă€r en utmatning nĂ„gonstans via PCIe:
-bootargs=console=ttySIF0,921600 debug
+bootargs=console=ttyS0,125200 debugOch dessutom byter vi hash-algoritmen frÄn SHA-256 till MD5: jag behöver ingen kryptostyrka (speciellt under felsökning), det sÀgs ta fruktansvÀrt lÄng tid, och för att fÄnga upp integritetsfel under inlÀsning Àr MD5 mer Àn tillrÀckligt. SÄ vad blev resultatet? Vi kunde passera det föregÄende steget betydligt snabbare (pÄ grund av den enklare hashningen), och nÀsta steg öppnades:
...
Verifierar hashintegritet ... md5+ OK
Laddar lastfiler frÄn 0x90a5a758 till 0x82000000
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
chosen {
linux,initrd-end = ;
linux,initrd-start = ;
riscv,kernel-end = ;
riscv,kernel-start = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
};
libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND
chosen {
linux,initrd-end = ;
linux,initrd-start = ;
riscv,kernel-end = ;
riscv,kernel-start = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
};
Laddar kÀrnbild ... OK
Startar kÀrnan om
3Men klockorna tickar inte...
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000Ups, det verkar som att justeringen av klockan var ett placebo, Àven om det dÄ verkade hjÀlpa. Nej, vi mÄste sjÀlvklart fixa det, men lÄt oss först vrida visarna manuellt och se vad som hÀnder:
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=1000000
(gdb) c
FortsÀtter.
^C
Programmet fick signal SIGINT, avbruten.
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=2000000
(gdb) c
FortsÀtter.
^C
Programmet fick signal SIGINT, avbruten.
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=3000000
(gdb) c
FortsÀtter.Under tiden...
Laddar kÀrnbild ... OK
Startar kÀrnan om
3
2
1
0
## Startar applikation vid 0x80000000 ...Nej dĂ„, jag gĂ„r för att automatisera klockan â annars kanske den försöker kalibrera timern!
Och adressen för den aktuella instruktionen pekar under tiden nÄgonstans pÄ
0000000080001c20 :
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
80001c2e: e406 sd ra,8(sp)
80001c30: f7fff0ef jal ra,80001bae
80001c34: 8522 mv a0,s0
80001c36: 267000ef jal ra,8000269c
80001c3a: 00010797 auipc a5,0x10
80001c3e: 41e78793 addi a5,a5,1054 # 80012058
80001c42: 639c ld a5,0(a5)
80001c44: c399 beqz a5,80001c4a
80001c46: 72c000ef jal ra,80002372
80001c4a: 45a1 li a1,8
80001c4c: 4501 li a0,0
80001c4e: dc7ff0ef jal ra,80001a14
80001c52: 10500073 wfi
80001c56: bff5 j 80001c52inuti den laddade Berkeley Boot Loader. Personligen stör jag mig pĂ„ omnĂ€mnandet htif â hostgrĂ€nssnittet som anvĂ€nds för tethered start av kĂ€rnan (det vill sĂ€ga i samarbete med vĂ€rd-ARM), jag hade tĂ€nkt mig en fristĂ„ende lösning. Men om man hittar denna funktion i kĂ€llkoden ser man att inte allt Ă€r sĂ„ illa:
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"); }
}
}Uppdrag: starta klockan
Sökning av register i CLINT leder oss till
val io = IO(new Bundle {
val rtcTick = Bool(INPUT)
})
val time = RegInit(UInt(0, width = timeWidth))
when (io.rtcTick) { time := time + UInt(1) }som kopplas in i RTC, eller i den mystiska MockAON, som jag frÄn början tÀnkte: 'Vad har vi hÀr? Oklart? Koppla bort!' Eftersom jag fortfarande inte förstÄr vilken klockmagik som pÄgÄr dÀr, kommer jag helt enkelt att omimplementera denna logik i System.scala:
val rtcDivider = RegInit(0.asUInt(16.W)) // för sÀkerhets skull stödjer jag upp till 16 GHz, jag Àr optimist :)
val mhzInt = p(DevKitFPGAFrequencyKey).toInt
// Anta att frekvensen Àr ett helt antal megahertz
rtcDivider := Mux(rtcDivider === (mhzInt - 1).U, 0.U, rtcDivider + 1.U)
outer.clintOpt.foreach { clint =>
clint.module.io.rtcTick := rtcDivider === 0.U
}NÀr jag nÀrmar mig Linux-kÀrnan
HÀr har berÀttelsen redan dragit ut pÄ tiden och blivit lite enformig, sÄ jag kommer att beskriva översiktligt:
BBL antog att det skulle finnas ett FDT vid adressen 0xF0000000, men jag hade ju redan rÀttat till det! NÄvÀl, vi letar vidare... Hittade i HiFive_U-Boot/arch/riscv/lib/boot.c, bytte till 0x81F00000, angiven i U-Boot:s laddningskonfiguration.
Sedan klagade BBL över att det inte fanns nĂ„got minne. Min vĂ€g ledde till funktionen mem_prop, visar att riscv-pk/machine/fdt.c: dĂ€rifrĂ„n fick jag veta att jag behövde mĂ€rka noden fdt ram som device_type = "memory" â kanske behöver jag justera CPU-generatorn senare, men för nu skriver jag bara in för hand â jag har Ă€ndĂ„ flyttat den hĂ€r filen manuellt.
Nu har jag fÄtt ett meddelande (visat i formaterad stil, med radbrytningar):
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.Verkar som att alternativen anges korrekt riscv,kernel-start och riscv,kernel-end i DTB, men nollor parsas. Debugging query_chosen visade att BBL försöker parsa en 32-bitars adress, men stöter pÄ ett par <0x0 0xADDR>, och det första vÀrdet verkar vara de lÀgre bitarna. Jag lade till i sektionen chosen
chosen {
#address-cells = ;
#size-cells = ;
...
}och justerade genereringen av vÀrdena: inte lÀgga till 0x0 som första element.
Dessa 100500 enkla steg gör det lÀtt och enkelt att se hur pingvinen faller:
Dolt innehÄll
Verifierar hash-integritet ... md5+ OK
Laddar lastbar frÄn 0x90a5a758 till 0x82000000
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
valda {
linux,initrd-end = ;
linux,initrd-start = ;
riscv,kernel-end = ;
riscv,kernel-start = ;
#address-cells = ;
#size-cells = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
stdout-path = "uart0:38400n8";
};
libfdt fdt_path_offset() ÄterstÀllde FDT_ERR_NOTFOUND
valda {
linux,initrd-end = ;
linux,initrd-start = ;
riscv,kernel-end = ;
riscv,kernel-start = ;
#address-cells = ;
#size-cells = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
stdout-path = "uart0:38400n8";
};
Laddar kÀrnbild ... OK
Startar kÀrnan i
3
2
1
0
## Startar applikationen vid 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 555555 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: Ignorerar minnesomrÄde 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 Ons Jul 3 21:29:21 MSK 2019
[ 0.000000] bootconsole [early0] aktiverad
[ 0.000000] Initial ramdisk pÄ: 0x(____ptrval____) (16777216 bytes)
[ 0.000000] Zonnintervall:
[ 0.000000] DMA32 [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] Normal [mem 0x00000000c0000000-0x00000bffffffffff]
[ 0.000000] Flyttbart zonstart för varje nod
[ 0.000000] Tidig minnesnodintervall
[ 0.000000] nod 0: [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] Initmem-setup nod 0 [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] För nod 0 total sidor: 261632
[ 0.000000] DMA32 zon: 3577 sidor anvÀnda för memmap
[ 0.000000] DMA32 zon: 0 sidor reserverade
[ 0.000000] DMA32 zon: 261632 sidor, LIFO-batch:63
[ 0.000000] mjukvaru IO TLB: mappad [mem 0xbb1fc000-0xbf1fc000] (64MB)(logotypen visar BBL, och det som Àr med tidsstÀmplar - kÀrnan).
Lyckligtvis vet jag inte hur det Àr överallt, men pÄ RocketChip kan man fÄnga trappor direkt frÄn lÄdan nÀr man ansluter en debugger via JTAG - debuggern stannar exakt i den punkten.
Programmet fick signal SIGTRAP, spÄrnings-/avbrottstrapp.
0xffffffe0000024ca i ?? ()
(gdb) bt
#0 0xffffffe0000024ca i ?? ()
TillbakatrÀd stoppat: föregÄende ram identisk med denna ram (korrupt stack?)
(gdb) fil work/linux/vmlinux
Ett program debuggeras redan.
Ăr du sĂ€ker pĂ„ att du vill Ă€ndra filen? (y eller n) y
LÀser symboler frÄn work/linux/vmlinux... klart.
(gdb) bt
#0 0xffffffe0000024ca i setup_smp () pÄ /hdd/trosinenko/fpga/freedom-u-sdk/linux/arch/riscv/kernel/smpboot.c:75
#1 0x0000000000000000 i ?? ()
TillbakatrÀd stoppat: ramen sparade inte PCfreedom-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); // < DU ĂR HĂR
}Som det sades i den gamla anekdoten, CPU inte hittad, kör programvaru-emulering. Eller inte körande. Förlorad i enstaka kÀrna av processorn.
/* The lucky hart to first increment this variable will boot the other cores */
atomic_t hart_lottery;
unsigned long boot_cpu_hartid;En bra kommentar i linux/arch/riscv/kernel/setup.c â en slags mĂ„lning av ett staket enligt Tom Sawyers metod. Sammanfattningsvis, idag fanns det av nĂ„gon anledning inga vinnare, priset flyttas till nĂ€sta omgĂ„ng...
Jag föreslÄr att vi avslutar den hÀr redan utdragna artikeln.
FortsÀttning följer. I den kommer en kamp med ett lurigt fel som hinner gömma sig om man nÀrmar sig lÄngsamt med singlestep.
Textbaserad screencast av laddningen (extern lÀnk):
KĂ€lla: habr.com
