Pàirt 3: Cha mhòr a 'luchdachadh Linux bho chairt SD gu RocketChip

Pàirt 3: Cha mhòr a 'luchdachadh Linux bho chairt SD gu RocketChip В pàirt roimhe chaidh rianadair cuimhne obrach nas motha no nas lugha a chuir an gnìomh, no an àite sin, pasgan thairis air IP Core bho Quartus, a tha na inneal-atharrachaidh airson TileLink. An-diugh, anns an earrainn “Tha sinn a’ giùlain RocketChip gu bòrd Sìneach air nach eil mòran eòlach le Cyclone ”chì thu tòcan obrach. Thug am pròiseas beagan nas fhaide: bha mi mu thràth a’ smaoineachadh gun cuireadh mi Linux air bhog gu sgiobalta agus gluasad air adhart, ach cha robh sin fìor. Anns a’ phàirt seo, tha mi a’ moladh coimhead air a’ phròiseas airson U-Boot, BBL a chuir air bhog, agus oidhirpean eagallach an eithne Linux gus tòiseachadh. Ach tha consol ann - U-Boot, agus gu math adhartach, le mòran de na bhiodh dùil agad bho chonsail làn-chuimseach.

Bidh am bathar-cruaidh a’ toirt a-steach cairt SD ceangailte tron ​​​​eadar-aghaidh SPI, a bharrachd air UART. Anns a 'phàirt bathar-bog, thèid BootROM a chuir na àite xip air sdboot agus, gu dearbh, chaidh na h-ìrean luchdachadh a leanas a chur ris (air a’ chairt SD).

A 'crìochnachadh am bathar-cruaidh

Mar sin, an obair: feumaidh tu atharrachadh gu cridhe “mòr” agus UART (bho Raspberry) agus inneal-atharrachaidh SD a cheangal (chleachd sinn cairt bho Catalex le sia prìneachan: GND, VCC, MISO, MOSI, SCK, CS) .

Ann am prionnsabal, bha a h-uile dad gu math sìmplidh. Ach mus do thuig mi seo, chaidh mo thilgeil beagan bho thaobh gu taobh: às deidh na h-ùine roimhe, cho-dhùin mi a-rithist gum feumadh mi measgachadh a dhèanamh a-rithist. System rudeigin mar HasPeripheryUART (agus buileachadh a rèir sin), an aon rud airson a 'chairt SD - agus bidh a h-uile dad deiseil. An uairsin chuir mi romham faicinn mar a chaidh a bhuileachadh ann an dealbhadh “dona”. Mar sin, dè a tha dona mu dheidhinn seo? Chan eil Arty, a rèir coltais, a’ freagairt - tha an uilebheist fhathast unleahshed.DevKitConfigs. Agus gu h-obann thionndaidh e a-mach gu robh cuid de ath-chòmhdach anns a h-uile àite, a chaidh a chuir tro pharamadairean le iuchraichean. Tha mi creidsinn gur dòcha gu bheil seo gu math sùbailte agus furasta a rèiteachadh, ach bu mhath leam co-dhiù rudeigin a ruith an toiseach ... Nach eil an aon rud agad, dìreach nas sìmplidh agus nas annasaiche?.. Sin nuair a thàinig mi tarsainn vera.iofpga.FPGAChip airson Microsemi FPGAn agus thug e air falbh e sa bhad airson luachan agus dh’ fheuch mi ri mo bhuileachadh fhèin a dhèanamh le samhlachas, gu fortanach tha barrachd no nas lugha an “cruth bòrd-màthar” gu lèir ann an aon fhaidhle.

Thionndaidh e a-mach nach fheum thu ach cuir ris System.scala sreathan

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

Loidhne ann am buidheann clas System a’ cur fiosrachadh mun tricead aig a bheil am pàirt seo den SoC againn ag obair ris an fhaidhle dts. Cho fad ‘s a tha mi a’ tuigsinn, tha DTS/DTB na analogue statach de theicneòlas plug-and-play airson innealan freumhaichte: tha an craobh tuairisgeul dts air a chuir ri chèile ann am faidhle binary dtb agus air a ghluasad leis an bootloader chun kernel gus an urrainn dha am faidhle a rèiteachadh gu ceart. bathar-cruaidh. Gu inntinneach, às aonais an loidhne le tlclock bidh a h-uile dad a’ co-chur gu foirfe, ach a’ cur ri chèile BootROM (leig dhomh do chuimhneachadh, a-nis bidh seo mar-thà sdboot) chan obraich e - rè a’ phròiseas cruinneachaidh bidh e a’ parsadh am faidhle dts agus a’ cruthachadh bann-cinn le macro TL_CLK, leis am bi e comasach dha roinneadh tricead a rèiteachadh gu ceart airson eadar-aghaidh taobh a-muigh.

