V oli rakendatud enam-vähem töötav mälukontroller, ausalt öeldes — ümbritsemine IP Core'ist Quartus, mis on üleminek TileLinkile. Täna rubriigis 'Kandime RocketChip'i vähem tuntud Hiina plaadile Cycloniga' näete töötavat konsooli. Protsess venis natuke: ma juba mõtlesin, et nüüd käivitan Linuxi kiiresti ja saadame edasi, aga sellega ei olnud kõik sugugi lihtne. Selles osas vaatame U-Booti, BBL-i ja Linuxi kernel'i esimesi ja ettevaatlikke algatusi. Kuid konsool on olemas — U-Booti konsool, ja üsna arenenud, omades palju sisu, mida te täiskasvanud konsoolilt ootate.
Riistvarasse lisatakse SD-kaart, mis on ühendatud SPI-liidese kaudu, samuti UART. Tarkvaras saab BootROM asendatud xip järgnevaga sdboot ja samuti lisatakse järgmised laadimise etapid (SD-kaardil).
Riistvara täiustamine
Nii et ülesanne: tuleb minna 'suure' tuuma peale ja ühendada UART (Raspberry'lt) ja SD-adapter (kasutatud on mingit Catalexi plaati kuue pinni (GND, VCC, MISO, MOSI, SCK, CS) jaotusega).
Põhimõtteliselt oli kõik üsna lihtne. Aga enne, kui ma seda mõistsin, viskas mind veidi siia-sinna: pärast eelmist korda otsustasin, et pean jälle lihtsalt lisama System midagi taolist HasPeripheryUART (ja vastavalt rakendusse), sama SD-kaardi jaoks — ja kõik on valmis. Siis otsustasin uurida, kuidas see "tõsises" disainis on rakendatud. Nii, mis meil seal tõsist on? Arty, näib, et ei sobi — jääb alles monster unleahshed.DevKitConfigs. Ja äkki avastasin, et seal on igal pool mingid overlay'd, mis lisatakse võtmeparametrite kaudu. Ma aiman, et see on tõenäoliselt väga paindlik ja konfigureeritav, aga ma tahaksin vähemalt midagi, et alustada... Kas teil ei ole midagi sarnast, ainult lihtsamate ja odavamate lahendustega?.. Siin sattusin ma vera.iofpga.FPGAChip Microsemi FPG-ile ja kohe rabasin tsitaatide peale, proovisin teha oma rakenduse sarnaselt, õnneks on siin enam-vähem kogu "emaplaadi kaabeldus" ühes failis.
Selgus, et tõesti on lihtsalt vaja lisada System.scala rea
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
...Klassi keha rida System lisab teavet selle kohta, millisel sagedusel see meie SoC osa töötab, dts-faili. Nii kuidas mina aru saan, on DTS/DTB staatiline analoog plug-and-play tehnoloogiale integreeritud seadmetele: dts- kirjeldus puu kompileeritakse binaarseks dtb-failiks ja edastatakse laadijale tuumale, et see saaks riistvara õigesti seadistada. Huvi pärast, ilma reaga tlclock kõik sünteesitakse kenasti, kuid BootROM-i kompileerida ei õnnestu (meenutan, et nüüd on see juba sdboot) — kompileerimise käigus analüüsib see dts-faili ja loob päise makroga TL_CLK, tänu millele saab ta õigesti seadistada sageduse jagureid välisseadmete jaoks.
Samuti on vajalik veidi "kaablit" kohandada:
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 kaardile
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
}Registeri ahelad on ausalt öeldes lisatud lihtsalt sarnaselt teistele originaalkoodi kohtadele. Tõenäoliselt peavad need kaitsma . Võib-olla on mõnedes plokkides juba oma kaitse olemas, aga alguseks tahaks vähemalt käivitada "kvaliteetsel tasemel". Mind huvitab rohkem küsimus — miks MISO ja MOSI on erinevates dq dq? Ответа я пока так и не нашёл, но, похоже, остальной код рассчитывает именно на такое подключение.
Füüsiliselt määrasin lihtsalt disaini väljundid tühi kontaktidele südamikus ja liikusin pingeselekti nõela 3.3V peale.
SD-adapter
Ülevaade ülalt:

Ülevaade alt:

