Qeybta 3: Ku dhawaad ​​rarka Linux kaarka SD ilaa RocketChip

Qeybta 3: Ku dhawaad ​​rarka Linux kaarka SD ilaa RocketChip В qayb hore wax ka badan ama ka yar oo kontorool xusuusta shaqaynaysa ayaa la hirgeliyay, ama halkii, duubab ka sarreeya IP Core oo ka yimid Quartus, kaas oo adabtarada u ah TileLink. Maanta, qaybta "Waxaan u wareejineynaa RocketChip boodh yar oo Shiinees ah oo la yaqaan oo leh Cyclone" waxaad ku arki doontaa console-ka shaqeeya. Nidaamku wax yar ayuu qaatay: Waxaan mar hore ka fekerayay inaan si dhakhso ah u bilaabi doono Linux oo aan u dhaqaaqo, laakiin taasi ma ahayn kiiska. Qaybtan, waxaan soo jeedinayaa in la eego habka loo bilaabayo U-Boot, BBL, iyo isku dayga xishoodka leh ee kernel Linux si loo bilaabo. Laakiin waxaa jira console - U-Boot, oo aad u horumarsan, oo leh wax badan oo aad ka filan karto console-ka buuxa.

Qalabku waxa ku jiri doona kaarka SD oo ku xidhan interneedka SPI, iyo sidoo kale UART. Qaybta software-ka, BootROM waa lagu bedeli doonaa xip on sdboot iyo, dhab ahaantii, heerarka soo socda ee loading ayaa lagu daray (korka SD ah).

Dhamaystirka qalabka

Marka, hawshu: waxaad u baahan tahay inaad u beddesho xudunta "weyn" oo aad ku xirto UART (laga bilaabo Raspberry) iyo adabtarada SD (waxaan ka isticmaalnay kaarka Catalex oo leh lix biin: GND, VCC, MISO, MOSI, SCK, CS) .

Mabda 'ahaan, wax walba waxay ahaayeen wax fudud. Laakiin ka hor intaanan taas ogaan, wax yar ayaa layga tuuray dhinac ilaa dhinac: ka dib markii hore, waxaan go'aansaday in mar kale aan u baahanahay inaan isku daro. System wax la mid ah HasPeripheryUART (iyo hirgelinta si waafaqsan), isku mid ah kaarka SD - wax walbana waxay noqon doonaan diyaar. Kadibna waxaan go'aansaday inaan arko sida loo hirgeliyay naqshad "khatar ah". Haddaba, maxaa ka daran arrintan? Arty, sida muuqata, kuma habboona - wuxuushku waa hadhay unleahshed.DevKitConfigs. Waxayna si lama filaan ah u soo baxday in meel walba ay jiraan qaar dul-saaran, kuwaas oo lagu daray cabirrada furayaasha. Waxaan qiyaasayaa in tani ay u badan tahay mid aad u dabacsan oo la habeyn karo, laakiin waxaan jeclaan lahaa in aan ugu yaraan wax ka qabto ... Miyaadan haysan wax la mid ah, kaliya ka fudud oo ka xanaaq badan? Waa markii aan la kulmay vera.iofpga.FPGAChip loogu talagalay Microsemi FPGAs oo isla markiiba u kala soocay xigashooyinka waxaanan isku dayay inaan sameeyo hirgelinta aniga oo isbarbar dhigaya, nasiib wanaag waxaa jira wax ka badan ama ka yar dhammaan "qaabaynta Motherboard-ka" ee hal fayl.

Waxaa soo baxday inaad runtii u baahan tahay inaad ku darto System.scala khadadka

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
...

Line in jirka fasalka System wuxuu ku darayaa macluumaadka ku saabsan inta jeer ee ay qaybtan SoC-ga ah ku shaqeyso faylka dts Ilaa hadda inta aan fahmayo, DTS/DTB waa analoog joogto ah oo ah tignoolajiyada plug-iyo-ciyaaraha ee aaladaha ku dhexjira: geedka sharaxaadda dts waxaa lagu soo ururiyey faylka dtb ee binary waxaana lagu wareejiyaa bootloader-ka kernel si uu si sax ah u habeeyo qalab. Waxa xiiso leh, iyada oo aan khadka la lahayn tlclock Wax walba si fiican ayey u wada shaqeeyaan, laakiin ururinta BootROM (aan ku xasuusiyo, hadda tani waxay ahaan doontaa mar hore sdboot) ma shaqeyn doono - inta lagu guda jiro habka isku dubaridka waxay kala saartaa faylka dts waxayna abuurtaa madax leh makro TL_CLK, taas oo uu ku mahadsan yahay inuu awood u yeelan doono inuu si sax ah u habeeyo qaybiyeyaasha soo noqnoqda ee isdhexgalka dibadda.