Feumaidh tu cuideachd an “uèirleadh” a cheartachadh beagan:

Àrd-ùrlar.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
}

Chaidh na slabhraidhean clàraidh, a bhith onarach, a chur ris dìreach mar an ceudna ri cuid de dh’ àiteachan eile sa chòd tùsail. As dualtaiche, bu chòir dhaibh dìon an aghaidh meata-sheasmhachd. 'S dòcha ann an некоторых tha an dìon fhèin aig blocaichean mu thràth, ach an toiseach tha mi airson a chuir air bhog co-dhiù “aig ìre àrd-inbhe.” Is e ceist nas inntinniche dhomh carson a tha MISO agus MOSI an crochadh air eadar-dhealaichte dq? Cha do lorg mi am freagairt fhathast, ach tha e coltach gu bheil an còrr den chòd an urra ri dìreach ceangal mar sin.

Gu corporra, thug mi dìreach na prìneachan dealbhaidh dha na fiosan an-asgaidh air a ’bhloc agus ghluais mi an geansaidh taghadh bholtachd gu 3.3V.

Uidheam lìonraidh cairt SD

Sealladh bho shuas:

Pàirt 3: Cha mhòr a 'luchdachadh Linux bho chairt SD gu RocketChip

Sealladh gu h-ìosal:

Pàirt 3: Cha mhòr a 'luchdachadh Linux bho chairt SD gu RocketChip

Debugging bathar-bog: Innealan

An toiseach, bruidhnidh sinn mu na h-innealan deasbaid a tha rim faighinn agus na crìochan aca.

Minicom

An toiseach, feumaidh sinn dòigh air choireigin a leughadh dè an toradh bootloader agus kernel. Gus seo a dhèanamh air Linux (sa chùis seo, air an fhear air an RaspberryPi), feumaidh sinn am prògram Minicom. San fharsaingeachd, nì prògram sam bith a bhios ag obair le port sreathach.

Thoir an aire, nuair a thòisicheas tu, gum feum ainm an inneal puirt a bhith air a shònrachadh mar -D /dev/ttyS0 - às deidh an roghainn -D. Uill, am prìomh fhiosrachadh: fàgail, cleachdadh Ctrl-A, X. Gu dearbh bha cùis agam nuair nach do dh ’obraich am measgachadh seo - faodaidh tu dìreach a ràdh bho sheisean SSH faisg air làimh killall -KILL minicom.

Tha aon fheart eile ann. Gu sònraichte, tha dà UART aig an RaspberryPi, agus faodar an dà phort atharrachadh mar-thà airson rudeigin: aon airson Bluetooth, am fear eile gu bunaiteach a’ toirt a-mach an consol kernel. Gu fortanach, faodar an giùlan seo a chuir thairis a rèir an leabhair-làimhe seo.

Ath-sgrìobhadh cuimhne

Nuair a bha mi a’ dì-bhugachadh, airson beachd-bharail a dhearbhadh, bha agam ri uaireannan luchdaich bootloader (duilich) a-steach do RAM gu dìreach bhon òstair. Is dòcha gun gabh seo a dhèanamh gu dìreach bho GDB, ach aig a’ cheann thall lean mi slighe shìmplidh: rinn mi leth-bhreac den fhaidhle riatanach don Raspberry, chuir mi air adhart port 4444 tro SSH (telnet bho OpenOCD) agus chleachd mi an àithne load_image. Nuair a nì thu e, tha e coltach gu bheil a h-uile dad reòta, ach gu dearbh “Cha bhith e a’ cadal, bidh e dìreach a ’brùthadh gu slaodach”: Bidh e a’ luchdachadh sìos am faidhle, bidh e dìreach ga dhèanamh aig astar no dhà kilobytes gach diog.

Feartan stàladh puingean brisidh

Is dòcha nach robh aig mòran dhaoine ri smaoineachadh mu dheidhinn seo nuair a bhios iad a’ deasbad phrògraman cunbhalach, ach chan eil puingean brisidh an-còmhnaidh air an suidheachadh ann am bathar-cruaidh. Aig amannan bidh suidheachadh briseadh a’ toirt a-steach sgrìobhadh sìos stiùireadh sònraichte airson ùine ghoirid san àite cheart gu dìreach ann an còd inneal. Mar eisimpleir, seo mar a dh'obraich an òrdugh àbhaisteach agam b ann an GDB. Seo na leanas:

  • chan urrainn dhut dot a chuir am broinn BootROM air sgàth ROM
  • Faodaidh tu puing-briseadh a shuidheachadh air a’ chòd air a luchdachadh a-steach don RAM bhon chairt SD, ach feumaidh tu feitheamh gus an tèid a luchdachadh. Rud eile, cha bhith sinn ag ath-sgrìobhadh pìos còd, ach bidh an luchdan ag ath-sgrìobhadh ar briseadh