Programmi osade tõrkeotsing: tööriistad
Alustame olemasolevate tõrkeotsingu tööriistade ja nende piirangute arutamisega.
Minicom
Esiteks vajame viisi, kuidas lugeda, mida käivitaja ja tuum välja trükivad. Selleks on Linuxis (antud juhul RaspberryPi-s) meil vaja programmi Minicom. Üldiselt sobib igasugune programm, mis töötab seeriaportidega.
Pöörake tähelepanu, et seadme porti nimi tuleb käivitamisel märkida kui -D /dev/ttyS0 — pärast valikut -D. Ja peamine info: väljuda saab kasutada Ctrl-A, X. Tõsi, mul oli kord, kui see kombinatsioon ei toiminud — siis saab lihtsalt teise SSH sessiooni kaudu öelda killall -KILL minicom.
On ka veel üks eripära. Konkreetsetel RaspberryPi mudelitel on kaks UART-i, ja mõlemad pordid võivad juba millekski kohandatud olla: üks Bluetoothi jaoks, teine aga toob vaikimisi välja tuumakonsoli. Õnneks seda käitumist saab ümber seadistada .
Mälu kirjutamine
Silumise käigus, hüpoteeside kontrollimiseks tuli mul vahel laadida buutloader (vabandust) otse hostilt operatiivmäesse. Võib-olla saab seda teha otse GDB-st, aga ma otsustasin minna lihtsat teed: kopeerisin Raspberry-le vajaliku faili, suunasin SSH kaudu ka porta 4444 (telnet OpenOCD-st) ja kasutasin käsku load_image. Kui te seda täidate, tundub, et kõik on kinni jäänud, aga tegelikult "see ei maga, see lihtsalt vilgub aeglaselt": see laadib faili, lihtsalt teeb seda kiirusel paar kilobaidi sekundis.
Breakpoint-ide seadistamise eripärad
Tõenäoliselt ei mõtle paljud sellele, kui nad tavapäraseid programme siluvad, kuid peatamise punktid ei ole alati riistvaraliselt määratletud. Mõnikord seisneb peatamise punktide seadmine erilise käsu ajutises kirjutamises soovitud kohta otse masinkoodi. Näiteks käitus minuga standardne käsk b GDB-s. Siit tuleb välja, et
- ei saa panna punkti BootROM-i, kuna ROM
- punkti saab seada koodi, mis on SD-kaardilt RAM-i laaditud, kuid tuleb oodata, kuni see on laaditud. Vastasel juhul ei kirjuta me koodi tükki ümber, vaid laadija kirjutab meie peatamise punkti ümber.
Olen kindel, et on võimalik selgelt paluda kasutada riistvaralisi peatamise punkte, kuid neid on igal juhul piiratud arv.
BootROM-i kiire asendamine
Silumise algfaasis tekib sageli soov BootROM-i parandada ja proovida veel kord. Kuid probleem on järgmine: BootROM on osa disainist, mis laaditakse FPGA-sse, ja selle sünteesimine on paariminutiline töö (ja see pärast peaaegu kohese BootROMi pildi kompileerimist C-st ja Assemblerist…). Õnneks on kõik tegelikult oluliselt kiirem: tegevuste järjestus on selline:
- regenereerida bootrom.mif (ma läksin MIF-le üle HEX-i asemel, sest HEX-iga olid mul pidevalt mingid probleemid, aga MIF on native Altera formaat)
- Quartusis öelda
Processing -> Update Memory Initialization File - punktis Assembler (vasakus veerus Tasks) käskida Start again
Kõik kokku — paar kümme sekundit.
SD-kaardi ettevalmistamine
Siin on kõik suhteliselt lihtne, kuid tuleb varuda kannatust ja umbes 14Gb ruumi kettal:
git clone https://github.com/sifive/freedom-u-sdk
git submodule update --recursive --init
makeSiis tuleb sisestada puhas, täpsemalt öeldes, midagi vajalikku mitte sisaldav SD-kaart ja täita
sudo make DISK=/dev/sdX format-boot-loader… kus sdX — seade, mis on määratud kaardile. KÄSITSED: kaardi andmed kustutatakse, üle kirjutatakse ja nii edasi! Ilmselt ei tasu kogu ehitust teha sudo, sest siis kuuluvad kõik ehitusartefaktid root, ja ehitust tuleb teha sudo pidevalt.
Tulemusena saadakse kaart, mis on GPT-s märgistatud nelja osaga, millest ühel on FAT-ga uEnv.txt ja laaditav pilt FIT-formaadis (see sisaldab mitmeid alampilte, igaühel oma laadimisadresiga), teine osa — puhas, selleks on plaanis formaadida Ext4 Linuxi jaoks. Veel kaks osa — müstilised: ühel elab U-Boot (kui ma õigesti aru saan, on tema nihkeinfo BootROM-is fikseeritud), teisel näib elavat tema keskkonnamuutujad, kuid ma ei kasuta neid veel.
Tase üks, BootROM
Rahvatarkus ütleb: "Kui programmeerimises on trall, siis elektroonikas on ka tulekustutaja kasutamine." Asi ei ole isegi selles, et ma kord peaaegu plaati ära põletanud, arvestades, et "No GND — see on ju madal tase" (ilmnelijk, takisti ei oleks ju üleliigne...) Küsimus on pigem selles, et kui käed ei tule õigest kohast, siis ei lõpeta elektroonika üllatuste toomist: kui ma keerasin pistikut plaadile, ei suutnud ma kontakte korralikult joota — videos näidatakse, kuidas solder laiali voolab üle kogu ühenduse, ainult puutuge jootepüstoliga, minul aga "koputas" see nagu tahtis. No, võib-olla ei sobinud solder jootepüstoli temperatuuriga, võib-olla midagi muud... Lõppkokkuvõttes, nähes, et mul on juba tosin kontakti, viskasin kõik ära ja hakkasin seadistama. Ja siis see algas müstiline: ühendasin UART-ist RX/TX, laen firmware'i — see kirjutab
INIT
CMD0
ERRORNo, kõik on loogiline — SD-kaardi moodulit ma ei ühendanud. Parandame olukorra, laeme tarkvara... Ja vaikus... Mis kõik mööda ei mõelnud, aga lahendus oli lihtne: üks mooduli väljund tuli ühendada VCC-le. Minu juhul toetas moodul 5V toite, seega ühendasin ilma pikalt mõtlemata kaabli, mis moodulist väljus, plaadi vastaskülge. Tulemuseks oli kehvasti joodetud ühendus, mis kallutas ja lihtsalt kaotas UART-i kontakti. facepalm.jpg Kokkuvõttes, "loll pea ei anna jalgadele rahu", aga käänulised käed — ette…
Lõpuks nägin Minicom-is kauaoodatud
INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING /Veelgi enam, laadimise indikaator liigub. Meenub lapsepõlv ja aeglane MinuetOS-i laadimine ketta pealt. Ainult, et kettaseade ei kriuksu.
Probleem on selles, et pärast sõnumit BOOT ei juhtu midagi. Seega on paras aeg ühendada OpenOCD-lt Raspberry-le, sellele GDB hostis ja vaadata, mis toimub.
Esiteks, GDB kaudu ühendamine näitas kohe, et $pc (program counter, kehtiva käsu aadress) kaob 0x0 — tõenäoliselt juhtub see pärast mitmeid vigu. Seetõttu, kohe pärast sõnumi andmist BOOT lisame lõpmatu tsükli. See pidurdab teda mõneks ajaks…
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;
}Sellist kavalat koodi kasutatakse "usaldusväärsuse" tagamiseks: olen kuulnud, et lõpmatu tsükkel on Undefined Behavior, ja siin ei suuda kompilaator seda tõenäoliselt aimata (tuletan meelde, et 0x10000 asub BootROM).