Waxaad sidoo kale u baahan doontaa inaad wax yar saxdo "xadhkaha":

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
}

Silsilada diiwaanka, si daacad ah, waxaa si fudud loogu daray meelo kale oo koodka asalka ah. Inta badan, waa inay ka difaacaan metastayn. Malaha gudaha qaar blocks ayaa horey u lahaa difaac u gaar ah, laakiin marka hore waxaan rabaa inaan bilaabo ugu yaraan "heerka tayada sare leh." Su'aasha iga sii xiiso badan ayaa ah sababta MISO iyo MOSI ay u kala laadlaadsan yihiin dq? Jawaabta weli ma helin, laakiin waxay u muuqataa in inta kale ee koodka ay ku tiirsan yihiin xidhiidhka noocaas ah.

Jir ahaan, waxaan si fudud u qoondeeyay biinanka naqshadeynta xiriirada bilaashka ah ee xannibaadda waxaanan u dhaqaaqay jumper xulashada korantada 3.3V.

adabtarada SD

Kor ka eeg:

Qeybta 3: Ku dhawaad ​​rarka Linux kaarka SD ilaa RocketChip

Aragtida hoose:

Qeybta 3: Ku dhawaad ​​rarka Linux kaarka SD ilaa RocketChip

Qalabaynta Software: Qalabka

Marka hore, aan ka hadalno qalabka wax-ka-hortagga ee jira iyo xaddidaaddooda.

Minicom

Marka hore, waxaan u baahan doonaa inaan si uun u akhrino waxa soo saarida bootloader iyo kernel. Si tan loo sameeyo Linux (kiiskan, kan RaspberryPi), waxaan u baahanahay barnaamijka Minicom. Guud ahaan, barnaamij kasta oo la shaqeeya deked taxane ah ayaa qaban doona.

Fadlan ogow marka la bilaabayo, magaca aaladda dekeddu waa in lagu qeexaa sida -D /dev/ttyS0 - ka dib doorashada -D. Hagaag, macluumaadka ugu muhiimsan: si aad uga baxdo, isticmaal Ctrl-A, X. Dhab ahaantii waxaan lahaa kiis markii isku-dhafkan uusan shaqeynin - markaa waxaad si fudud uga sheegi kartaa fadhiga SSH ee deriska ah killall -KILL minicom.

Waxaa jira hal sifo oo kale. Gaar ahaan RaspberryPi waxaa jira laba UARTs, labada dekedoodna mar horeba waa la waafajin karaa shay: mid Bluetooth ah, kan kalena wuxuu soo saaraa kumbuyuutarka kernel-ka. Nasiib wanaag, dhaqankan waa la dhaafi karaa sida ku cad buug-gacmeedkan.

Xusuusta dib u qor

Marka qaladka laga saarayo, si aan u tijaabiyo mala-awaal, mararka qaarkood waa inaan sameeyo bootloader (ka xumahay) si toos ah RAM uga soo galo martida loo yahay. Waxaa laga yaabaa in tan si toos ah looga sameeyo GDB, laakiin ugu dambeyntii waxaan raacay waddo fudud: Waxaan koobiyeeyay faylka lagama maarmaanka ah Raspberry, sidoo kale waxaan u gudbiyay dekedda 4444 iyada oo loo sii marayo SSH (telnet ka OpenOCD) waxaanan adeegsaday amarka load_image. Markaad sameyso, waxay u muuqataa in wax walba ay barafoobeen, laakiin dhab ahaantii "ma seexdo, si tartiib ah ayay u libiqaysaa": Waxa ay soo dejisanaysaa faylka, waxa ay ku samaynaysaa xawaare dhan laba kilobytes ilbiriqsikii.

Astaamaha rakibidda meelaha jabinta

Dad badan ayaa laga yaabaa inaysan ka fikirin tan marka ay saxayaan barnaamijyada caadiga ah, laakiin meelaha jaban had iyo jeer laguma dejiyo qalabka. Mararka qaarkood dejinta barta jabinta waxay ku lug leedahay in si ku meel gaar ah loo qoro tilmaamo gaar ah meesha saxda ah si toos ah u geli code mashiinka. Tusaale ahaan, tani waa sida amarkayga caadiga ahi u shaqeeyay b ee GDB. Waa kuwan waxa soo socda:

  • dhibic ma dhigi kartid gudaha BootROM sababtoo ah ROM
  • Waxaad dejin kartaa barta jabinta koodhka RAM-ka lagu shubay kaarka SD, laakiin waxaad u baahan tahay inaad sugto ilaa inta laga soo shubanayo. Haddii kale, dib uma qori doonno qayb kood ah, laakiin xamuulka ayaa dib u qori doona bartayada