Tha mi cinnteach gun urrainn dhut iarraidh gu soilleir puingean brisidh bathar-cruaidh a chleachdadh, ach tha àireamh bheag dhiubh ann co-dhiù.

Ath-nuadhachadh Quick BootROM

Aig a' chiad ìre den debugging, gu tric bidh miann ann am BootROM a chàradh is feuch ris a-rithist. Ach tha duilgheadas ann: tha BootROM mar phàirt den dealbhadh air a luchdachadh a-steach don FPGA, agus tha an synthesis aige na chùis beagan mhionaidean (agus tha seo às deidh an ìomhaigh BootROM fhèin a chuir ri chèile bho C agus Assembler ...). Gu fortanach, ann an da-rìribh a h-uile dad fada nas luaithe: Tha sreath nan gnìomhan mar a leanas:

  • ath-ghin bootrom.mif (thuit mi gu MIF an àite HEX, oir bha cuid de dhuilgheadasan agam an-còmhnaidh le HEX, agus is e MIF an cruth dùthchasach aig Alter)
  • ann an Quartus abair Processing -> Update Memory Initialization File
  • air an nì Assembler (sa cholbh chlì de Tasks) àithne Tòisich a-rithist

A h-uile dad mu dheidhinn a h-uile càil - beagan deichean de dhiog.

Ag ullachadh a 'chairt SD

Tha a h-uile dad an seo gu math sìmplidh, ach feumaidh tu a bhith foighidneach agus timcheall air 14Gb de dh’ àite diosc a bhith agad:

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

Às deidh sin feumaidh tu fear glan, no an àite, a chuir a-steach anns nach eil dad riatanach, cairt SD, agus cuir an gnìomh

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

… càite sdX - inneal air a shònrachadh don chairt. ATTENTION: thèid an dàta air a’ chairt a dhubhadh às, ath-sgrìobhadh agus san fharsaingeachd! Cha mhòr gum b’ fhiach an co-chruinneachadh gu lèir a dhèanamh bho shìos sudooir an sin buinidh na h‑uile nithean togail dha root, agus feumaidh an co-chruinneachadh a bhith air a dhèanamh bho shìos sudo daonnan.

Is e an toradh seo cairt air a chomharrachadh ann an GPT le ceithir earrannan, aon dhiubh le FAT uEnv.txt agus ìomhaigh bootable ann an cruth FIT (tha grunn fo-ìomhaighean ann, gach fear le a sheòladh luchdachadh sìos fhèin), tha an sgaradh eile falamh, tha còir gum bi e air a chruth ann an Ext4 airson Linux. Dà earrann eile - dìomhair: Tha U-Boot a’ fuireach air aon (tha a chothromachadh, cho fada ‘s a tha mi a’ tuigsinn, air a chòdachadh gu cruaidh ann am BootROM), air an taobh eile, tha e coltach, tha na caochladairean àrainneachd aige beò, ach cha bhith mi gan cleachdadh fhathast.

Ìre a h-aon, BootROM

Tha gliocas mòr-chòrdte ag ràdh: “Ma tha ann am prògramadh tha dannsadh le tambourine, an uairsin ann an electronics tha dannsa le inneal-smàlaidh cuideachd.” Chan eil e eadhon mu dheidhinn aon uair ‘s gu robh mi cha mhòr air am bòrd a losgadh, a’ co-dhùnadh “Uill, tha GND aig an aon ìre ìosal.” (a rèir coltais, cha bhiodh resistor air a ghoirteachadh às deidh a h-uile càil ...) Tha e nas motha mu dheidhinn mura fàs na làmhan às an sin, nach sguir electronics a bhith a’ toirt iongnadh: nuair a bha mi a ’sàthadh a’ cheangail air a ’bhòrd, cha b’ urrainn dhomh fhathast an luchd-ceangail a shàrachadh gu ceart - tha a ’bhidio a’ sealltainn mar a bhios an solder a ’sgaoileadh gu dìreach thairis air a’ cheangal gu lèir, dìreach cuir a-steach iarann ​​​​soldering, Dhòmhsa, rinn e “slap” air thuaiream. Uill, is dòcha nach robh an solder freagarrach airson teòthachd an iarann ​​​​solder, is dòcha rudeigin eile... San fharsaingeachd, nuair a chunnaic mi gu robh dusan neach-fios agam mu thràth, leig mi seachad agus thòisich mi a’ dì-bhugachadh. Agus an uairsin thòisich e dìomhair: Cheangail mi RX/TX bho UART, bidh mi a’ luchdachadh am firmware - tha e ag ràdh