Tundub, et ei ole vaja oodata – karm embedded, mis puutub siin lähtekoodidesse. Kuid autor silus C-koodi… Kreks-feks-peks:
(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.
Ainult et ei tule laadida MIF-faili ega bin'i, vaid originaalversioon ELF-formaadis.
Nüüd on võimalik järgneva katsega arvata adresse, kus täitmine jätkub (see on veel üks põhjus, miks kompilaator ei pidanud arvama, et tsükkel on lõpmatu). Käsk
set variable $pc=0xADDRvõimaldab muuta registri väärtust jooksvalt (antud juhul – praeguse käsu aadressi). Sama meetodiga saab muutujaid muuta, mis on salvestatud mällu (ja mäluga kaardistatud registrid).
Lõppkokkuvõttes jõudsin järeldusele (ei ole kindel, et see on õige), et meil on "sd-kaardi pilt vale süsteemi jaoks", ja siirduma tuleb mitte kõige algusesse laaditud andmete, vaid 0x89800 baidi võrra edasi:
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 .rodataVõib-olla mõjutas seda ka see, et kuna mul polnud käepärast mittevajalikku 4Gb kaarti, võtsin 2Gb kaardi ja katsetasin, muutes Makefile'i DEMO_END=11718750 järgnevaga DEMO_END=3078900 (ärge otsige spetsiifilisest tähendusest – seda ei ole, lihtsalt nüüd sobib pilt kaardile).
Teine tase, U-Boot
Nüüd langeme endiselt, kuid jõuame juba aadressile 0x0000000080089a84. Siinkohal pean tunnistama: tegelikult ei kulge esitus „kõikide peatustega”, vaid kirjutatakse osaliselt juba „hiljem”, seega olen siin juba suutnud lisada õige dtb-faili meie SoC-lt, parandada seadetest HiFive_U-Boot muutuja CONFIG_SYS_TEXT_BASE=0x80089800 (asemel 0x08000000), et laadimisadress vastaks tegelikule. Laadime nüüd järgmise taseme kaardi teise pildi:
(gdb) file ../freedom-u-sdk/work/HiFive_U-Boot/u-boot
(gdb) tui enJa näeme:
│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) │Ja hüpame ridade 308 ja 309 vahel. Ja pole üllatav, et $sp hoiab väärtust 0xfffffffe31cdc0a0. Kahjuks „põgeneb“ see pidevalt, kuna rida 307. Seetõttu proovime panna peatumispunkti trap_entry, seejärel naasta 0x80089800 (U-Booti sisenemiskohta) ja loodame, et see ei vaja enne üleminekut registreid õigesti seadistada... Tundub, et töötab:
(gdb) b trap_entry
Breakpoint 1 at 0x80089a80: fail /hdd/trosinenko/fpga/freedom-u-sdk/HiFive_U-Boot/arch/riscv/cpu/HiFive/start.S, rida 308.
(gdb) set variable $pc=0x80089800
(gdb) c
Jätkub.
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 = 0x81cf950Selle koha pealt on virna näitaja mitte just parim, otse öeldes: see viitab üldse mööda mälust (kui meil pole veel aadresside tõlget, kuid loodame, et on lihtsam variant).
Proovime asendada näitaja 0x881cf950. Lõpuks jõuame järeldusele, et handle_trap kutsub ja kutsub, samas liikudes _exit_trap argumentiga epc=2148315240 (dekaarses vormis):
(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,0Seame katkestuspunkt strnlen, jätkame ja näeme:
(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/interr... 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 PCTundub, _exit_trap üritab esitada teavet toimunud erandite kohta, aga tal ei õnnestu. Nii et ilmselt on meie allikad taas allpool. seadista kataloogid ../freedom-u-sdk/HiFive_U-Boot/ O! Nüüd kuvatakse!
Noh, käivitame uuesti ja näeme virnaprotsessis algse probleemi põhjust, mis tekitas esimese vea (mcause == 5). Kui ma õigesti aru sain, mis seal on kirjutatud leheküljel 37, siis see erand tähendab Selle laadimise juurdepääsurike. Põhjus on ilmselt see, et siin
arch/riscv/cpu/HiFive/start.S:
call_board_init_f:
li t0, -16
li t1, CONFIG_SYS_INIT_SP_ADDR
and sp, t1, t0 /* sundige 16 baidi joondust */
#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 /* hüppa board_init_f() */
$sp on see vale väärtus, ja sees board_init_f_init_reserve tekib tõrge. Tundub, et siin on süüdlane: muutuja, millel on arusaadav nimi CONFIG_SYS_INIT_SP_ADDR. See on määratletud failis HiFive_U-Boot/include/configs/HiFive-U540.h. Mõnel hetkel mõtlesin isegi, et võib-olla ei tasu laadijat protsessori jaoks kohandada — võib-olla on lihtsam protsessorit natuke parandada? Aga siis märkasin, et see näib olevat rohkem artefakt muudetud mälukonfiguratsiooni seadmest, ja võiks proovida teha järgmist:#if 0-seadme kaitset muud konfiguratsiooni mälu, ja võid proovida teha nii:
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 */Mõnes kohas on tokarite kogus järginud kriitilise piiri. Pärast natuke vaeva olen jõudnud vajadusele teha korralik port oma plaadile. Selleks tuleb kopeerida ja kohandada meie konfiguratsiooniga teatav hulk faile.
Noh, ligikaudu, siin on natuke
trosinenko@trosinenko-pc:/hdd/trosinenko/fpga/freedom-u-sdk/HiFive_U-Boot$ git show --name-status
commit 39cd67d59c16ac87b46b51ac1fb58f16f1eb1048 (HEAD -> zeowaa-1gb)
Author: Anatoly Trosinenko <anatoly.trosinenko@gmail.com>
Date: Tue Jul 2 17:13:16 2019 +0300
Esialgne tugi Zeowaa A-E115FB plaadile
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.hDetailid on saadaval .
Kuna selgus, et sellel SiFive'i plaadil on mõnede seadmete registrid teistel aadressidel. Samuti selgus, et U-Boot konfigureeritakse juba tuttava Linuxi tuuma Kconfig mehhanismi abil — näiteks saate sisestada make menuconfig, ja teie ette ilmub mugav tekstiliides koos parameetrite kirjelduste näitamisega ? ja ja. Üldiselt, kombineerides kahe plaadi kirjeldusi kolmanda jaoks, jättes välja kõik uhked PLL ümberseaded (ilmselt on see seotud host-arvuti juhtimisega PCIe kaudu, kuid see ei pruugi olla tõsi), sain ma mingi püsivara, mis õigete Marsi ilmaolude korral edastas mulle UARTi kaudu sõnumi, millise kommituvi hashist see on kokku pandud, ja kui palju mul on DRAMi (aga selle info panin ma ise headeris kirja).
Kahjuks lõpetas plaat pärast seda tavaliselt protsessori JTAG kaudu vastamise, ja SD-kaardilt bootimine — see on kahjuks minu konfiguratsioonis aeglane protsess. Teisest küljest, mõnikord edastas BootROM sõnumi, et ERROR, ei õnnestunud bootida, ja kohe tuli U-Boot. Siin sain ma aru: ilmselt pärast bitstreami taaskäivitamist PLISi, mälu ei kustutata, ei jõua "dekonfigureerida" jne. Ühesõnaga, võin lihtsalt sõnumi ilmumisel LOADING / ühendada debugeerijaga ja käskida set variable $pc=0x80089800, mööda minnes sellest pikast laadimisest (loomulikult oletame, et eelmisel korral see katki ei läinud liiga hilja, ja ei saanud midagi originaalkoodile peale laadida).
Muide, kas tõesti on normaalne, et protsessor hangub täielikult ja JTAG-debugger ei saa ühendust, andes selliseid teateid
Viga: ei saa peatada hart 0
Viga: dmcontrol=0x80000001
Viga: dmstatus=0x00030c82Oodake! Olen juba seda näinud! Midagi sellist juhtub TileLink'i deadlock'i puhul, ja ma ei usalda üldse mälu kontrolleri autorit — ta ise kirjutas... Ühtäkki, peale esimest edukat protsessori uuesti kokkupanekut pärast kontrolleri redigeerimist, nägin ma:
INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LAADIMINE
KÄIVITUS
U-Boot 2018.09-g39cd67d-dirty (03. juuli 2019 - 13:50:33 +0300)
DRAM: 1 GiB
MMC:
ENNE KESKKONNA LAADIMIST
ENNE FDTCONTROLADDR
ENNE LOADADDR
Sisse: serial
Välja: serial
Viga: serial
Pese mõni klahv, et peatada automaatne käivitamine: 3Selle kummalise rea ees Sisse: serial Ärge pange tähele — see olin mina, kes üritas külmunud protsessoriga mõista, kas see töötab keskkonnaga. Mis tähendab "Juba kümme minutit on see niimoodi ripakil"? Kas see suutis vähemalt paikneda ja liikuda laadimismenüüsse! Väike kõrvalepõige: kuigi U-Boot laaditakse esimestest 2^24 baitist SD-kaardilt, laadib see ennast käivitudes kuhugi kaugemale aadressile, mis on kas konfigureerimise pealkirjas kirjas või lihtsalt operatiivmälu kõrgematel aadressidel, viib läbi ELF-sümbolite relokatsiooni ja edastab juhtimise sinna. Noh, tundub, et see tase on ületatud ja boonuseks saadi protsessor, mis pärast seda ei külmu täielikult.
Nii et, miks ajastik ei tööta? Tundub, et kellad ei käi kuidagi…
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000Aga mis siis, kui sõrmedega käsitsi keerata?
(gdb) set variable *0x0200bff8=310000000
(gdb) cSiis:
Püüdke mis tahes klahvi, et autolaadimine peatada: 0
MMC_SPI: 0 aadressil 0:1 hz 20000000 režiim 0Tulemus: kellad ei käi. Tõenäoliselt on see sama põhjus, miks klaviatuuri sisend ei tööta:
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:
/* ANSI escape jada jada 'e' esimene karakter */
if (c == 'e') {
*esc = 1;
*key = KEY_NONE;
}
break;
case 1:
/* ANSI '[' teise karakter */
if (c == '[') {
...Probleem oli selles, et ma läksin natuke liiale: lisasin protsessori konfiguratsiooni võtme:
case DTSTimebase => BigInt(0)…pidades silmas, et kommentaaris oli öeldud "kui te ei tea - jätke 0". Ja tegelikult WithNBigCores seadis selle 1MHz (nagu oli kirjas ka U-Booti konfiguratsioonis). Aga ma olen ju tähelepanelik ja pedantne: seal ma ei tea, siin 25MHz! Lõpuks ei tööta midagi. Eemaldasin oma "parandused" ja...
Vajutage mis tahes klahvi, et katkestada automaatne käivitamine: 0
MMC_SPI: 0 aadressil 0:1 hz 20000000 režiim 0
## Tunmata partitsioonitabeli tüüp 0
libfdt fdt_path_offset() tagastas FDT_ERR_NOTFOUND
** Partitsioonitabel puudub - mmc 0 **
## Teave: sisendi andmete suurus = 34 = 0x22
Käivitab uEnv.txt boot2...
## Viga: "boot2" ei ole defineeritud
HiFive-Unleashed #Sa saad isegi käske sisestada! Näiteks, natuke nuputades, saab lõpuks aru, et tuleb sisestada mmc_spi 1 10000000 0; mmc part, vähendades SPI sagedust 20MHz-lt 10MHz-le. Miks? No, konfiguratsioonis oli kirjas maksimaalne sagedus 20MHz, see on seal praegu ka kirjas. Kuid, nii palju kui ma aru sain, töötavad liidesed vähemalt siin nii: kood jagab riistvarabloki sageduse (mul on see igal pool 25MHz) sihtsagedusega ja seab saadud väärtuse jagajaks vastavasse juhtimisregistrisse. Probleem on selles, et kui 115200Hz UART-i jaoks sobib umbes see, mida on vaja, siis kui jagada täpselt 25000000 20000000-ga, saame 1, st see töötab 25MHz-l. Võib-olla on see normaalne, kuid kui piiranguid seavad, siis on see kellelegi vajalik (aga see ei pruugi nii olla)... Ühesõnaga, lihtsam on välja panna ja edasi minna — kaugele ja, kahjuks, pikaks ajaks. 25MHz — see ei ole Core i9.
Konsoli väljund
HiFive-Unleashed # env edit mmcsetup
redigeeri: mmc_spi 1 10000000 0; mmc part
HiFive-Unleashed # boot
MMC_SPI: 1 aadressil 0:1 hz 10000000 režiim 0
Partitsioonikaart MMC seadme 0 jaoks -- Partitsiooni tüüp: EFI
Osad Algus LBA Lõpp LBA Nimi
Atribuudid
Tüübi GUID
Partitsiooni GUID
1 0x00000800 0x0000ffde "Vfat Boot"
atribuudid: 0x0000000000000000
tüüp: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
tüüp: andmed
guid: 76bd71fd-1694-4ff3-8197-bfa81699c2fb
2 0x00040800 0x002efaf4 "juur"
atribuudid: 0x0000000000000000
tüüp: 0fc63daf-8483-4772-8e79-3d69d8477de4
tüüp: linux
guid: 9f3adcc5-440c-4772-b7b7-283124f38bf3
3 0x0000044c 0x000007e4 "uboot"
atribuudid: 0x0000000000000000
tüüp: 5b193300-fc78-40cd-8002-e86c45580b47
guid: bb349257-0694-4e0f-9932-c801b4d76fa3
4 0x00000400 0x0000044b "uboot-env"
atribuudid: 0x0000000000000000
tüüp: a09354ac-cd63-11e8-9aff-70b3d592f0fa
guid: 4db442d0-2109-435f-b858-be69629e7dbf
libfdt fdt_path_offset() tagastas FDT_ERR_NOTFOUND
2376 baiti loeti 0 ms
Käivitamine uEnv.txt boot2...
15332118 baiti loeti 0 ms
## Laadimine kernel FIT pildist aadressil 90000000 ...
Kasutades 'config-1' konfiguratsiooni
Proovides 'bbl' kernel alampilti
Kirjeldus: BBL/SBI/riscv-pk
Tüüp: Kernel Image
Kompressioon: avatud
Andmete algus: 0x900000d4
Andmete suurus: 74266 baitsi = 72.5 KiB
Arhitektuur: RISC-V
OS: Linux
Laadimise aadress: 0x80000000
Sisenemispunkt: 0x80000000
Hash algoritm: sha256
Hash väärtus: 28972571467c4ad0cf08a81d9cf92b9dffc5a7cb2e0cd12fdbb3216cf1f19cbd
Hashi sisemise vigastuse kontrollimine ... sha256+ OK
## Laadimine fdt FIT pildist aadressil 90000000 ...
Kasutades 'config-1' konfiguratsiooni
Proovides 'fdt' fdt alampilti
Kirjeldus: saadaval pole
Tüüp: Flat Device Tree
Kompressioon: avatud
Andmete algus: 0x90e9d31c
Andmete suurus: 6911 baitsi = 6.7 KiB
Arhitektuur: RISC-V
Laadimise aadress: 0x81f00000
Hash algoritm: sha256
Hash väärtus: 10b0244a5a9205357772ea1c4e135a4f882409262176d8c7191238cff65bb3a8
Hashi sisemise vigastuse kontrollimine ... sha256+ OK
Laadimine fdt aadressilt 0x90e9d31c aadressile 0x81f00000
Käivitamine fdt blobiga aadressil 0x81f00000
## Laadimine laaditavaid elemente FIT pildist aadressil 90000000 ...
Proovides 'kernel' laaditavad alampilt
Kirjeldus: Linux kernel
Tüüp: Kernel Image
Kompressioon: avatud
Andmete algus: 0x900123e8
Andmete suurus: 10781356 baitsi = 10.3 MiB
Arhitektuur: RISC-V
OS: Linux
Laadimise aadress: 0x80200000
Sisenemispunkt: vabalt
Hash algoritm: sha256
Hash väärtus: 72a9847164f4efb2ac9bae736f86efe7e3772ab1f01ae275e427e2a5389c84f0
Hashi sisemise vigastuse kontrollimine ... sha256+ OK
Laadimine laaditavaid elemente aadressilt 0x900123e8 aadressile 0x80200000
## Laadimine laaditavaid elemente FIT pildist aadressil 90000000 ...
Proovides 'ramdisk' laaditavad alampilt
Kirjeldus: buildroot initramfs
Tüüp: RAMDisk Image
Kompressioon: gzip kompressioon
Andmete algus: 0x90a5a780
Andmete suurus: 4467411 baitsi = 4.3 MiB
Arhitektuur: RISC-V
OS: Linux
Laadimise aadress: 0x82000000
Sisenemispunkt: vabalt
Hash algoritm: sha256
Hash väärtus: 883dfd33ca047e3ac10d5667ffdef7b8005cac58b95055c2c2beda44bec49bd0
Hashi sisemise vigastuse kontrollimine ... sha256+ OK
Laadimine laaditavaid elemente aadressilt 0x90a5a780 aadressile 0x82000000Selge, oleme uuele tasemele jõudnud, kuid see jääb endiselt kinni. Ja mõnikord viskab veel erandeid. Näha mcause'i saab, püüdes koodi antud aadressilt. $pc ja pärast si jõuda trap_entry. Isegi U-Booti töötleja suudab kuvada ainult mcause = 0..4, seega valmistuge vale laadimise puhul ringi jääma. Siit vaatasin konfi, et näha, mida ma muudsin, ja meenutasin: seal on ju conf/rvboot-fit.txt kirjutatud:
fitfile=image.fit
# allpool peab vastama sellele, mis on FITis (ugha)Mis siis, viime kõik failid vastavusse, asendame kernelikomandorida ligikaudu nii, kuna on kahtlusi, et SIF0 — see on väljund kuskile PCIe kaudu:
-bootargs=console=ttySIF0,921600 debug
+bootargs=console=ttyS0,125200 debugJa üleüldiselt muudame räsi algoritmi SHA-256-lt MD5-ks: krüpto tugevust mul ei ole vaja (ikka, silumise ajal), loetakse see väga aeglaseks, ning vigade püüdmiseks laadimise ajal piisab ka MD5-st. Mis siis lõpuks? Me hakkasime eelmisest tasemest selgelt kiiremini läbi minema (lihtsama räsi tõttu) ja järgnev avanes:
... Verifitseerimise räsiväärtuse terviklikkust ... md5+ OK
Laadimine laaditavatest aadressidest 0x90a5a758 kuni 0x82000000
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
valitud {
linux,initrd-lõpp = ;
linux,initrd-alg = ;
riscv,kernele-lõpp = ;
riscv,kernele-alg = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
};
libfdt fdt_path_offset() tagastas FDT_ERR_NOTFOUND
valitud {
linux,initrd-lõpp = ;
linux,initrd-alg = ;
riscv,kernele-lõpp = ;
riscv,kernele-alg = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
};
Laadimine Kernel Image ... OK
Käivitamine kernelis
3Ainult kellad ei tikti...
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000Ups, tundub, et kellade parandus osutus platseeboks, kuigi toona näis, et see aitas. Ei, loomulikult tuleb parandada, aga alustame kätega kellade keeramisest ja vaatame, mis juhtub:
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=1000000
(gdb) c
Jätkamine.
^C
Programm sai signaali SIGINT, katkestamine.
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=2000000
(gdb) c
Jätkamine.
^C
Programm sai signaali SIGINT, katkestamine.
0x00000000bff6dbb0 in ?? ()
(gdb) set variable *0x0200bff8=3000000
(gdb) c
Jätkamine.Vahepeal...
Laadimine Kernel Image ... OK
Käivitamine kernelis
3
2
1
0
## Rakenduse alustamine aadressil 0x80000000 ...Ei, ma lähen automatiseerima kellade käimist — kui äkki ta mõtleb, et võiks kalibreerimiseks taimerit kasutada!
Juhise aadress suunab samal ajal kuhugi
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 80001c52laaditud Berkeley Boot Loaderi sees. Mind häirib siinkohal mainimine htif — host interface, mida kasutatakse südamiku tethered-käivitamiseks (ehk koostöös host ARM-iga), ma arvasin standalone. Siiski, kui leida see funktsioon lähtekoodist, siis on näha, et asi ei ole sugugi nii halb:
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"); }
}
}Ülesanne: käivita kellad
Registreerimise otsimine CLINT'is viib meid
val io = IO(new Bundle {
val rtcTick = Bool(INPUT)
})
val time = RegInit(UInt(0, width = timeWidth))
when (io.rtcTick) { time := time + UInt(1) }Mis on ühendatud RTC-sse, või müstilisse MockAON-i, mille kohta ma alguses mõtlesin: „Nii, mis see meil siin on? Ebaselge? Lülitame välja!” Kuna mulle ei ole siiani selge, mis see takti maagia seal toimub, seega lihtsalt realiseerin selle loogika uuesti System.scala:
val rtcDivider = RegInit(0.asUInt(16.W)) \/\/ igaks juhuks toetame kuni 16GHz, olen optimist :)
val mhzInt = p(DevKitFPGAFrequencyKey).toInt
\/\/ Eeldame, et sagedus on täisarv megahertsides
rtcDivider := Mux(rtcDivider === (mhzInt - 1).U, 0.U, rtcDivider + 1.U)
outer.clintOpt.foreach { clint =>
clint.module.io.rtcTick := rtcDivider === 0.U
}Liikudes Linux kernel'i poole
Siin on narratiiv juba veninud ja natuke ühtlane, seega kirjeldan ülevalt:
BBL eeldas FDT olemasolu aadressil 0xF0000000, aga ma olen juba seda parandanud! Mis siis on, otsime veel… Leidsin HiFive_U-Boot/arch/riscv/lib/boot.c, asendasin 0x81F00000, mis on näidatud U-Booti laadimis konfiguratsioonis.
Siis kaebas BBL, et pole mälu. Minu tee viis funktsiooni juurde mem_prop, mis on riscv-pk/machine/fdt.c: sealt sain teada, et tuleb märkida fdt ram sõlm nagu device_type = "memory" — siis võib-olla on vaja muuta protsessori generaatorit, aga praegu kirjutan lihtsalt käsitsi — niikuinii tõin ma selle faili käsitsi üle.
Nüüd sain sõnumi (esitatud vormindatud kujul, koos reavahetustega):
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.Tundub, et valikud on õigesti määratud riscv,kernel-start ja riscv,kernel-end DTB-s, aga nullid parsetakse. Läbivaatamine query_chosen näitas, et BBL proovib parseta 32-bitist aadressi, kui sellele satub paar <0x0 0xADDR>, ja esimene väärtus näib olevat madalamad bitid. Kirjutasin sektsiooni chosen
chosen {
#address-cells = ;
#size-cells = ;
...
}ja parandasasin väärtuste genereerimist: mitte kirjutada 0x0 esimese elemendina.
Need 100500 lihtsat sammu võimaldavad hõlpsasti ja kiiresti näha, kuidas pingviin kukub:
Peidetud tekst
Kontrollitakse räsisumma terviklikkust ... md5+ OK
Laadimine laaditavaid andmeid 0x90a5a758-st 0x82000000-ni
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
valitud {
linux, initrd-lõpp = ;
linux, initrd-alguses = ;
riscv, kernel-lõpp = ;
riscv, kernel-alguses = ;
#address-cells = ;
#size-cells = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
stdout-path = "uart0:38400n8";
};
libfdt fdt_path_offset() naasis FDT_ERR_NOTFOUND
valitud {
linux, initrd-lõpp = ;
linux, initrd-alguses = ;
riscv, kernel-lõpp = ;
riscv, kernel-alguses = ;
#address-cells = ;
#size-cells = ;
bootargs = "debug console=tty0 console=ttyS0,125200 root=/dev/mmcblk0p2 rootwait";
stdout-path = "uart0:38400n8";
};
Laadimine Kernel Image ... OK
Käivitamine kernelis
3
2
1
0
## Rakenduse käivitamine aadressil 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 versioon 4.19.0-sifive-1+ (trosinenko@trosinenko-pc) (gcc versioon 8.3.0 (Buildroot 2019.02-07449-g4eddd28f99)) #1 SMP Kolm Juuli 3 21:29:21 MSK 2019
[ 0.000000] bootconsole [early0] lubatud
[ 0.000000] Algne ramdisk aadress: 0x(____ptrval____) (16777216 baiti)
[ 0.000000] Zone'i vahemikud:
[ 0.000000] DMA32 [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] Normaalne [mem 0x00000000c0000000-0x00000bffffffffff]
[ 0.000000] Liikuv tsoon igas sõlmes
[ 0.000000] Varajased mälu sõlme vahemikud
[ 0.000000] sõlm 0: [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] Initmem seadistamise sõlm 0 [mem 0x0000000080200000-0x00000000bfffffff]
[ 0.000000] Sõlmes 0 kokku lehtede arv: 261632
[ 0.000000] DMA32 tsoon: 3577 lehte kasutatud memmap'i jaoks
[ 0.000000] DMA32 tsoon: 0 lehte reserveeritud
[ 0.000000] DMA32 tsoon: 261632 lehte, LIFO partii:63
[ 0.000000] tarkvara IO TLB: kaardistatud [mem 0xbb1fc000-0xbf1fc000] (64MB)(BBL-i embleem ja aegade žetoonid - südamik).
Õnneks ei tea ma, kuidas igal pool, kuid RocketChipil JTAG-debuggeri ühendamisel saab kohe kinni püüda trap'e — debugger peatub just seal.
Programmi signaal SIGTRAP, jälgimise/löögipunkti trap.
0xffffffe0000024ca in ?? ()
(gdb) bt
#0 0xffffffe0000024ca in ?? ()
Tagasivaade peatatud: eelmine raam on sama, mis see raam (rikutud virn?)
(gdb) file work/linux/vmlinux
Programm on juba de- debugitud.
Kas olete kindel, et soovite faili muuta? (y või n) y
Sümbolite lugemine failist work/linux/vmlinux... tehtud.
(gdb) bt
#0 0xffffffe0000024ca in setup_smp () at /hdd/trosinenko/fpga/freedom-u-sdk/linux/arch/riscv/kernel/smpboot.c:75
#1 0x0000000000000000 in ?? ()
Tagasivaade peatatud: raam ei salvestanud PC-d.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); // < OLETE SIIN
}Nagu vanas anekdoodis öeldud, CPU-d ei leitud, tarkvaralise emulatsiooni käivitamine.. Või mitte käivitamine. Ekslesime protsessori ühes tuumas.
/* The lucky hart to first increment this variable will boot the other cores */
atomic_t hart_lottery;
unsigned long boot_cpu_hartid;Hea kommentaar failis linux/arch/riscv/kernel/setup.c — nagu Tom Sawyer'i meetodi järgi värvimine. Üldiselt, täna ei leidunud kuidagi võitjaid, auhind lükatakse järgmisele loosimisele...
Sellega lõpetan juba niigi veniva artikli.
Jätkub. Järgmisena on lahing kavalate vigadega, mis suudab varjuda, kui sellele aeglaselt läheneda singlestep-iga.
Tekstiline ekraanikaader laadimisest (väline link):
Allikas: habr.com