Waan hubaa inaad si cad u waydiisan karto inaad isticmaasho goobaha jabinta qalabka, laakiin waxaa jira tiro kooban oo iyaga ka mid ah si kastaba.

Beddelka BootROM degdegga ah

Marxaladda bilawga ah ee qaladka, inta badan waxaa jira rabitaan ah in la hagaajiyo BootROM-ka oo mar kale isku day. Laakiin waxaa jirta dhibaato: BootROM waa qayb ka mid ah nashqada lagu shubay FPGA, isku-dubaridkeeduna waa dhawr daqiiqadood (tanina waa ka dib markii la soo ururiyey sawirka BootROM laftiisa C iyo Assembler...). Nasiib wanaag, dhab ahaantii wax walba aad uga dhakhso badan: tixda falku waa sidan soo socota:

  • dib u soo kicin bootrom.mif (Waxaan u wareegay MIF halkii HEX, sababtoo ah had iyo jeer waxaan lahaa xoogaa dhibaatooyin ah HEX, iyo MIF waa qaabka asalka ah ee Alter)
  • Quartus ku dheh Processing -> Update Memory Initialization File
  • on shayga Assembler (ee tiirka bidix ee Hawlaha) amarka Bilow mar kale

Wax kasta oo ku saabsan wax walba - dhowr iyo toban ilbiriqsi.

Diyaarinta kaadhka SD

Wax kasta oo halkan ku yaal waa sahlan yihiin, laakiin waxaad u baahan tahay inaad samir yeelato oo aad haysato 14Gb oo boos disk ah:

git clone https://github.com/sifive/freedom-u-sdk
git submodule update --recursive --init
make

Taas ka dib waxaad u baahan tahay inaad geliso nadiif ah, ama halkii, mid aan ku jirin wax lagama maarmaan ah, kaarka SD, oo fuliyo

sudo make DISK=/dev/sdX format-boot-loader

… Halkee sdX - qalab loo qoondeeyey kaarka. FIIRO GAAR AH: xogta kaadhka ku jirta waa la tirtiri doonaa, waa la beddeli doonaa iyo guud ahaan! Way adag tahay in shirka oo dhan laga sameeyo hoosta sudosababtoo ah markaa dhammaan qalabka dhismaha ayaa iska lahaan doona root, shirkana waa in hoos laga soo bilaabo sudo si joogto ah.

Natiijadu waa kaar ku qoran GPT oo ka kooban afar qaybood, mid ka mid ah uu leeyahay baruur uEnv.txt iyo sawirka bootable ee qaabka FIT (waxa uu ka kooban yahay dhowr sawir-hoosaad, mid walbana uu leeyahay ciwaanka soo dejinta), qaybta kale waa madhan, waxaa loo malaynayaa in lagu qaabeeyey Ext4 ee Linux. Laba qaybood oo kale - dahsoonU-Boot waxay ku nooshahay mid ka mid ah (ka-soo-noqoshada, inta aan fahmay, waxaa lagu dhejiyay BootROM), dhanka kale, waxay u muuqataa, doorsoomayaasha deegaanku way nool yihiin, laakiin weli ma isticmaalin.

Heerka koowaad, BootROM

Xikmadda caanka ah waxay tiraahdaa: "Haddii barnaamijka uu jiro qoob-ka-ciyaarka dafka, ka dibna elektarooniga waxaa sidoo kale jira qoob-ka-ciyaarka dab-damiska." Xitaa maahan xaqiiqda ah in mar aan ku dhawaad ​​gubay guddiga, go'aaminta in "Hagaag, GND waa isla heer hoose." (sida muuqata, iska caabintu waxba ma yeeli doonto ka dib...) Waa wax badan oo ku saabsan xaqiiqda ah in haddii gacmahaagu aysan halkaas ka korin, markaa qalabka elektiroonigga ah waligiis ma joojinayo inuu keeno waxyaabo la yaab leh: marka la iibiyo xiriiriyaha guddiga, weli ma awoodin in aan si sax ah u iibiyo xiriirada - fiidiyoowgu wuxuu muujinayaa sida alxanka laftiisa u faafo Isku xirka oo dhan, kaliya mari birta alxanka, Aniga ahaan, wuxuu "dharbaaxay" si aan kala sooc lahayn. Waa hagaag, waxaa laga yaabaa in alxanku aanu ku habboonayn heerkulka birta alxanka, laga yaabee wax kale ... Guud ahaan, markii aan arkay in aan hore u lahaa darsin xiriir ah, waan ka quustay oo bilaabay cillad. Kadibna way bilaabatay dahsoon: Waxaan ku xiray RX / TX UART, waxaan ku shubaa firmware - waxay tiri

INIT
CMD0
ERROR