INIT
CMD0
ERROR

Uill, tha a h-uile dad loidsigeach - cha do cheangail mi am modal cairt SD. Bidh sinn a 'ceartachadh an t-suidheachaidh, a' luchdachadh am firmware ... Agus sàmhach ... Carson nach do dh'atharraich mi m 'inntinn, ach dh' fhosgail am bogsa beag: dh'fheumadh aon de na prìneachan modal a bhith ceangailte ri VCC. Anns a 'chùis agam, thug am modal taic do 5V airson solar cumhachd, agus mar sin gun a bhith a' smaoineachadh dà uair, chuir mi a-steach an uèir a 'tighinn bhon mhodal gu taobh eile a' bhùird. Mar thoradh air an sin, dh'fhàs an ceanglaiche cam a bha air a shìneadh gu sgiobalta, agus Bha an conaltradh UART dìreach air chall. aghaidh pailm.jpg San fharsaingeachd, “chan eil droch cheann a’ toirt fois dha na casan, ”agus chan eil làmhan cam a’ toirt fois sam bith don cheann ...

Mar thoradh air an sin, chunnaic mi an rud ris an robh dùil o chionn fhada

INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING /

A bharrachd air an sin, bidh e a ’gluasad agus bidh an comharra luchdachadh a’ snìomh. Tha cuimhne agam sa bhad air na làithean sgoile agam agus mar a chaidh MinuetOS a luchdachadh gu socair bho diosc sùbailte. Mura h-eil an dràibhear a 'bleith.

Is e an duilgheadas a th’ ann nach tachair dad às deidh an teachdaireachd BOOT. Tha seo a’ ciallachadh gu bheil an t-àm ann ceangal tro OpenOCD gu Raspberry, gu GDB air an aoigh, agus faicinn dè a th’ ann.

An toiseach, sheall ceangal le bhith a’ cleachdadh GDB sin sa bhad $pc (cunntas prògram, seòladh an stiùiridh làithreach) ag itealaich gu 0x0 - is dòcha gun tachair seo às deidh grunn mhearachdan. Mar sin, dìreach às deidh an teachdaireachd a chuir a-mach BOOT Nach cuir sinn lùb gun chrìoch. Cuiridh seo dàil air airson greis...

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

Tha còd duilich mar seo air a chleachdadh “airson earbsachd”: chuala mi am badeigin gur e Giùlan Neo-mhìnichte a th’ ann an lùb gun chrìoch, ach chan eil e coltach gum bi an neach-cruinneachaidh a’ tomhas (tha mi gad chuimhneachadh a rèir 0x10000 suidhichte BootROM).

Pàirt 3: Cha mhòr a 'luchdachadh Linux bho chairt SD gu RocketChip

Bhiodh e coltach, dè eile a bhiodh dùil - freumhaichte cruaidh, dè an seòrsa còdan stòr a th’ ann? Ach ann an an artaigil sin bha an t-ùghdar a' deasbaireachd a' chòd 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.

Pàirt 3: Cha mhòr a 'luchdachadh Linux bho chairt SD gu RocketChip

Feumaidh tu dìreach am faidhle MIF no biona a luchdachadh sìos, ach an dreach tùsail ann an cruth ELF.

A-nis faodaidh tu tomhas leis an naoidheamh oidhirp air an t-seòladh far an lean an cur gu bàs (is e seo adhbhar eile nach bu chòir don neach-cruinneachaidh a bhith air tomhas gu bheil an lùb gun chrìoch). Sgioba

set variable $pc=0xADDR

a’ leigeil leat luach a’ chlàir atharrachadh air a’ chuileag (sa chùis seo, seòladh an stiùiridh làithreach). Le a chuideachadh, faodaidh tu luachan sgrìobhte gu cuimhne atharrachadh (agus clàran le mapa cuimhne).

Aig a’ cheann thall, thàinig mi chun cho-dhùnadh (chan eil mi cinnteach cò tha ceart) gu bheil “dealbh cairt SD againn den t-siostam ceàrr”, agus feumaidh sinn a dhol chan ann gu toiseach an dàta a chaidh a luchdachadh sìos, ach gu 0x89800 bytes a bharrachd:

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

Is dòcha gun tug seo buaidh cuideachd leis nach robh cairt 4Gb neo-riatanach agam ri làimh, ghabh mi fear 2Gb agus chuir mi a-steach e san Makefile air thuaiream DEMO_END=11718750 air DEMO_END=3078900 (na bi a’ coimhead airson brìgh ann an ciall sònraichte - chan eil gin ann, is e dìreach gu bheil an ìomhaigh a-nis air a chuir air a’ chairt).