Hagaag, wax walba waa macquul - Ma aanan ku xirin moduleka kaarka SD. Waanu saxnaa xaalada, ku dheji firmware-ka ... Oo aamusnaanta ... Maxaan u bedeli waayay maskaxdayda, laakiin sanduuqa yar ayaa furay: mid ka mid ah biinanka moduleka waa in lagu xiro VCC. Xaaladdeyda, moduleku wuxuu taageeray 5V si uu u helo koronto, sidaas darteed aniga oo aan ka fikirin laba jeer, waxaan ku dhejiyay fiilada ka imanaysa moduleka dhinaca ka soo horjeeda guddiga. Natiijo ahaan, xidhiidhiyaha qalloocan ee la iibiyay ayaa noqday mid qalloocan, iyo Xidhiidhka UART ayaa si fudud u lumay. facepalm.jpg Guud ahaan, "madaxa xun lugaha nasasho ma siiyo," gacmaha qalloocanna nasasho ma siiyaan madaxa ...

Natiijo ahaan, waxaan arkay kii la sugayay

INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING /

Intaa waxaa dheer, way dhaqaaqdaa oo tusaha loading wuu wareegayaa. Isla markiiba waxaan xusuustaa maalmahaygii dugsiga iyo raritaannada firaaqada ah ee MinuetOS ee diskka-floppy-ka. Haddii aanu waduhu shiidin.

Dhibaatadu waxay tahay in fariinta BOOT ka dib aysan waxba dhicin. Tani waxay ka dhigan tahay in la gaadhay waqtigii lagu xidhi lahaa OpenOCD ilaa Raspberry, GDB ee martida loo yahay, oo arag waxa ay tahay.

Marka hore, isku xirka iyadoo la adeegsanayo GDB isla markiiba waxay muujisay taas $pc (barnaamijka miiska, ciwaanka tilmaamaha) ayaa u duulaya 0x0 - Tani waxay u badan tahay inay dhacdo khaladaad badan ka dib. Sidaa darteed, isla markiiba ka dib marka fariinta la soo saaro BOOT aan ku darno wareeg aan xad lahayn. Tani waxay dib u dhigi doontaa isaga in muddo ah ...

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;
 }

Koodhkan khiyaanada leh waxaa loo adeegsadaa "isku halaynta": Waxaan maqlay meel in wareeg aan dhammaad lahayn ay tahay Dabeecad aan la qeexin, laakiin isku-dubariduhu uma badna inuu qiyaaso (Waxaan ku xasuusinayaa taas sida waafaqsan 0x10000 ku yaal BootROM).

Qeybta 3: Ku dhawaad ​​rarka Linux kaarka SD ilaa RocketChip

Waxay u ekaan doontaa, maxaa kale oo laga filan karaa - qallafsanaan adag, noocee koodhadhka isha ayaa jira? Laakin gudaha maqaalkaas qoraagu waxa uu khalad ka saarayay code C... Kreks-fex-pex:

(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.

Qeybta 3: Ku dhawaad ​​rarka Linux kaarka SD ilaa RocketChip

Kaliya uma baahnid inaad soo dejiso faylka MIF ama bin, laakiin nooca asalka ah oo qaab ELF ah.

Hadda waxaad ku qiyaasi kartaa isku dayga nth ciwaanka halka fulintu ay sii socon doonto (tani waa sabab kale oo ay tahay in iskuduwehu aanu u malayn in loopku uu yahay mid aan xad lahayn). Kooxda

set variable $pc=0xADDR

Waxay kuu ogolaaneysaa inaad bedesho qiimaha diiwaanka ee duulista (kiiskan, cinwaanka tilmaamaha hadda jira). Caawimaadkeeda, waxaad bedeli kartaa qiyamka lagu qoray xusuusta (iyo diiwaannada xusuusta-mapped).

Ugu dambeyntii, waxaan imid gabagabada (ma hubo midka saxda ah) in aan haysano "sawirka kaarka SD ee nidaamka khaldan", waxaanan u baahanahay inaanan tagin bilowga hore ee xogta la soo dejiyey, laakiin 0x89800 bytes sii:

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

Waxaa laga yaabaa in tani ay sidoo kale saameysay xaqiiqda ah inaan gacanta ku haysan kaarka 4Gb ee aan loo baahnayn, waxaan qaatay 2Gb oo waxaan ku beddelay Makefile si aan kala sooc lahayn. DEMO_END=11718750 on DEMO_END=3078900 (ha raadsan macnaha macne gaar ah - ma jiro, kaliya hadda sawirka ayaa la dhigayaa kaarka).

Heerka labaad, U-Boot

Hadda weli waanu "soo dhacaynaa", laakiin waxaan mar hore joognaa meeshii saxda ahayd 0x0000000080089a84. Halkan waa inaan qiraa: dhab ahaantii, soojeedintu kuma socoto "dhammaan joogsiga", laakiin qayb ahaan waa la qoray "ka dib", markaa halkan waxaan mar horeba ku guuleystey inaan geliyo faylka dtb saxda ah ee SoC-ga, ku saxo goobaha HiFive_U-Boot doorsoome CONFIG_SYS_TEXT_BASE=0x80089800 (halkii 0x08000000) si ciwaanka la soo dejiyo uu ula mid noqdo kan dhabta ah. Hadda waxaan ku dhejineynaa khariidadda heerka xiga, sawir kale:

(gdb) file ../freedom-u-sdk/work/HiFive_U-Boot/u-boot
(gdb) tui en

Oo waxaynu aragnaa:

   │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)                      │

Waxaa intaa dheer, waxaan ku boodnaa inta u dhaxaysa sadarrada 308 iyo 309. La yaab maaha, marka la eego in $sp been macnaha 0xfffffffe31cdc0a0. Hoogay, waxay sidoo kale si joogto ah "u carartaa" sababtoo ah xariiqa 307. Sidaa darteed, aan isku dayno inaan dejino meel ka baxsan. trap_entry, ka dibna ku noqo 0x80089800 (U-Boot's entry point), oo aynu rajayno in aanay u baahnayn in diiwaanada si sax ah loo dejiyo ka hor intaanad boodin... Waxay u egtahay inay shaqaynayso:

(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

Tilmaamaha xirmooyinka waa sidaas, si daacad ah u hadla: waxay tilmaamaysaa inay ka gudubto RAM gebi ahaanba (haddii, dabcan, horayba uma haysanin tarjumaad ciwaan ah, laakiin aan rajeyneyno doorasho fudud).

Aan isku dayno inaan ku bedelno tilmaame 0x881cf950. Natiijo ahaan, waxaan ku soo gebogebeynay in handle_trap wacay oo la wacay, isla markaana waanu galnay _exit_trap oo dood leh epc=2148315240 (hal jajab tobanle):

(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

U deji barta goynta strnlen, waan sii wadnaa oo aragnaa:

(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

U muuqda inuu yahay, _exit_trap wuxuu rabaa inuu bixiyo macluumaadka qaladka ee ku saabsan marka laga reebo in dhacay, laakiin ma awoodo. Markaa, si uun ilahayagu dib looma soo bandhigin. set directories ../freedom-u-sdk/HiFive_U-Boot/ KU SAABSAN! Hadda la soo bandhigay!

Hagaag, aan mar kale socodsiinno, oo aan ka aragno rajada sababta keentay dhibkii asalka ahaa ee sababay khaladkii ugu horreeyay (mcause == 5). Haddii aan si sax ah u fahmay waxa qoran halkan bogga 37, markaas ka-reebitaankan macneheedu waa Load access fault. Sababtu waxay u muuqataa inay tahay halkan

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 wuxuu leeyahay macno isku mid ah oo khaldan, iyo gudaha board_init_f_init_reserve qalad ayaa dhaca. Waxay u eg tahay kan dambiilaha: doorsoome leh magac aan madmadow lahayn CONFIG_SYS_INIT_SP_ADDR. Waxaa lagu qeexay faylka HiFive_U-Boot/include/configs/HiFive-U540.h. Mararka qaar xitaa waxaan u maleeyay, malaha, si fiican, waa inaan ku daraa bootloader ee processor-ka - malaha way sahlanaan lahayd in la hagaajiyo processor-ka wax yar? Laakiin markaas waxaan arkay in ay u badan tahay sida farshaxan aan dhammaystirnayn#if 0goobaha gaarka ah ee qaabeynta xusuusta kala duwan, waxaadna isku dayi kartaa inaad sidan sameyso:

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 */

Mar marka qaar tirada ulaha xirmooyinka tignoolajiyada meel xasaasi ah ayuu gaaray. Ka dib markii aan yara halgamay, waxaan imid baahida loo qabo in aan sameeyo deked sax ah oo loogu talagalay guddigayga. Si tan loo sameeyo, waxaan u baahanahay inaan nuqul ka sameyno oo aan hagaajino tiro faylal ah si aan ugu habbooneyno qaabeyntayada.

Hagaag, qiyaastii, halkan waa miis yar

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

Faahfaahinta waxaa laga heli karaa kayd.

Sida ay soo baxday, sabuuradan SiFive diiwaanka aaladaha qaarkood waxay leeyihiin cinwaano kala duwan. Waxa kale oo ay soo baxday in U-Boot lagu habeeyay iyadoo la adeegsanayo habka Kconfig, oo horeba looga yaqaan kernel Linux - tusaale ahaan, waxaad amri kartaa make menuconfig, iyo interface qoraal ah oo ku habboon ayaa hortiisa ka muuqan doonta adiga oo muujinaya sharraxaadda cabirrada by ? iwm. Guud ahaan, markii la isku daro sharraxa saddexaad ee sharraxaadaha laba guddi, ka tuuray dhammaan noocyada dib-u-habaynta PLL ee is-beddelka ah (sida muuqata, tani waxay si uun ugu xiran tahay kontoroolka kombuyuutarka martida loo yahay iyada oo loo marayo PCIe, laakiin tani lama hubo) , Waxaan helay qaar ka mid ah firmware, kaas oo, cimilada saxda ah ee Mars i siisay fariin via UART oo ku saabsan samaynta xashiish laga soo ururiyey, iyo ku saabsan inta DRAM aan haysto (laakin aniga qudhaydu waxay xogtan ku qoray madaxa).

Waxa kaliya ee naxariista leh ayaa ah in tan ka dib guddigu caadi ahaan joojiyay ka jawaabista processor-ka JTAG, iyo ka soo dejinta kaarka SD waa, hoogay, maaha mid degdeg ah qaabeyntayda. Dhanka kale, mararka qaarkood BootROM wuxuu siiyay fariin taas ERROR, wuu ku guul daraystay inuu bootiyo, U-Bootna isla markiiba wuu soo baxay. Markaas ayay ahayd markii ay ii soo baxday: sida muuqata, ka dib markii dib loo bilaabo bitstream-ka FPGA, xusuusta lama tirtiro, waqti uma hayso "tababarka", iwm. Marka la soo koobo, waxaad si fudud u samayn kartaa marka fariintu soo baxdo LOADING / ku xidhnow cilladaha iyo amar set variable $pc=0x80089800, halkaas oo la hareer maray loading this dheer (dabcan, on malo ah in markii ugu danbeysay ee ay jabtay goor hore oo ku filan in aanay haysan waqti ay ku shuban wax on top of code asalka ah).

Jid ahaan, guud ahaan miyay caadi tahay in processor-ku uu gabi ahaanba qaboojiyo oo JTAG debugger aanu ku xidhi karin fariimaha?

Error: unable to halt hart 0
Error:   dmcontrol=0x80000001
Error:   dmstatus =0x00030c82

Markaa, sug! Horay ayaan u arkay tan! Wax la mid ah ayaa dhacaya marka TileLink uu xiran yahay, oo anigu si uun kuma aamini karo qoraaga kontoroolka xusuusta - aniga qudhaydu waxaan qoray ...

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

Xariiqan qariibka ah ka hor In: serial dheg ha u dhigin - Waxaan isku dayay inaan ku fahmo processor-ka laadlaadsan inuu si sax ah ula shaqeeyo deegaanka iyo in kale. Maxaad ula jeeddaa, "Toban daqiiqo ayaa sidan oo kale u soo laadlaadsannaa"? Ugu yaraan waxa ay ku guulaysatay in ay guurto oo aad tagto liiska boot-ka! Digression yar: in kasta oo U-Boot lagu shubo 2 ^ 24 bytes ee ugu horreeya ee kaarka SD, marka uu bilaabo, waxay isu koobiyaysaa ciwaanka ka fog, ama ku qoran madaxa qaabeynta, ama si fudud ciwaannada sare ee RAM. , oo qabta ELF raritaan - characters, iyo wareejinta maamulka halkaas. Markaa: waxay u egtahay in aanu heerkan ka gudubnay oo aanu helnay gunno aanu Processor-ku si adag u laadlaadsan intaa ka dib.

Haddaba waa maxay sababta aanu saacad-guduhu u shaqaynayn? Waxay u egtahay inaysan saacadu shaqaynayn sababo jira awgood...

(gdb) x/x 0x0200bff8
0x200bff8:      0x00000000

Maxaa dhacaya haddii aad gacanta u rogto fallaadhaha?

(gdb) set variable *0x0200bff8=310000000
(gdb) c

Kadib:

Hit any key to stop autoboot:  0
MMC_SPI: 0 at 0:1 hz 20000000 mode 0

Gabagabo: saacadu ma dagto. Tani waxay u badan tahay sababta gelinta kiiboodhka aanu u shaqayn:

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 == '[') {
...

Dhibaatadu waxay noqotay in aan aad u xariifsanaa: Waxaan ku daray furaha qaabaynta processor-ka:

  case DTSTimebase => BigInt(0)

... iyadoo lagu saleynayo xaqiiqda ah in faallada ay tiri "haddii aadan aqoon, ka tag 0." Oo ka dib oo dhan WithNBigCores Kaliya waxaan u dhigay 1 MHz (sida, habka, waxaa lagu muujiyey qaabka U-Boot). Laakin habaar, waan nadiifsanahay oo taxaddar leh: halkaas kuma aqaan, halkan waa 25MHz! Ugu dambeyntii, waxba ma shaqeeyaan. Waxaan meesha ka saaray "horumarkayga" iyo...

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 #

Xitaa waxaad geli kartaa amarrada! Tusaale ahaan, ka dib markaad wax yar ku dhufato, ugu dambeyntii waxaad qiyaasi kartaa inaad gasho mmc_spi 1 10000000 0; mmc part, yaraynta inta jeer ee SPI laga bilaabo 20MHz ilaa 10MHz. Waa maxay sababtu? Hagaag, inta jeer ee ugu badan ee 20MHz ayaa lagu qoray qaabeynta, walina halkaasay ku qoran tahay. Laakiin, inta aan fahamsanahay, interfaces-yada, ugu yaraan halkan, waxay u shaqeeyaan sidan oo kale: koodhka ayaa u qaybiya inta jeer ee cutubka qalabka (keygu waa 25MHz meel kasta) bartilmaameedka, oo dejinaya qiimaha natiijada sida qaybiye ee xakamaynta u dhiganta. diiwaan geli. Dhibaatadu waxay tahay haddii loogu talagalay 115200Hz UART waxaa jira qiyaastii waxa loo baahan yahay, markaa haddii aad u qaybiso 25000000 20000000 waxaad heli doontaa 1, i.e. waxay ku shaqayn doontaa 25MHz. Waxaa laga yaabaa in tani ay tahay mid caadi ah, laakiin haddii xayiraadaha la dejiyo, waxay la macno tahay in qof u baahan yahay (laakiin tani maaha mid la hubo) ... Guud ahaan, way fududahay in la dejiyo oo la sii wado - fog iyo, hoog, muddo dheer. 25MHz ma aha Core i9.

Soo saarida konsole

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

Hagaag, waxaan gaarnay heerkii ku xigay, laakiin wali waa baraf. Mararka qaarkood waxay sidoo kale ku rushaysaa ka reeban. Waxaad ku arki kartaa mcause adiga oo sugaya koodka ciwaanka la cayimay $pc iyo ka dib si ahaado trap_entry. Xakameeyaha U-Boot laftiisu wuxuu kaliya soo saari karaa mcause = 0..4, markaa u diyaargarow inaad ku dhegto boot khaldan. Ka dib waxaan galay qaabeynta, waxaan bilaabay inaan eego waxa aan bedelayo, oo waxaan xasuustay: halkaas conf/rvboot-fit.txt qoran:

fitfile=image.fit
# below much match what's in FIT (ugha)

Hagaag, aynu keenno dhammaan faylasha si waafaqsan, oo ku beddelo khadka taliska kernel wax sidan oo kale ah, maadaama ay jiraan tuhuno SIF0 - Tani waa wax soo saarka meel loo sii marayo PCIe:

-bootargs=console=ttySIF0,921600 debug
+bootargs=console=ttyS0,125200 debug

Aynu ka beddelno algorithm-ka xashiishka ee SHA-256 una beddelno MD5: Uma baahni xoogga sirta ah (gaar ahaan marka la tirtirayo), waxay qaadataa waqti aad u dheer, iyo qabashada khaladaadka daacadnimada inta lagu jiro rarka, MD5 aad bay u fududahay. Waa maxay natiijada ugu dambaysa? Waxaan bilownay inaan heerkii hore si dhaqsiyo leh u dhameystirno (sababtoo ah xashiish fudud), midda xigtana waa furmay:

...
   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

Laakin saacadu ma dagi...

(gdb) x/x 0x0200bff8
0x200bff8:      0x00000000

Haah, waxay u egtahay in la saxay saacada ay noqotay placebo, in kasta oo ay aniga ila ahayd wakhtigaas inay caawisay. Maya, dabcan waxay u baahan tahay in la hagaajiyo, laakiin aan marka hore u leexanno fallaadhaha gacanta oo aan aragno waxa dhacaya:

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.

Dhanka kale…

   Loading Kernel Image ... OK
Booting kernel in
3
2
1
0
## Starting application at 0x80000000 ...

Maya, waxaan si otomaatig ah u wadi doonaa saacadda - haddii kale waxaa laga yaabaa inuu go'aansado inuu ku hagaajiyo saacadda halkaas!

Dhanka kale, ciwaanka tilmaamaha hadda jira wuxuu tilmaamayaa meel

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>

Gudaha Rakaabka Berkeley Boot Loader. Shakhsiyan, waxa igu jahawareersan arrintan waa sheegida htif - Interface-ka loo isticmaalo furitaanka kernel-ka (taas oo ah, iyada oo la kaashanaysa ARM-ga martida loo yahay), waxaan u qaatay in aan keli ahay. Si kastaba ha noqotee, haddii aad ka hesho shaqadan koodhka isha, waxaad arki kartaa in wax walba aysan aad u xunayn:

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"); }
  }
}

Raadinta: bilaw saacadda

Raadinta diiwaanka CLINT ayaa nagu hogaamineysa

    val io = IO(new Bundle {
      val rtcTick = Bool(INPUT)
    })

    val time = RegInit(UInt(0, width = timeWidth))
    when (io.rtcTick) { time := time + UInt(1) }

Kee ku xidha RTC, ama MockAON dahsoon, kaas oo aan markii hore ka fikiray: "Marka, maxaan halkan ku haynaa? Ma cadda? Aan daminno!" Maadaama aanan wali fahmin nooca sixirka saacada ka socda halkaas, markaa waxaan dib u soo celin doonaa macquulkan 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
  }

Samaynta jidkayaga kernel Linux

Halkan sheekadu mar hore ayay soo jiitamaysay oo waxay noqotay wax yar oo kali ah, markaa kor ilaa hoos ayaan ku tilmaami doonaa:

BBL waxay u qaadatay joogitaanka FDT ee 0xF0000000, laakiin mar hore ayaan saxay! Hagaag, aan mar kale eegno... La helay HiFive_U-Boot/arch/riscv/lib/boot.c, lagu beddelay 0x81F00000, ku qeexan qaabka U-Boot.

Dabadeed BBL waxay ka cawdeen in aanay jirin wax xusuus ah. Jidkaygu wuxuu ku dhex jiraa shaqada mem_prop, maxaa ku jira riscv-pk/mashiin/fdt.c: halkaas waxaan ka bartay inaad u baahan tahay inaad calaamadiso fdt ram node sida device_type = "memory" - ka dib, laga yaabee, koronto-dhaliyaha processor-ku wuxuu u baahan doonaa in la saxo, laakiin hadda waxaan ku qori doonaa gacanta - si kastaba, gacanta ayaan ku wareejiyay faylkan.

Hadda waxaan helay fariinta (oo lagu bixiyay qaab qaabaysan, oo leh soo celinta gaadiidka):

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.

Waxay u muuqataa in xulashooyinka la tilmaamay sida loo baahdo riscv,kernel-start и riscv,kernel-end DTB, laakiin eber waa la kala saaray. Dejinta query_chosen waxay muujisay in BBL ay isku dayayso inay kala saarto ciwaanka 32-bit ah, laakiin ay la kulanto labo-labo <0x0 0xADDR>, oo qiimaha ugu horreeya wuxuu u muuqdaa inuu yahay kuwa ugu yar ee muhiimka ah. Lagu daray qaybta chosen

chosen {
      #address-cells = <1>;
      #size-cells = <0>;
      ...
}

oo saxay jiilka qiyamka: ha ku darin 0x0 curiyaha kowaad.

Talaabooyinkan 100500 ee fudud waxay fududayn doonaan daawashada dhicitaanka penguin:

Qoraal qarsoon

   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)