Ìre a dhà, U-Boot

A-nis tha sinn fhathast “a’ tuiteam ”, ach tha sinn mar-thà aig an àite cheart 0x0000000080089a84. An seo feumaidh mi aideachadh: gu dearbh, chan eil an taisbeanadh a’ dol “leis a h-uile stad”, ach tha e air a sgrìobhadh gu ìre “às deidh”, agus mar sin an seo tha mi air am faidhle dtb ceart a chuir a-steach bhon SoC againn, a cheartachadh anns na roghainnean HiFive_U-Boot caochlaideach CONFIG_SYS_TEXT_BASE=0x80089800 (an àite 0x08000000) gus am bi an seòladh luchdaich sìos a rèir an fhìor fhear. A-nis bidh sinn a’ luchdachadh mapa na h-ath ìre, ìomhaigh eile:

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

Agus chì sinn:

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

A bharrachd air an sin, bidh sinn a 'leum eadar loidhnichean 308 agus 309. Agus chan eil e na iongnadh, leis gu bheil sin ann $sp laighe an ciall 0xfffffffe31cdc0a0. Gu mì-fhortanach, bidh e an-còmhnaidh “a’ ruith air falbh” air sgàth loidhne 307. Mar sin, feuchaidh sinn ri puing-briseadh a shuidheachadh aig trap_entry, agus an uairsin air ais gu 0x80089800 (àite inntrigidh U-Boot), agus tha sinn an dòchas nach fheum e na clàran a shuidheachadh ceart mus leum iad... Tha e coltach gu bheil e ag obair:

(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

Tha am puing stac cho math, gu fìrinneach: tha e a’ comharrachadh a bhith a ’dol seachad air an RAM gu tur (mura, gu dearbh, nach eil eadar-theangachadh seòlaidh againn mu thràth, ach tha sinn an dòchas roghainn shìmplidh).

Feuchaidh sinn ris a’ phuing a chuir na àite 0x881cf950. Mar thoradh air an sin, thig sinn chun cho-dhùnadh sin handle_trap ghairm, agus ghairm sinn, agus aig a' cheart àm thèid sinn a steach _exit_trap le argamaid epc=2148315240 (ann an deicheach):

(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

Suidhich puing briseadh gu strnlen, leanaidh sinn oirnn agus chì sinn:

(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

A rèir coltais a bhith, _exit_trap ag iarraidh fiosrachadh deasbaid a thoirt seachad mun eisgeachd a thachair, ach chan urrainn dha. Mar sin, dòigh air choireigin chan eil na stòran againn air an taisbeanadh a-rithist. set directories ../freedom-u-sdk/HiFive_U-Boot/ AIRSON! A-nis air a thaisbeanadh!

Uill, ruithidh sinn a-rithist e, agus chì sinn bhon chruach adhbhar na trioblaid thùsail a dh’ adhbhraich a’ chiad mhearachd (mcause == 5). Ma thuig mi gu ceart na tha sgrìobhte an seo air duilleag 37, tha an eisgeachd seo a’ ciallachadh Load access fault. Tha e coltach gur e sin an adhbhar an seo

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 tha an aon chiall ceàrr aige, agus a-staigh board_init_f_init_reserve tha mearachd a’ tachairt. Tha e coltach gur e seo an neach a tha ciontach: caochladair le ainm gun teagamh CONFIG_SYS_INIT_SP_ADDR. Tha e air a mhìneachadh anns an fhaidhle HiFive_U-Boot/include/configs/HiFive-U540.h. Aig àm air choreigin bha mi eadhon a ’smaoineachadh, is dòcha, uill, bu chòir dhomh boot loader a chuir ris airson a’ phròiseasar - is dòcha gum biodh e na b ’fhasa am pròiseasar a chàradh beagan? Ach an uairsin chunnaic mi gu robh e nas coltaiche ri artifact bho nach deach a chrìochnachadh gu tur#if 0- suidheachaidhean sònraichte airson rèiteachadh cuimhne eadar-dhealaichte, agus faodaidh tu feuchainn ri seo a dhèanamh:

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

Aig àm air choreigin an àireamh de chnapan-starra fasteners teicneòlach air ìre èiginneach a ruighinn. An dèidh a bhith a 'strì beagan, thàinig mi chun an fheum air a' phort ceart a dhèanamh airson mo bhòrd. Gus seo a dhèanamh, feumaidh sinn grunn fhaidhlichean a chopaigeadh agus atharrachadh a rèir ar rèiteachadh.

Uill, timcheall air, seo bòrd beag

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

Gheibhear mion-fhiosrachadh ann an tasgaidh.

Mar a thionndaidh e, air a’ bhòrd SiFive seo tha seòlaidhean eadar-dhealaichte aig clàran cuid de dh’ innealan. Thionndaidh e a-mach cuideachd gu bheil U-Boot air a rèiteachadh le bhith a ’cleachdadh an uidheamachd Kconfig, a tha eòlach mu thràth bhon kernel Linux - mar eisimpleir, faodaidh tu òrdachadh make menuconfig, agus nochdaidh eadar-aghaidh teacsa goireasach air do bheulaibh a’ sealltainn tuairisgeulan air na paramadairean le ? etc. San fharsaingeachd, às deidh dhut tuairisgeul den treas fear a chruinneachadh bho na tuairisgeulan air dà bhòrd, a ’tilgeil a-mach a h-uile seòrsa de ath-dhealbhadh PLL seòlta às an sin (a rèir coltais, tha seo ann an dòigh air choireigin ceangailte ri smachd bhon choimpiutair aoigheachd tro PCIe, ach chan eil seo cinnteach) , fhuair mi firmware, a thug, anns an aimsir cheart air Mars teachdaireachd dhomh tro UART mu cò an hash a chaidh a chuir ri chèile, agus dè an ìre de DRAM a th’ agam (ach sgrìobh mi fhìn am fiosrachadh seo anns a’ bhann-cinn).

Is e an aon truas a th ’ann, às deidh seo, mar as trice sguir am bòrd a bhith a’ freagairt tro phròiseasar JTAG, agus chan eil luchdachadh bho chairt SD, alas, luath nam rèiteachadh. Air an làimh eile, uaireannan thug BootROM teachdaireachd sin ERROR, dh’ fhàillig am bròg, agus nochd U-Boot sa bhad. B ’ann an uairsin a thàinig e a-steach orm: a rèir coltais, às deidh dha ath-thòiseachadh bitstream a-steach don FPGA, chan eil an cuimhne air a dhubhadh às, chan eil ùine aige“ gun trèanadh ”, msaa. Ann an ùine ghoirid, faodaidh tu dìreach nuair a nochdas teachdaireachd LOADING / ceangail ri debugger agus àithne set variable $pc=0x80089800, mar sin a’ dol seachad air a’ luchdachadh fhada seo (gu dearbh, leis a’ bharail gun do bhris e tràth gu leòr an turas mu dheireadh nach robh ùine aige dad a luchdachadh a bharrachd air a’ chòd thùsail).

Co-dhiù, a bheil e àbhaisteach sa chumantas gum bi am pròiseasar a’ reothadh gu tur agus nach urrainn don dì-bhugadair JTAG ceangal a dhèanamh ris le teachdaireachdan?

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

Mar sin, fuirich! Tha mi air seo fhaicinn mar-thà! Bidh rudeigin coltach ris a’ tachairt nuair a tha TileLink dùinte, agus ann an dòigh air choireigin chan eil earbsa agam ann an ùghdar rianadair na cuimhne - sgrìobh mi mi fhìn e... Gu h-obann, às deidh a’ chiad ath-thogail soirbheachail den phròiseasar às deidh dhomh an rianadair a dheasachadh, chunnaic mi:

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

Chun an loidhne neònach seo roimhe In: serial na toir aire - bha mi a’ feuchainn ri tuigsinn air pròiseasar crochte a bheil e ag obair gu ceart leis an àrainneachd. Dè tha thu a’ ciallachadh, “Tha e air a bhith crochte mar seo airson deich mionaidean”? Co-dhiù chaidh aige air gluasad agus a dhol chun chlàr bròg! Gluasad beag: eadhon ged a tha U-Boot air a luchdachadh anns a’ chiad 2 ^ 24 bytes bhon chairt SD, nuair a thòisicheas e, bidh e ga lethbhreacadh fhèin gu seòladh nas fhaide air falbh, an dàrna cuid sgrìobhte ann am bann-cinn an rèiteachaidh, no dìreach gu na seòlaidhean as àirde de RAM, agus a 'coileanadh ELF gluasad -characters, agus a' gluasad smachd an sin. Mar sin: tha e a’ coimhead coltach gun deach sinn seachad air an ìre seo agus gun d’ fhuair sinn bònas nach do chroch am pròiseasar gu teann às deidh sin.

Mar sin carson nach eil an timer ag obair? Tha e coltach nach eil an gleoc ag obair airson adhbhar air choireigin...

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

Dè ma thionndaidheas tu na saighdean le làimh?

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

An uairsin:

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

Co-dhùnadh: chan eil an gleoc a’ strì. Is dòcha gur e seo as coireach nach eil cuir a-steach meur-chlàr ag obair:

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

B’ e an duilgheadas a bh’ ann gu robh mi rud beag ro ghlic: chuir mi an iuchair ris a’ phròiseasar config:

  case DTSTimebase => BigInt(0)

stèidhichte air an fhìrinn gun tuirt am beachd “mura h-eil fios agad, fàg 0.” Agus às deidh a h-uile càil WithNBigCores Chuir mi dìreach e gu 1MHz (mar, co-dhiù, chaidh a chomharrachadh ann an config U-Boot). Ach damn, tha mi sgiobalta agus faiceallach: chan eil fhios agam an sin, seo e 25MHz! Aig a 'cheann thall, chan eil dad ag obair. Thug mi air falbh na “leasachaidhean” agam agus…

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 #

Faodaidh tu eadhon òrdughan a chuir a-steach! Mar eisimpleir, às deidh dhut beagan a dhol timcheall, faodaidh tu mu dheireadh tomhas a dhol a-steach mmc_spi 1 10000000 0; mmc part, a 'lùghdachadh tricead SPI bho 20MHz gu 10MHz. Carson? Uill, chaidh an tricead as àirde de 20MHz a sgrìobhadh anns an rèiteachadh, agus tha e fhathast sgrìobhte an sin. Ach, cho fad ‘s a tha mi a’ tuigsinn, bidh na h-eadar-aghaidh, co-dhiù an seo, ag obair mar seo: bidh an còd a ’roinn tricead an aonaid bathar-cruaidh (tha mèinn 25MHz anns a h-uile àite) leis an targaid, agus a’ suidheachadh an luach a thig às mar sgaradh anns an smachd co-fhreagarrach. clàraich. Is e an duilgheadas a th’ ann ma tha timcheall air na tha a dhìth airson UART 115200Hz, an uairsin ma roinneas tu 25000000 le 20000000 gheibh thu 1, i.e. obraichidh e aig 25MHz. Is dòcha gu bheil seo àbhaisteach, ach ma tha cuingealachaidhean air an suidheachadh, tha e a’ ciallachadh gu bheil feum aig cuideigin air (ach chan eil seo cinnteach)... San fharsaingeachd, tha e nas fhasa a chuir sìos agus gluasad air adhart - fada agus, alas, airson ùine mhòr. Chan e Core i25 a th’ ann an 9MHz.

Toradh console

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

Ceart gu leòr, tha sinn air an ath ìre a ruighinn, ach tha e reothadh fhathast. Agus uaireannan bidh e cuideachd a 'crathadh eisgeachdan. Chì thu mcause le bhith a’ feitheamh ris a’ chòd aig an t-seòladh ainmichte $pc agus an uair sin si bi air adhart trap_entry. Chan urrainn don inneal-làimhseachaidh U-Boot fhèin toradh a thoirt a-mach ach airson mcause = 0..4, mar sin dèan deiseil airson a dhol an sàs ann am bròg ceàrr. An uairsin chaidh mi a-steach don config, thòisich mi a ’coimhead air na bha mi ag atharrachadh, agus chuimhnich mi: an sin a-staigh conf/rvboot-fit.txt sgrìobhte:

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

Uill, bheir sinn a h-uile faidhle gu gèilleadh, cuir rudeigin mar seo an àite an loidhne-àithne kernel, leis gu bheil amharas ann gu bheil SIF0 - is e seo an toradh an àiteigin tro PCIe:

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

Agus atharraichidh sinn an algairim hashing bho SHA-256 gu MD5: chan eil feum agam air neart criptografach (gu sònraichte nuair a bhios mi a’ dì-bhugachadh), bheir e ùine uamhasach fada, agus airson mearachdan ionracas a ghlacadh aig àm luchdachadh, tha MD5 ro fhurasta. Dè an toradh deireannach? Thòisich sinn air an ìre roimhe a chrìochnachadh gu math nas luaithe (mar thoradh air hashing nas sìmplidh), agus dh’ fhosgail an ath fhear:

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

Ach chan eil an uaireadair a’ tic...

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

Oops, tha e coltach gur e placebo a bh’ ann a bhith a’ ceartachadh a’ ghleoc, ged a bha e coltach riumsa aig an àm gun do chuidich e. Chan eil, gu dearbh feumar a shuidheachadh, ach tionndaidhidh sinn na saighdean le làimh an toiseach agus faic dè thachras:

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.

Aig an aon àm…

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

Chan e, thèid mi an gleoc gu fèin-ghluasadach - air neo is dòcha gun co-dhùin e an timer a chalpachadh an sin!

Aig an aon àm, tha seòladh an stiùiridh gnàthach a’ comharrachadh àiteigin a-staigh

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>

taobh a-staigh an Berkeley Boot Loader luchdaichte. Gu pearsanta, is e an rud a tha a’ cur dragh orm mu dheidhinn seo an iomradh htif - eadar-aghaidh aoigheachd air a chleachdadh airson an kernel a chuir air bhog (is e sin, ann an co-obrachadh leis an aoigheachd ARM), ghabh mi ris leis fhèin. Ach, ma lorgas tu an gnìomh seo sa chòd stòr, chì thu nach eil a h-uile dad cho dona:

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

Quest: tòisich an uaireadair

Le bhith a’ lorg chlàran ann an CLINT tha sinn gar toirt gu

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

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

A tha a’ ceangal ri RTC, no ris an MockAON dìomhair, air an do smaoinich mi an toiseach: “Mar sin, dè a th’ againn an seo? Neo-shoilleir? Nach cuir sinn dheth e!" Leis nach eil mi fhathast a’ tuigsinn dè an seòrsa draoidheachd gleoc a tha a’ dol an sin, mar sin cuiridh mi an reusanachadh seo an sàs. 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
  }

A’ dèanamh ar slighe gu kernel Linux

An seo tha an sgeulachd air a dhol air adhart mu thràth agus air fàs beagan monotonous, agus mar sin bheir mi cunntas air bho mhullach gu bonn:

Ghabh BBL ris gu robh FDT an làthair aig 0xF0000000, ach tha mi air a cheartachadh mu thràth! Uill, leig dhuinn coimhead a-rithist ... Lorg a-steach e HiFive_U-Boot/arch/riscv/lib/boot.c, air a chur na àite 0x81F00000, air a shònrachadh ann an rèiteachadh boot U-Boot.

An uairsin ghearain BBL nach robh cuimhne sam bith ann. Bha mo shlighe na laighe anns a 'ghnìomh mem_prop, dè a-staigh riscv-pk/machine/fdt.c: às an sin dh'ionnsaich mi gum feum thu an nód fdt ram a chomharrachadh mar device_type = "memory" - an uairsin, is dòcha, feumar gineadair pròiseasar a cheartachadh, ach airson a-nis bidh mi dìreach ga sgrìobhadh le làimh - co-dhiù, ghluais mi am faidhle seo le làimh.

A-nis fhuair mi am brath (air a sholarachadh ann an cruth cruth, le tilleadh carbaid):

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.

Tha e coltach gu bheil na roghainnean air an comharrachadh mar a tha feum riscv,kernel-start и riscv,kernel-end ann an DTB, ach tha neamhan air am parsadh. Debugging query_chosen sheall e gu bheil BBL a’ feuchainn ri seòladh 32-bit a pharsadh, ach tha e a’ tighinn tarsainn air paidhir <0x0 0xADDR>, agus tha e coltach gur e a’ chiad luach na pìosan as cudromaiche. Air a chur ris an roinn chosen

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

agus cheartaich e ginealach nan luachan: na cuir 0x0 a' chiad eileamaid.

Nì na 100500 ceum sìmplidh seo e furasta sùil a thoirt air penguin a’ tuiteam:

Teacs falaichte

   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)

(tha an suaicheantas air a thaisbeanadh le BBL, agus tha am fear le stampaichean-ama air a thaisbeanadh leis an kernel).

Gu fortanach, chan eil fhios agam ciamar a tha e anns a h-uile àite, ach air RocketChip, nuair a cheanglas tu dì-bhugadair tro JTAG, gheibh thu ribeachan a-mach às a’ bhogsa - stadaidh an debugger aig an ìre seo.

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

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

Mar a thuirt an sean-f hocal, Cha deach CPU a lorg, a' ruith aithris bathar-bog. Uill, no gun a bhith a 'ruith. Air chall ann an aon chridhe pròiseasar.

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

Deagh bheachd a-steach linux/arch/riscv/kernel/setup.c - seòrsa de pheantadh de fheansa a’ cleachdadh modh Tom Sawyer. San fharsaingeachd, airson adhbhar air choireigin cha robh buannaichean ann an-diugh, thèid an duais a ghluasad chun ath tharraing ...

An seo tha mi a’ moladh crìoch a chuir air an artaigil a tha fada mar-thà.

Ri leantainn. Bidh sabaid ann le biast seòlta a thèid air falach ma dh’ èireas tu suas air le aon cheum.

Screencast luchdachadh sìos teacsa (ceangal taobh a-muigh):
Pàirt 3: Cha mhòr a 'luchdachadh Linux bho chairt SD gu RocketChip

Source: www.habr.com

Cuir beachd ann