( sumadda waxaa soo bandhigay BBL, midda ku dhegganna waxaa soo bandhigay kernel-ka).

Nasiib wanaag, ma aqaano sida ay meel walba u tahay, laakiin RocketChip, marka aad ku xirto debugger via JTAG, waxaad ka qaban kartaa dabinnada dibadda sanduuqa - cilladaha ayaa si sax ah u joogsan doona meeshan.

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); // < ВЫ НАХОДИТЕСЬ ЗДЕСЬ
}

Sida kaftankii hore yidhi, CPU lama helin, ku dayashada software-ka. Hagaag, ama ha ordin. Lumay hal processor ubucda.

/* The lucky hart to first increment this variable will boot the other cores */
atomic_t hart_lottery;
unsigned long boot_cpu_hartid;

Faallo Wacan linux/arch/riscv/kernel/setup.c - nooc ka mid ah rinjiyeynta deyrka iyadoo la adeegsanayo habka Tom Sawyer. Guud ahaan, sababo jira awgeed maanta ma jirin cid ku guulaysata, abaal-marinta waxaa loo wareejiyaa barbaraha xiga...

Halkan waxaan ku soo jeedinayaa in la soo afjaro maqaalkii hore ee dheeraa.

In la sii wado. Waxaa jiri doona dagaal uu la jiro bug dhagaraysan oo awood u leh inuu qariyo haddii aad si tartiib tartiib ah ugu soo guurto adigoo raacaya tallaabo keli ah.

Soo daji qoraalka qoraalka ah ee shaashadda (xidhiidhinta dibadda):
Qeybta 3: Ku dhawaad ​​rarka Linux kaarka SD ilaa RocketChip

Source: www.habr.com

Add a comment