Π§Π°ΡΡ‚ΡŒ 3: ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ‡Ρ‚ΠΎ Π³Ρ€ΡƒΠ·ΠΈΠΌ Linux с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° RocketChip

Π§Π°ΡΡ‚ΡŒ 3: ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ‡Ρ‚ΠΎ Π³Ρ€ΡƒΠ·ΠΈΠΌ Linux с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° RocketChip Π’ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ части Π±Ρ‹Π» Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π±ΠΎΠ»Π΅Π΅-ΠΌΠ΅Π½Π΅Π΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ памяти, Π° Ρ‚ΠΎΡ‡Π½Π΅Π΅ β€” ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° Π½Π°Π΄ IP Core ΠΈΠ· Quartus, ΡΠ²Π»ΡΡŽΡ‰Π°ΡΡΡ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π½ΠΈΠΊΠΎΠΌ Π½Π° TileLink. БСгодня ΠΆΠ΅ Π² Ρ€ΡƒΠ±Ρ€ΠΈΠΊΠ΅ Β«ΠŸΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ RocketChip Π½Π° ΠΌΠ°Π»ΠΎΠΈΠ·Π²Π΅ΡΡ‚Π½ΡƒΡŽ ΠΊΠΈΡ‚Π°ΠΉΡΠΊΡƒΡŽ ΠΏΠ»Π°Ρ‚Ρƒ с Π¦ΠΈΠΊΠ»ΠΎΠ½ΠΎΠΌΒ» Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΡƒΡŽ консоль. ΠŸΡ€ΠΎΡ†Π΅ΡΡ нСсколько затянулся: я ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΎ Π΄ΡƒΠΌΠ°Π», Ρ‡Ρ‚ΠΎ сСйчас ΠΏΠΎ-быстрому Π·Π°ΠΏΡƒΡ‰Ρƒ Linux, ΠΈ ΠΏΠΎΠΉΠ΄Ρ‘ΠΌ дальшС, Π½ΠΎ Π½Π΅ Ρ‚ΡƒΡ‚ Ρ‚ΠΎ Π±Ρ‹Π»ΠΎ. Π’ этой части ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° процСсс запуска U-Boot, BBL, ΠΈ Ρ€ΠΎΠ±ΠΊΠΈΠ΅ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ Linux kernel ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ. Но консоль Π΅ΡΡ‚ΡŒ β€” U-Boot-овская, ΠΈ довольно-Ρ‚Π°ΠΊΠΈ продвинутая, ΠΈΠΌΠ΅ΡŽΡ‰Π°Ρ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ ΠΈΠ· Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚Π΅ ΠΎΡ‚ ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½ΠΎΠΉ консоли.

Π’ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠΉ части добавится SD-ΠΊΠ°Ρ€Ρ‚Π°, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½Π°Ρ ΠΏΠΎ интСрфСйсу SPI, Π° Ρ‚Π°ΠΊΠΆΠ΅ UART. Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΉ части BootROM Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΌΠ΅Π½Ρ‘Π½ с xip Π½Π° sdboot ΠΈ, собствСнно, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ стадии Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ (Π½Π° SD-ΠΊΠ°Ρ€Ρ‚Π΅).

Π”ΠΎΠΏΠΈΠ»ΠΈΠ²Π°Π½ΠΈΠ΅ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠΉ части

Π˜Ρ‚Π°ΠΊ, Π·Π°Π΄Π°Ρ‡Π°: Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π½Π° «большоС» ядро ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ UART (ΠΎΡ‚ Raspberry) ΠΈ SD-Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ (использовалась нСкая ΠΏΠ»Π°Ρ‚ΠΊΠ° ΠΎΡ‚ Catalex с ΡˆΠ΅ΡΡ‚ΡŒΡŽ ΠΏΠΈΠ½Π°ΠΌΠΈ: GND, VCC, MISO, MOSI, SCK, CS).

Π’ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅, всё Π±Ρ‹Π»ΠΎ довольно просто. Но ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ это ΠΎΡΠΎΠ·Π½Π°Ρ‚ΡŒ, мСня Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ побросало ΠΈΠ· стороны Π² сторону: послС ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Ρ€Π°Π·Π° я Ρ€Π΅ΡˆΠΈΠ», Ρ‡Ρ‚ΠΎ снова Π½ΡƒΠΆΠ½ΠΎ просто ΠΏΠΎΠ΄ΠΌΠ΅ΡˆΠ°Ρ‚ΡŒ Π² System Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π²Ρ€ΠΎΠ΄Π΅ HasPeripheryUART (ΠΈ Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ соотвСтствСнно), Ρ‚ΠΎ ΠΆΠ΅ для SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ β€” ΠΈ всё Π±ΡƒΠ΄Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ²ΠΎ. ΠŸΠΎΡ‚ΠΎΠΌ я Ρ€Π΅ΡˆΠΈΠ» ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, Π° ΠΊΠ°ΠΊ ΠΆΠ΅ ΠΎΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ Π² Β«ΡΠ΅Ρ€ΡŒΡ‘Π·Π½ΠΎΠΌΒ» Π΄ΠΈΠ·Π°ΠΉΠ½Π΅. Π’Π°ΠΊ, Ρ‡Ρ‚ΠΎ Ρƒ нас Ρ‚ΡƒΡ‚ ΠΈΠ· ΡΠ΅Ρ€ΡŒΡ‘Π·Π½ΠΎΠ³ΠΎ? Arty, Π²ΠΈΠ΄ΠΈΠΌΠΎ, Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ β€” остаётся монстр unleahshed.DevKitConfigs. И Π²Π΄Ρ€ΡƒΠ³ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ»ΠΎΡΡŒ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΌ ΠΏΠΎΠ²ΡΡŽΠ΄Ρƒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΠΎΠ²Π΅Ρ€Π»Π΅ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π°ΠΌ. Π― Π΄ΠΎΠ³Π°Π΄Ρ‹Π²Π°ΡŽΡΡŒ, Ρ‡Ρ‚ΠΎ это, Π½Π°Π²Π΅Ρ€Π½ΠΎΠ΅, ΠΎΡ‡Π΅Π½ΡŒ Π³ΠΈΠ±ΠΊΠΎ ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎ, Π½ΠΎ ΠΌΠ½Π΅ Π±Ρ‹ Ρ…ΠΎΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ для Π½Π°Ρ‡Π°Π»Π° Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒβ€¦ А Ρƒ вас Π½Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΆΠ΅, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠΏΡ€ΠΎΡ‰Π΅-ΠΏΠΎΠΊΠΎΡΡ‚Ρ‹Π»ΡŒΠ½Π΅Π΅?.. Π’ΡƒΡ‚-Ρ‚ΠΎ я ΠΈ наткнулся Π½Π° vera.iofpga.FPGAChip для ΠŸΠ›Π˜Π‘ Microsemi ΠΈ Ρ‚ΡƒΡ‚ ΠΆΠ΅ растащил Π½Π° Ρ†ΠΈΡ‚Π°Ρ‚Ρ‹ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Π» ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ, Π±Π»Π°Π³ΠΎ Ρ‚ΡƒΡ‚ Π±ΠΎΠ»Π΅Π΅-ΠΌΠ΅Π½Π΅Π΅ вся Β«Ρ€Π°Π·Π²ΠΎΠ΄ΠΊΠ° систСмной ΠΏΠ»Π°Ρ‚Ρ‹Β» Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅.

Оказалось, Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π½ΡƒΠΆΠ½ΠΎ просто Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² System.scala строчки

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

Π‘Ρ‚Ρ€ΠΎΡ‡ΠΊΠ° Π² Ρ‚Π΅Π»Π΅ класса System добавляСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ частотС, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ эта Ρ‡Π°ΡΡ‚ΡŒ нашСго SoC, Π² dts-Ρ„Π°ΠΉΠ». Насколько я понимаю, DTS/DTB β€” это Ρ‚Π°ΠΊΠΎΠΉ статичный Π°Π½Π°Π»ΠΎΠ³ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ plug-and-play для встраиваСмых устройств: Π΄Π΅Ρ€Π΅Π²ΠΎ dts-описания компилируСтся Π² Π±ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ dtb-Ρ„Π°ΠΉΠ» ΠΈ пСрСдаётся Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠΎΠΌ ядру, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΎ ΠΌΠΎΠ³Π»ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚ΡƒΡ€Ρƒ. Π§Ρ‚ΠΎ интСрСсно, Π±Π΅Π· строчки с tlclock всё прСкрасно синтСзируСтся, Π½ΠΎ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ BootROM (напомню, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ это Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠΆΠ΅ sdboot) Π½Π΅ получится β€” Π² процСссС компиляции ΠΎΠ½ парсит dts-Ρ„Π°ΠΉΠ» ΠΈ создаёт Ρ…Π΅Π΄Π΅Ρ€ с макросом TL_CLK, благодаря ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ½ смоТСт ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΠΈ частоты для Π²Π½Π΅ΡˆΠ½ΠΈΡ… интСрфСйсов.

Π’Π°ΠΊΠΆΠ΅ потрСбуСтся Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Β«Ρ€Π°Π·Π²ΠΎΠ΄ΠΊΡƒΒ»:

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
}

Π¦Π΅ΠΏΠΎΡ‡ΠΊΠΈ рСгистров, чСстно говоря, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ просто ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ мСстами ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. Π‘ΠΊΠΎΡ€Π΅Π΅ всСго, ΠΎΠ½ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°Ρ‰ΠΈΡ‰Π°Ρ‚ΡŒ ΠΎΡ‚ ΠΌΠ΅Ρ‚Π°ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±Π»ΠΎΠΊΠ°Ρ… ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ своя Π·Π°Ρ‰ΠΈΡ‚Π°, Π½ΠΎ для Π½Π°Ρ‡Π°Π»Π° хочСтся Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ хотя Π±Ρ‹ Β«Π½Π° качСствСнном ΡƒΡ€ΠΎΠ²Π½Π΅Β». Π‘ΠΎΠ»Π΅Π΅ интСрСсный для мСня вопрос β€” ΠΏΠΎΡ‡Π΅ΠΌΡƒ MISO ΠΈ MOSI висят Π½Π° Ρ€Π°Π·Π½Ρ‹Ρ… dq? ΠžΡ‚Π²Π΅Ρ‚Π° я ΠΏΠΎΠΊΠ° Ρ‚Π°ΠΊ ΠΈ Π½Π΅ Π½Π°ΡˆΡ‘Π», Π½ΠΎ, ΠΏΠΎΡ…ΠΎΠΆΠ΅, ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ ΠΊΠΎΠ΄ рассчитываСт ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π° Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.

ЀизичСски, я просто Π½Π°Π·Π½Π°Ρ‡ΠΈΠ» Π²Ρ‹Π²ΠΎΠ΄Ρ‹ Π΄ΠΈΠ·Π°ΠΉΠ½Π° Π½Π° свободныС ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚Ρ‹ Π½Π° ΠΊΠΎΠ»ΠΎΠ΄ΠΊΠ΅ ΠΈ пСрСставил Π΄ΠΆΠ°ΠΌΠΏΠ΅Ρ€ Π²Ρ‹Π±ΠΎΡ€Π° напряТСния Π² 3.3V.

SD-Π°Π΄Π°ΠΏΡ‚Π΅Ρ€

Π’ΠΈΠ΄ свСрху:

Π§Π°ΡΡ‚ΡŒ 3: ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ‡Ρ‚ΠΎ Π³Ρ€ΡƒΠ·ΠΈΠΌ Linux с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° RocketChip

Π’ΠΈΠ΄ снизу:

Π§Π°ΡΡ‚ΡŒ 3: ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ‡Ρ‚ΠΎ Π³Ρ€ΡƒΠ·ΠΈΠΌ Linux с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° RocketChip

ΠžΡ‚Π»Π°Π΄ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΉ части: инструмСнты

Для Π½Π°Ρ‡Π°Π»Π° ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎΠ± ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ инструмСнтах ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ ΠΈ ΠΈΡ… ограничСниях.

Minicom

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π½Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π½ΡƒΠΆΠ½ΠΎ ΠΊΠ°ΠΊ-Ρ‚ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊ ΠΈ ядро. Для этого Π½Π° Linux (Π² Π΄Π°Π½Π½ΠΎΠΌ случаС β€” Π½Π° Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π° RaspberryPi) Π½Π°ΠΌ потрСбуСтся ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Minicom. Π’ΠΎΠΎΠ±Ρ‰Π΅ говоря, ΠΏΠΎΠ΄ΠΎΠΉΠ΄Ρ‘Ρ‚ любая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ ΠΏΠΎΡ€Ρ‚ΠΎΠΌ.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ запускС имя устройства ΠΏΠΎΡ€Ρ‚Π° Π½ΡƒΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ -D /dev/ttyS0 β€” послС ΠΎΠΏΡ†ΠΈΠΈ -D. Ну ΠΈ главная информация: для Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Ctrl-A, X. Π£ мСня ΠΏΡ€Π°Π²Π΄Π° Π±Ρ‹Π» случай, ΠΊΠΎΠ³Π΄Π° эта комбинация Π½Π΅ сработала β€” Ρ‚ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ· сосСднСго сСанса SSH просто ΡΠΊΠ°Π·Π°Ρ‚ΡŒ killall -KILL minicom.

Π•ΡΡ‚ΡŒ ΠΈ Π΅Ρ‰Ρ‘ ΠΎΠ΄Π½Π° ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ. ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ Π½Π° RaspberryPi Π΅ΡΡ‚ΡŒ Π΄Π²Π° UART, ΠΈ ΠΎΠ±Π° ΠΏΠΎΡ€Ρ‚Π° ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΆΠ΅ для Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ приспособлСны: ΠΎΠ΄ΠΈΠ½ для Bluetooth, Ρ‡Π΅Ρ€Π΅Π· Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ выводится консоль ядра. К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, это ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΠΎ этому ΠΌΠ°Π½ΡƒΠ°Π»Ρƒ.

ΠŸΠ΅Ρ€Π΅ΠΏΠΈΡΡ‹Π²Π°Π½ΠΈΠ΅ памяти

ΠŸΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅, для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π³ΠΈΠΏΠΎΡ‚Π΅Π·Ρ‹ ΠΌΠ½Π΅ ΠΈΠ½ΠΎΠ³Π΄Π° ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊ (ΠΈΠ·Π²ΠΈΠ½ΠΈΡ‚Π΅) Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ нСпосрСдствСнно с хоста. ΠœΠΎΠΆΠ΅Ρ‚, это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ прямо ΠΈΠ· GDB, Π½ΠΎ я Π² ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΠΎΡˆΡ‘Π» ΠΏΠΎ простому ΠΏΡƒΡ‚ΠΈ: скопировал Π½Π° Raspberry Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ Ρ„Π°ΠΉΠ», пробросил Ρ‡Π΅Ρ€Π΅Π· SSH Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΡ€Ρ‚ 4444 (telnet ΠΎΡ‚ OpenOCD) ΠΈ воспользовался ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ load_image. Когда Π²Ρ‹ Π΅Ρ‘ выполняСтС, каТСтся Ρ‡Ρ‚ΠΎ всё зависло, Π½ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ Β«ΠΎΠ½ΠΎ Π½Π΅ спит, ΠΎΠ½ΠΎ просто ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΌΠΎΡ€Π³Π°Π΅Ρ‚Β»: ΠΎΠ½ΠΎ Π³Ρ€ΡƒΠ·ΠΈΡ‚ Ρ„Π°ΠΉΠ», просто Π΄Π΅Π»Π°Π΅Ρ‚ это со ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ ΠΏΠ°Ρ€Ρƒ ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ‚ Π² сСкунду.

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ установки breakpoint-ΠΎΠ²

ВСроятно, ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΎΠ± этом Π½Π΅ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ Π·Π°Π΄ΡƒΠΌΡ‹Π²Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Π½ΠΎ Ρ‚ΠΎΡ‡ΠΊΠΈ останова Π½Π΅ всСгда ставятся Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎ. Иногда постановка breakpoint-Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΌ записывании ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ инструкции Π² Π½ΡƒΠΆΠ½ΠΎΠ΅ мСсто прямо Π² ΠΌΠ°ΡˆΠΈΠ½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄. НапримСр, Ρ‚Π°ΠΊ Ρƒ мСня дСйствовала стандартная ΠΊΠΎΠΌΠ°Π½Π΄Π° b Π² GDB. Π’ΠΎΡ‚, Ρ‡Ρ‚ΠΎ ΠΈΠ· этого слСдуСт:

  • нСльзя ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΎΡ‡ΠΊΡƒ Π²Π½ΡƒΡ‚Ρ€ΠΈ BootROM, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ROM
  • ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΎΡ‡ΠΊΡƒ останова Π½Π° ΠΊΠΎΠ΄, Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹ΠΉ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²ΠΊΡƒ с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹, ΠΌΠΎΠΆΠ½ΠΎ, Π½ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π½Π΅ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅ΠΌ кусочСк ΠΊΠΎΠ΄Π°, Π° Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅Ρ‚ наш breakpoint

Π£Π²Π΅Ρ€Π΅Π½, ΠΌΠΎΠΆΠ½ΠΎ явно ΠΏΠΎΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½Ρ‹Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ останова, Π½ΠΎ ΠΈΡ… Π² любом случаС ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠ΅ число.

Быстрая ΠΏΠΎΠ΄ΠΌΠ΅Π½Π° BootROM

На Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌ этапС ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ Π½Π΅Ρ€Π΅Π΄ΠΊΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ BootROM ΠΈ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π΅Ρ‰Ρ‘ Ρ€Π°Π·ΠΎΠΊ. Но Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°: BootROM являСтся Ρ‡Π°ΡΡ‚ΡŒΡŽ Π΄ΠΈΠ·Π°ΠΉΠ½Π°, Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ Π² ΠŸΠ›Π˜Π‘, Π° Π΅Π³ΠΎ синтСз β€” Π΄Π΅Π»ΠΎ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΌΠΈΠ½ΡƒΡ‚ (ΠΈ это-Ρ‚ΠΎ послС ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΌΠ³Π½ΠΎΠ²Π΅Π½Π½ΠΎΠΉ компиляции самого ΠΎΠ±Ρ€Π°Π·Π° BootROM ΠΈΠ· C ΠΈ Assembler…). К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, Π½Π° самом Π΄Π΅Π»Π΅ всё Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ быстрСС: ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ дСйствий такая:

  • ΠΏΠ΅Ρ€Π΅Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ bootrom.mif (я ΠΏΠ΅Ρ€Π΅ΡˆΡ‘Π» Π½Π° MIF вмСсто HEX, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ с HEX Ρƒ мСня Π²Π΅Ρ‡Π½ΠΎ Π±Ρ‹Π»ΠΈ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Π° MIF β€” Ρ€ΠΎΠ΄Π½ΠΎΠΉ ΠΠ»ΡŒΡ‚Π΅Ρ€ΠΎΠ²ΡΠΊΠΈΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚)
  • Π² Quartus ΡΠΊΠ°Π·Π°Ρ‚ΡŒ Processing -> Update Memory Initialization File
  • Π½Π° ΠΏΡƒΠ½ΠΊΡ‚Π΅ Assembler (Π² Π»Π΅Π²ΠΎΠΉ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ΅ Tasks) ΡΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠ²Π°Ρ‚ΡŒ Start again

На всё ΠΏΡ€ΠΎ всё β€” ΠΏΠ°Ρ€Π° дСсятков сСкунд.

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° SD-ΠΊΠ°Ρ€Ρ‚Ρ‹

Π’ΡƒΡ‚ всё ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ просто, Π½ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΠ°ΡΡ‚ΠΈΡΡŒ Ρ‚Π΅Ρ€ΠΏΠ΅Π½ΠΈΠ΅ΠΌ ΠΈ ΠΎΠΊΠΎΠ»ΠΎ 14Gb мСста Π½Π° дискС:

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

ПослС Ρ‡Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‡ΠΈΡΡ‚ΡƒΡŽ, Π° Ρ‚ΠΎΡ‡Π½Π΅Π΅, Π½Π΅ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ, SD-ΠΊΠ°Ρ€Ρ‚Ρƒ, ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ

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

… Π³Π΄Π΅ sdX β€” устройство, Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½ΠΎΠ΅ ΠΊΠ°Ρ€Ρ‚Π΅. Π’ΠΠ˜ΠœΠΠΠ˜Π•: Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° ΠΊΠ°Ρ€Ρ‚Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹, пСрСзаписаны ΠΈ Π²ΠΎΠΎΠ±Ρ‰Π΅! Вряд Π»ΠΈ стоит Π΄Π΅Π»Π°Ρ‚ΡŒ всю сборку ΠΈΠ·-ΠΏΠΎΠ΄ sudo, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠ³Π΄Π° всС Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ сборки Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ΡŒ root, ΠΈ сборку придётся Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΈΠ·-ΠΏΠΎΠ΄ sudo постоянно.

Π’ ΠΈΡ‚ΠΎΠ³Π΅ получаСтся ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠ°, размСчСнная Π² GPT с Ρ‡Π΅Ρ‚Ρ‹Ρ€ΡŒΠΌΡ Ρ€Π°Π·Π΄Π΅Π»Π°ΠΌΠΈ, Π½Π° ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… FAT с uEnv.txt ΠΈ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ FIT (ΠΎΠ½ содСрТит нСсколько ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Π·ΠΎΠ², ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ со своим адрСсом Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ), Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ€Π°Π·Π΄Π΅Π» β€” чистый, Π΅Π³ΠΎ прСдполагаСтся ΠΎΡ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Ext4 для Линукса. Π•Ρ‰Ρ‘ Π΄Π²Π° Ρ€Π°Π·Π΄Π΅Π»Π° β€” Π·Π°Π³Π°Π΄ΠΎΡ‡Π½Ρ‹Π΅: Π½Π° ΠΎΠ΄Π½ΠΎΠΌ ΠΆΠΈΠ²Ρ‘Ρ‚ U-Boot (Π΅Π³ΠΎ смСщСниС, насколько я понимаю, Π·Π°ΡˆΠΈΡ‚ΠΎ Π² BootROM), Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΌ, ΠΏΠΎΡ…ΠΎΠΆΠ΅, ΠΆΠΈΠ²ΡƒΡ‚ Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния, Π½ΠΎ я ΠΈΡ… ΠΏΠΎΠΊΠ° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ.

Π£Ρ€ΠΎΠ²Π΅Π½ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ, BootROM

Народная ΠΌΡƒΠ΄Ρ€ΠΎΡΡ‚ΡŒ гласит: «Если Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π±Ρ‹Π²Π°ΡŽΡ‚ пляски с Π±ΡƒΠ±Π½ΠΎΠΌ, Ρ‚ΠΎ Π² элСктроникС β€” Π΅Ρ‰Ρ‘ ΠΈ с ΠΎΠ³Π½Π΅Ρ‚ΡƒΡˆΠΈΡ‚Π΅Π»Π΅ΠΌΒ». Π Π΅Ρ‡ΡŒ Π΄Π°ΠΆΠ΅ Π½Π΅ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· я Ρ‡ΡƒΡ‚ΡŒ Π½Π΅ спалил ΠΏΠ»Π°Ρ‚Ρƒ, Ρ€Π΅ΡˆΠΈΠ², Ρ‡Ρ‚ΠΎ «Ну GND β€” это ΠΆΠ΅ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Π½ΠΈΠ·ΠΊΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒΒ» (Π²ΠΈΠ΄ΠΈΠΌΠΎ, рСзистор всё-Ρ‚Π°ΠΊΠΈ Π½Π΅ помСшал Π±Ρ‹…) Π Π΅Ρ‡ΡŒ скорСС ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ссли Ρ€ΡƒΠΊΠΈ растут Π½Π΅ ΠΎΡ‚Ρ‚ΡƒΠ΄Π°, Ρ‚ΠΎ элСктроника Π½Π΅ пСрСстаёт ΠΏΡ€ΠΈΠ½ΠΎΡΠΈΡ‚ΡŒ ΡΡŽΡ€ΠΏΡ€ΠΈΠ·Ρ‹: припаивая Ρ€Π°Π·ΡŠΡ‘ΠΌ Π½Π° ΠΏΠ»Π°Ρ‚Ρƒ, я Ρ‚Π°ΠΊ ΠΈ Π½Π΅ сумСл Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΎΠΏΠ°ΡΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚Ρ‹ β€” Π½Π° Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚, ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠΏΠΎΠΉ прямо сам растСкаСтся ΠΏΠΎ всСму соСдинСнию, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ паяльник ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈ, Ρƒ мСня ΠΆΠ΅ ΠΎΠ½ Β«Π½Π°ΡˆΠ»Ρ‘ΠΏΡ‹Π²Π°Π»ΡΡΒ» ΠΊΠ°ΠΊ ΠΏΠΎΠΏΠ°Π»ΠΎ. Ну, ΠΌΠΎΠΆΠ΅Ρ‚, ΠΏΡ€ΠΈΠΏΠΎΠΉ Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΠ» для Ρ‚Π΅ΠΌΠΏΠ΅Ρ€Π°Ρ‚ΡƒΡ€Ρ‹ паяльника, ΠΌΠΎΠΆΠ΅Ρ‚, Π΅Ρ‰Ρ‘ что… Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, ΡƒΠ²ΠΈΠ΄Π΅Π², Ρ‡Ρ‚ΠΎ дСсяток ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚ΠΎΠ² Ρƒ мСня ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ, я ΠΏΠ»ΡŽΠ½ΡƒΠ», ΠΈ Π½Π°Ρ‡Π°Π» ΠΎΡ‚Π»Π°ΠΆΠΈΠ²Π°Ρ‚ΡŒ. И Ρ‚ΡƒΡ‚ Π½Π°Ρ‡Π°Π»ΠΎΡΡŒ Π·Π°Π³Π°Π΄ΠΎΡ‡Π½ΠΎΠ΅: ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ» RX/TX ΠΎΡ‚ UART-Π°, Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΡƒ β€” ΠΎΠ½ΠΎ ΠΏΠΈΡˆΠ΅Ρ‚

INIT
CMD0
ERROR

Ну, всё Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒ SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ я Π½Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ». Π˜ΡΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ, Π³Ρ€ΡƒΠ·ΠΈΠΌ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΡƒβ€¦ И Ρ‚ΠΈΡˆΠΈΠ½Π°β€¦ Π§Π΅Π³ΠΎ я Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄ΡƒΠΌΠ°Π», Π° Π»Π°Ρ€Ρ‡ΠΈΠΊ-Ρ‚ΠΎ просто открывался: ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π²Ρ‹Π²ΠΎΠ΄ΠΎΠ² модуля Π½ΡƒΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π½Π° VCC. Π’ ΠΌΠΎΡ‘ΠΌ случаС ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π» 5V для питания, поэтому я, Π½Π΅Π΄ΠΎΠ»Π³ΠΎ думая, Π²ΠΎΡ‚ΠΊΠ½ΡƒΠ» ΠΏΡ€ΠΎΠ²ΠΎΠ΄, Ρ‚ΡΠ½ΡƒΠ²ΡˆΠΈΠΉΡΡ ΠΎΡ‚ модуля, Π½Π° ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΡƒΡŽ сторону ΠΏΠ»Π°Ρ‚Ρ‹. Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΊΡ€ΠΈΠ²ΠΎ пропаянный Ρ€Π°Π·ΡŠΡ‘ΠΌ пСрСкосился, ΠΈ просто потСрялся ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚ UART. facepalm.jpg Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, «дурная Π³ΠΎΠ»ΠΎΠ²Π° Π½ΠΎΠ³Π°ΠΌ покоя Π½Π΅ Π΄Π°Ρ‘Ρ‚Β», Π° ΠΊΡ€ΠΈΠ²Ρ‹Π΅ Ρ€ΡƒΠΊΠΈ β€” Π³ΠΎΠ»ΠΎΠ²Π΅…

Π’ ΠΈΡ‚ΠΎΠ³Π΅ я ΡƒΠ²ΠΈΠ΄ΠΈΠ» Π² Minicom Π΄ΠΎΠ»Π³ΠΎΠΆΠ΄Π°Π½Π½ΠΎΠ΅

INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING /

Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, ΠΎΠ½ΠΎ ΡˆΠ΅Π²Π΅Π»ΠΈΡ‚ΡΡ крутится ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. ΠŸΡ€ΡΠΌΠΎ Π²ΡΠΏΠΎΠΌΠΈΠ½Π°ΡŽΡ‚ΡΡ ΡˆΠΊΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π³ΠΎΠ΄Ρ‹ ΠΈ нСспСшная Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° MinuetOS с дискСты. Π Π°Π·Π²Π΅ Ρ‡Ρ‚ΠΎ дисковод Π½Π΅ скрСТСщСт.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ послС сообщСния BOOT Π½Π΅ происходит Π½ΠΈΡ‡Π΅Π³ΠΎ. Π—Π½Π°Ρ‡ΠΈΡ‚, самоС врСмя ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ Ρ‡Π΅Ρ€Π΅Π· OpenOCD Π½Π° Raspberry, ΠΊ Π½Π΅ΠΌΡƒ GDB Π½Π° хостС, ΠΈ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΆΠ΅ это Ρ‚Π°ΠΊΠΎΠ΅.

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ GDB Ρ‚ΡƒΡ‚ ΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π»ΠΎ, Ρ‡Ρ‚ΠΎ $pc (program counter, адрСс Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ инструкции) ΡƒΠ»Π΅Ρ‚Π°Π΅Ρ‚ Π² 0x0 β€” вСроятно, это происходит послС мноТСствСнной ошибки. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ, сразу послС Π²Ρ‹Π΄Π°Ρ‡ΠΈ сообщСния BOOT Π΄ΠΎΠ±Π°Π²ΠΈΠΌ бСсконСчный Ρ†ΠΈΠΊΠ». Π­Ρ‚ΠΎ Π΅Π³ΠΎ Π½Π΅Π½Π°Π΄ΠΎΠ»Π³ΠΎ Π·Π°Π΄Π΅Ρ€ΠΆΠΈΡ‚…

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

Π’Π°ΠΊΠΎΠΉ Ρ…ΠΈΡ‚Ρ€Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ «для надёТности»: я Π³Π΄Π΅-Ρ‚ΠΎ ΡΠ»Ρ‹ΡˆΠ°Π», Ρ‡Ρ‚ΠΎ, Π²Ρ€ΠΎΠ΄Π΅ Π±Ρ‹, бСсконСчный Ρ†ΠΈΠΊΠ» β€” это Undefined Behavior, Π° Ρ‚ΡƒΡ‚ компилятор вряд Π»ΠΈ догадаСтся (Напоминаю, Ρ‡Ρ‚ΠΎ ΠΏΠΎ 0x10000 находится BootROM).

Π§Π°ΡΡ‚ΡŒ 3: ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ‡Ρ‚ΠΎ Π³Ρ€ΡƒΠ·ΠΈΠΌ Linux с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° RocketChip

Казалось Π±Ρ‹, Π° Ρ‡Ρ‚ΠΎ Π΅Ρ‰Ρ‘ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ β€” суровый embedded, ΠΊΠ°ΠΊΠΈΠ΅ ΡƒΠΆ Ρ‚ΡƒΡ‚ исходники. Но вСдь Π² Ρ‚ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ Π°Π²Ρ‚ΠΎΡ€ ΠΎΡ‚Π»Π°ΠΆΠΈΠ²Π°Π» ΡΠΈΡˆΠ½Ρ‹ΠΉ код… ΠšΡ€Π΅ΠΊΡ-фСкс-пСкс:

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

Π§Π°ΡΡ‚ΡŒ 3: ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ‡Ρ‚ΠΎ Π³Ρ€ΡƒΠ·ΠΈΠΌ Linux с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° RocketChip

Волько Π½ΡƒΠΆΠ½ΠΎ Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Π½Π΅ MIF-Ρ„Π°ΠΉΠ» ΠΈ Π½Π΅ bin, Π° ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ELF.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ с энной ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ ΡƒΠ³Π°Π΄Π°Ρ‚ΡŒ адрСс, Π³Π΄Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ продолТится (это Π΅Ρ‰Ρ‘ ΠΎΠ΄Π½Π° ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎΡ‡Π΅ΠΌΡƒ компилятор Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Π» Π΄ΠΎΠ³Π°Π΄Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Ρ†ΠΈΠΊΠ» β€” бСсконСчный). Команда

set variable $pc=0xADDR

позволяСт ΠΏΠΎΠΌΠ΅Π½ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ рСгистра Π½Π° Ρ…ΠΎΠ΄Ρƒ (Π² Π΄Π°Π½Π½ΠΎΠΌ случаС β€” адрСс Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ инструкции). Π‘ Π΅Ρ‘ ΠΆΠ΅ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΌΠ΅Π½ΡΡ‚ΡŒ значСния, записанныС Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ (ΠΈ memory-mapped рСгистры).

Π’ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ ΠΈΡ‚ΠΎΠ³Π΅ я ΠΏΡ€ΠΈΡˆΡ‘Π» ΠΊ Π²Ρ‹Π²ΠΎΠ΄Ρƒ (Π½Π΅ ΡƒΠ²Π΅Ρ€Π΅Π½, Ρ‡Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌΡƒ), Ρ‡Ρ‚ΠΎ Ρƒ нас Β«ΠΎΠ±Ρ€Π°Π· sd-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π΅ Ρ‚ΠΎΠΉ систСмы», ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π½ΡƒΠΆΠ½ΠΎ Π½Π΅ Π½Π° самоС Π½Π°Ρ‡Π°Π»ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, Π° Π½Π° 0x89800 Π±Π°ΠΉΡ‚ΠΎΠ² дальшС:

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

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½Π° этом Ρ‚Π°ΠΊΠΆΠ΅ сказалось Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π΅ имСя ΠΏΠΎΠ΄ Ρ€ΡƒΠΊΠΎΠΉ Π½Π΅Π½ΡƒΠΆΠ½ΠΎΠΉ ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° 4Gb, я взял Π½Π° 2Gb ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ Ρ‚Ρ‹ΠΊΠ° Π·Π°ΠΌΠ΅Π½ΠΈΠ» Π² Makefile DEMO_END=11718750 Π½Π° DEMO_END=3078900 (Π½Π΅ ΠΈΡ‰ΠΈΡ‚Π΅ смысл Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ β€” Π΅Π³ΠΎ Π½Π΅Ρ‚, просто Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΠ±Ρ€Π°Π· помСщаСтся Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΡƒ).

Π£Ρ€ΠΎΠ²Π΅Π½ΡŒ Π²Ρ‚ΠΎΡ€ΠΎΠΉ, U-Boot

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ всё Π΅Ρ‰Ρ‘ Β«ΠΏΠ°Π΄Π°Π΅ΠΌΒ», Π½ΠΎ оказываСмся ΡƒΠΆΠ΅ ΠΏΠΎ адрСсу 0x0000000080089a84. Π’ΡƒΡ‚ я Π²Ρ‹Π½ΡƒΠΆΠ΄Π΅Π½ ΠΏΡ€ΠΈΠ·Π½Π°Ρ‚ΡŒΡΡ: Π½Π° самом Π΄Π΅Π»Π΅, ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ΄Ρ‘Ρ‚ Π½Π΅ «со всСми остановками», Π° частично ΠΏΠΈΡˆΠ΅Ρ‚ΡΡ ΡƒΠΆΠ΅ «опосля», поэтому здСсь я ΡƒΠΆΠ΅ успСл ΠΏΠΎΠ΄Π»ΠΎΠΆΠΈΡ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ dtb-Ρ„Π°ΠΉΠ» ΠΎΡ‚ нашСго SoC, ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π² настройках HiFive_U-Boot ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ CONFIG_SYS_TEXT_BASE=0x80089800 (вмСсто 0x08000000), Ρ‡Ρ‚ΠΎΠ±Ρ‹ адрСс Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ совпадал с фактичСским. Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡƒΠΆΠ΅ ΠΊΠ°Ρ€Ρ‚Ρƒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ уровня Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΎΠ±Ρ€Π°Π·:

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

И видим:

   β”‚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)                      β”‚

ΠŸΡ€ΠΈΡ‡Ρ‘ΠΌ ΠΌΡ‹ ΠΏΡ€Ρ‹Π³Π°Π΅ΠΌ ΠΌΠ΅ΠΆΠ΄Ρƒ строчками 308 ΠΈ 309. И Π½Π΅ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, учитывая, Ρ‡Ρ‚ΠΎ Π² $sp Π»Π΅ΠΆΠΈΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0xfffffffe31cdc0a0. Π£Π²Ρ‹, ΠΎΠ½ΠΎ Π΅Ρ‰Ρ‘ ΠΈ постоянно Β«ΡƒΠ±Π΅Π³Π°Π΅Ρ‚Β» ΠΈΠ·-Π·Π° строчки 307. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΎΡ‡ΠΊΡƒ останова Π½Π° trap_entry, Π° ΠΏΠΎΡ‚ΠΎΠΌ снова ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π½Π° 0x80089800 (Ρ‚ΠΎΡ‡ΠΊΡƒ Π²Ρ…ΠΎΠ΄Π° U-Boot), ΠΈ Π±ΡƒΠ΄Π΅ΠΌ Π½Π°Π΄Π΅ΡΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΎ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ выставлСния рСгистров ΠΏΠ΅Ρ€Π΅Π΄ пСрСходом… ΠŸΠΎΡ…ΠΎΠΆΠ΅, Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚:

(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

Π’Π°ΠΊ сСбС ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ стСка, прямо скаТСм: ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π²ΠΎΠΎΠ±Ρ‰Π΅ ΠΌΠΈΠΌΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²ΠΊΠΈ (Ссли, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ρƒ нас Π΅Ρ‰Ρ‘ Π½Π΅Ρ‚ трансляции адрСсов, Π½ΠΎ Π±ΡƒΠ΄Π΅ΠΌ Π½Π°Π΄Π΅ΡΡ‚ΡŒΡΡ Π½Π° простой Π²Π°Ρ€ΠΈΠ°Π½Ρ‚).

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° 0x881cf950. Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠΌ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ handle_trap вызываСтся ΠΈ вызываСтся, ΠΏΡ€ΠΈ этом ΡƒΡ…ΠΎΠ΄ΠΈΠΌ Π² _exit_trap с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ epc=2148315240 (Π² дСсятичном Π²ΠΈΠ΄Π΅):

(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

Π‘Ρ‚Π°Π²ΠΈΠΌ breakpoint Π½Π° strnlen, ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ ΠΈ Π²ΠΈΠ΄ΠΈΠΌ:

(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

ΠŸΠΎΡ…ΠΎΠΆΠ΅, _exit_trap Ρ…ΠΎΡ‡Π΅Ρ‚ Π²Ρ‹Π΄Π°Ρ‚ΡŒ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΏΡ€ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π΄ΡˆΠ΅Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Π½ΠΎ Ρƒ Π½Π΅Π³ΠΎ Π½Π΅ получаСтся. Π’Π°ΠΊ, Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Ρƒ нас исходники ΠΎΠΏΡΡ‚ΡŒ Π½Π΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ. set directories ../freedom-u-sdk/HiFive_U-Boot/ О! Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ!

Π§Ρ‚ΠΎ ΠΆΠ΅, запустим Π΅Ρ‰Ρ‘ Ρ€Π°Π·, ΠΈ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ ΠΏΠΎ стСк-трСйсу ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ исходной ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅ΠΉ ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ (mcause == 5). Если я ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ понял, Ρ‡Ρ‚ΠΎ написано здСсь Π½Π° стр. 37, Ρ‚ΠΎ это ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Load access fault. ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎ-Π²ΠΈΠ΄ΠΈΠΌΠΎΠΌΡƒ, Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π²ΠΎΡ‚ здСсь

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 ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΎ самоС Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ board_init_f_init_reserve Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ошибка. ΠŸΠΎΡ…ΠΎΠΆΠ΅, Π²ΠΎΡ‚ ΠΈ Π²ΠΈΠ½ΠΎΠ²Π½ΠΈΠΊ: пСрСмСнная с нСдвусмыслСнным Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ CONFIG_SYS_INIT_SP_ADDR. Она ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Π² Ρ„Π°ΠΉΠ»Π΅ HiFive_U-Boot/include/configs/HiFive-U540.h. Π’ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚ я Π΄Π°ΠΆΠ΅ ΠΏΠΎΠ΄ΡƒΠΌΠ°Π», Π° ΠΌΠΎΠΆΠ΅Ρ‚, Π½Ρƒ Π΅Π³ΠΎ, Π΄ΠΎΠΏΠΈΠ»ΠΈΠ²Π°Ρ‚ΡŒ Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊ ΠΏΠΎΠ΄ процСссор β€” ΠΌΠΎΠΆΠ΅Ρ‚, Π»Π΅Π³Ρ‡Π΅ Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ процСссор? Но ΠΏΠΎΡ‚ΠΎΠΌ я ΡƒΠ²ΠΈΠ΄Π΅Π», Ρ‡Ρ‚ΠΎ это большС ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ ΠΎΡ‚ Π½Π΅ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Π·Π°-#if 0-Π΅Π½Π½Ρ‹Ρ… настроСк ΠΏΠΎΠ΄ Π΄Ρ€ΡƒΠ³ΡƒΡŽ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ памяти, ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

diff --git a/include/configs/HiFive-U540.h b/include/configs/HiFive-U540.h
index ca89383..245542c 100644
--- a/include/configs/HiFive-U540.h
+++ b/include/configs/HiFive-U540.h
@@ -65,12 +65,9 @@
 #define CONFIG_SYS_SDRAM_BASE  PHYS_SDRAM_0
 #endif
 #if 1
-/*#define CONFIG_NR_DRAM_BANKS 1*/
+#define CONFIG_NR_DRAM_BANKS   1
 #define PHYS_SDRAM_0   0x80000000              /* SDRAM Bank #1 */
-#define PHYS_SDRAM_1   
-       (PHYS_SDRAM_0 + PHYS_SDRAM_0_SIZE)      /* SDRAM Bank #2 */
-#define PHYS_SDRAM_0_SIZE      0x80000000      /* 2 GB */
-#define PHYS_SDRAM_1_SIZE      0x10000000      /* 256 MB */
+#define PHYS_SDRAM_0_SIZE      0x40000000      /* 1 GB */
 #define CONFIG_SYS_SDRAM_BASE  PHYS_SDRAM_0
 #endif
 /*
@@ -81,7 +78,7 @@
 #define CONSOLE_ARG                            "console=ttyS0,115200 "

 /* Init Stack Pointer */
-#define CONFIG_SYS_INIT_SP_ADDR                (0x08000000 + 0x001D0000 - 
+#define CONFIG_SYS_INIT_SP_ADDR                (0x80000000 + 0x001D0000 - 
                                        GENERATED_GBL_DATA_SIZE)

 #define CONFIG_SYS_LOAD_ADDR           0xa0000000      /* partway up SDRAM */

Π’ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚ количСство костылСй тСхнологичСского ΠΊΡ€Π΅ΠΏΠ΅ΠΆΠ° достигло критичСской ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠΈ. НСмного ΠΏΠΎΠΌΡƒΡ‡Π°Π²ΡˆΠΈΡΡŒ, я ΠΏΡ€ΠΈΡˆΡ‘Π» ΠΊ нСобходимости ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚ Π½Π° свою ΠΏΠ»Π°Ρ‚Ρƒ. Для этого Π½ΡƒΠΆΠ½ΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄ Π½Π°ΡˆΡƒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ количСство Ρ„Π°ΠΉΠ»ΠΎΠ².

Ну, ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π²ΠΎΡ‚ столСчко

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

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΡΡ‚ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.

Как оказалось, Π½Π° этой SiFive-овской ΠΏΠ»Π°Ρ‚Π΅ рСгистры Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… устройств ΠΈΠΌΠ΅ΡŽΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ адрСса. А Π΅Ρ‰Ρ‘ оказалось, Ρ‡Ρ‚ΠΎ U-Boot конфигурируСтся ΡƒΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ΠΌ ΠΏΠΎ ядру Linux ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ Kconfig β€” Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠ²Π°Ρ‚ΡŒ make menuconfig, ΠΈ ΠΏΠ΅Ρ€Π΅Π΄ Π²Π°ΠΌΠΈ появится ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ тСкстовый интСрфСйс с ΠΏΠΎΠΊΠ°Π·ΠΎΠΌ описаний ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΏΠΎ ? ΠΈ Ρ‚.Π΄. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, слСпив ΠΈΠ· описаний Π΄Π²ΡƒΡ… ΠΏΠ»Π°Ρ‚ описаниС Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ, Π²Ρ‹ΠΊΠΈΠ½ΡƒΠ² ΠΎΡ‚Ρ‚ΡƒΠ΄Π° всякиС пафосныС пСрСнастройки PLL (Π²ΠΈΠ΄ΠΈΠΌΠΎ, это ΠΊΠ°ΠΊ-Ρ‚ΠΎ связано с ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ с хостового ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π° ΠΏΠΎ PCIe, Π½ΠΎ это Π½Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ), я ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΡƒ, которая ΠΏΡ€ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΉ ΠΏΠΎΠ³ΠΎΠ΄Π΅ Π½Π° ΠœΠ°Ρ€ΡΠ΅ Π²Ρ‹Π΄Π°Π²Π°Π»Π° ΠΌΠ½Π΅ ΠΏΠΎ UART сообщСниС ΠΎ Ρ‚ΠΎΠΌ, ΠΈΠ· ΠΊΠ°ΠΊΠΎΠ³ΠΎ Ρ…Π΅ΡˆΠ° ΠΊΠΎΠΌΠΌΠΈΡ‚Π° ΠΎΠ½Π° собрана, ΠΈ ΠΎ Ρ‚ΠΎΠΌ, сколько Ρƒ мСня DRAM (Π½ΠΎ эту ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ я сам ΠΆΠ΅ Π² Ρ…Π΅Π΄Π΅Ρ€Π΅ ΠΈ прописал).

Π–Π°Π»ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ, Ρ‡Ρ‚ΠΎ послС этого ΠΏΠ»Π°Ρ‚Π° ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ пСрСставала ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ ΠΏΠΎ процСссорному JTAG, Π° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ β€” Π΄Π΅Π»ΠΎ, ΡƒΠ²Ρ‹, Π² ΠΌΠΎΠ΅ΠΉ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π½Π΅ быстроС. Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, ΠΈΠ½ΠΎΠ³Π΄Π° BootROM Π²Ρ‹Π΄Π°Π²Π°Π» сообщСниС, Ρ‡Ρ‚ΠΎ ERROR, Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒΡΡ, ΠΈ Ρ‚ΡƒΡ‚ ΠΆΠ΅ выскакивал U-Boot. Π’ΡƒΡ‚-Ρ‚ΠΎ Π΄ΠΎ мСня ΠΈ дошло: Π²ΠΈΠ΄ΠΈΠΌΠΎ, послС ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ bitstream Π² ΠŸΠ›Π˜Π‘ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅ пСрСтираСтся, Π½Π΅ успСваСт Β«Ρ€Π°ΡΡ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡΒ» ΠΈ Ρ‚.Π΄. ΠšΠΎΡ€ΠΎΡ‡Π΅, ΠΌΠΎΠΆΠ½ΠΎ просто ΠΏΡ€ΠΈ появлСнии сообщСния LOADING / ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒΡΡ ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠΎΠΌ ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠ²Π°Ρ‚ΡŒ set variable $pc=0x80089800, минуя Ρ‚Π΅ΠΌ самым эту Π΄ΠΎΠ»Π³ΡƒΡŽ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ (ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π² ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΎ Π² ΠΏΡ€ΠΎΡˆΠ»Ρ‹ΠΉ Ρ€Π°Π· сломалось достаточно Ρ€Π°Π½ΠΎ, ΠΈ Π½Π΅ успСло ΠΏΠΎΠ²Π΅Ρ€Ρ… ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ).

ΠšΡΡ‚Π°Ρ‚ΠΈ, Π° это Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, Ρ‡Ρ‚ΠΎ процСссор Π½Π°ΠΏΡ€ΠΎΡ‡ΡŒ виснСт, ΠΈ ΠΊ Π½Π΅ΠΌΡƒ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ JTAG-ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊ с сообщСниями

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

Π’Π°ΠΊ, постойтС! Π― это ΡƒΠΆΠ΅ Π²ΠΈΠ΄Π΅Π»! Π§Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ происходит ΠΏΡ€ΠΈ Π΄Π΅Π΄Π»ΠΎΠΊΠ΅ TileLink, Π° Π°Π²Ρ‚ΠΎΡ€Ρƒ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° памяти я ΠΊΠ°ΠΊ-Ρ‚ΠΎ Π½Π΅ Π΄ΠΎΠ²Π΅Ρ€ΡΡŽ β€” сам ΠΆΠ΅ писал… Π’Π½Π΅Π·Π°ΠΏΠ½ΠΎ, послС ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΆΠ΅ ΡƒΠ΄Π°Ρ‡Π½ΠΎΠΉ пСрСсборки процСссора послС рСдактирования ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° я ΡƒΠ²ΠΈΠ΄Π΅Π»:

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

На эту ΡΡ‚Ρ€Π°Π½Π½ΡƒΡŽ строчку ΠΏΠ΅Ρ€Π΅Π΄ In: serial Π½Π΅ ΠΎΠ±Ρ€Π°Ρ‰Π°ΠΉΡ‚Π΅ внимания β€” это я пытался Π½Π° виснущСм процСссорС ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π»ΠΈ ΠΎΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с environment. Π§Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚, Β«Π£ΠΆΠ΅ Π΄Π΅ΡΡΡ‚ΡŒ ΠΌΠΈΠ½ΡƒΡ‚ Ρ‚Π°ΠΊ висит»? Оно хотя Π±Ρ‹ сумСло Ρ€Π΅Π»ΠΎΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ Π·Π°Π³Ρ€ΡƒΠ·ΠΎΡ‡Π½ΠΎΠΌΡƒ мСню! НСбольшоС отступлСниС: Ρ…ΠΎΡ‚ΡŒ U-Boot ΠΈ грузится Π² числС ΠΏΠ΅Ρ€Π²Ρ‹Ρ… 2^24 Π±Π°ΠΉΡ‚ с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹, Π·Π°ΠΏΡƒΡΡ‚ΠΈΠ²ΡˆΠΈΡΡŒ, ΠΎΠ½ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ сСбя ΠΊΡƒΠ΄Π° подальшС ΠΏΠΎ адрСсу, Ρ‚ΠΎ Π»ΠΈ записанному Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΌ Ρ…Π΅Π΄Π΅Ρ€Π΅, Ρ‚ΠΎ Π»ΠΈ просто Π² ΡΡ‚Π°Ρ€ΡˆΠΈΠ΅ адрСса ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти, ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ Ρ€Π΅Π»ΠΎΠΊΠ°Ρ†ΠΈΡŽ ELF-символов, ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‘Ρ‚ Ρ‚ΡƒΠ΄Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅. Π’Π°ΠΊ Π²ΠΎΡ‚: ΠΏΠΎΡ…ΠΎΠΆΠ΅, этот ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ΠΏΡ€ΠΎΡˆΠ»ΠΈ ΠΈ бонусом ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ процСссор, Π½Π΅ виснущий Π½Π°ΠΌΠ΅Ρ€Ρ‚Π²ΠΎ послС этого.

Π˜Ρ‚Π°ΠΊ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚Π°ΠΉΠΌΠ΅Ρ€? ΠŸΠΎΡ…ΠΎΠΆΠ΅, часы Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ ΠΏΠΎΡ‡Π΅ΠΌΡƒ-Ρ‚ΠΎ Π½Π΅ ΠΈΠ΄ΡƒΡ‚…

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

А Ρ‡Ρ‚ΠΎ, Ссли стрСлки Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΏΠΎΠΊΡ€ΡƒΡ‚ΠΈΡ‚ΡŒ?

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

Π’ΠΎΠ³Π΄Π°:

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

Π’Ρ‹Π²ΠΎΠ΄: часы Π½Π΅ ΠΈΠ΄ΡƒΡ‚. ВСроятно, ΠΈΠ·-Π·Π° этого ΠΆΠ΅ ΠΈ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π²Π²ΠΎΠ΄ с ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹:

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

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° оказалась Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ я ΠΌΠ°Π»ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΡƒΠ΄Ρ€ΠΈΠ»: я Π΄ΠΎΠ±Π°Π²ΠΈΠ» Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ процСссора ΠΊΠ»ΡŽΡ‡:

  case DTSTimebase => BigInt(0)

… ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΡƒΡΡΡŒ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ Π±Ρ‹Π»ΠΎ сказано «Ссли Π½Π΅ Π·Π½Π°Π΅Ρ‚Π΅ β€” ΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ 0Β». И вСдь WithNBigCores ΠΊΠ°ΠΊ Ρ€Π°Π· проставляло Π΅Π³ΠΎ Π² 1MHz (ΠΊΠ°ΠΊ, кстати, ΠΈ Π±Ρ‹Π»ΠΎ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³Π΅ U-Boot). Но я ΠΆΠ΅, Π±Π»ΠΈΠ½, Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½Ρ‹ΠΉ ΠΈ Π΄ΠΎΡ‚ΠΎΡˆΠ½Ρ‹ΠΉ: Ρ‚Π°ΠΌ я Π½Π΅ знаю, Ρ‚ΡƒΡ‚ 25MHz! Π’ ΠΈΡ‚ΠΎΠ³Π΅ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. Π£Π±Ρ€Π°Π» свои Β«ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡΒ» ΠΈ…

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 #

МоТно Π΄Π°ΠΆΠ΅ Π²Π²ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹! НапримСр, Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠΊΠΎΠ²Ρ‹Ρ€ΡΠ²ΡˆΠΈΡΡŒ, ΠΌΠΎΠΆΠ½ΠΎ, Π½Π°ΠΊΠΎΠ½Π΅Ρ†, Π΄ΠΎΠ³Π°Π΄Π°Ρ‚ΡŒΡΡ ввСсти mmc_spi 1 10000000 0; mmc part, ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ² частоту SPI с 20MHz Π΄ΠΎ 10MHz. ΠŸΠΎΡ‡Π΅ΠΌΡƒ? Ну, Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³Π΅ Π±Ρ‹Π»Π° написана максимальная частота 20MHz, ΠΎΠ½Π° ΠΆΠ΅ Ρ‚Π°ΠΌ ΠΈ сСйчас написана. Но, насколько я понял, интСрфСйсы, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ здСсь, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Ρ‚Π°ΠΊ: ΠΊΠΎΠ΄ Π΄Π΅Π»ΠΈΡ‚ частоту Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° (Ρƒ мСня β€” Π²Π΅Π·Π΄Π΅ 25MHz) Π½Π° Ρ†Π΅Π»Π΅Π²ΡƒΡŽ, ΠΈ выставляСт ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠ΅Π΅ΡΡ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² качСствС дСлитСля Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ рСгистр. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ссли для 115200Hz UART-Π° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ, Ρ‚ΠΎ Ссли Π½Π°Ρ†Π΅Π»ΠΎ ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒ 25000000 Π½Π° 20000000 получится 1, Ρ‚.Π΅. Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΎΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π½Π° 25MHz. ΠœΠΎΠΆΠ΅Ρ‚, это ΠΈ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, Π½ΠΎ Ссли ограничСния Π²Ρ‹ΡΡ‚Π°Π²Π»ΡΡŽΡ‚, Π·Π½Π°Ρ‡ΠΈΡ‚, это ΠΊΠΎΠΌΡƒ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π½ΡƒΠΆΠ½ΠΎ (Π½ΠΎ это Π½Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ)… Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, Π»Π΅Π³Ρ‡Π΅ ΠΏΡ€ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΈ ΠΏΠΎΠΉΡ‚ΠΈ дальшС β€” Π΄Π°Π»Π΅ΠΊΠΎ ΠΈ, ΡƒΠ²Ρ‹, Π½Π°Π΄ΠΎΠ»Π³ΠΎ. 25MHz β€” это Π²Π°ΠΌ Π½Π΅ Core i9.

Π’Ρ‹Π²ΠΎΠ΄ консоли

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

ОкСй, ΠΌΡ‹ ΠΏΡ€ΠΎΡˆΠ»ΠΈ Π½Π° Π½ΠΎΠ²Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ, Π½ΠΎ ΠΎΠ½ΠΎ всё Π΅Ρ‰Ρ‘ зависаСт. А ΠΈΠ½ΠΎΠ³Π΄Π° Π΅Ρ‰Ρ‘ ΠΈ сыплСт эксСпшСнами. Π£Π²ΠΈΠ΄Π΅Ρ‚ΡŒ mcause ΠΌΠΎΠΆΠ½ΠΎ, ΠΏΠΎΠ΄ΠΊΠ°Ρ€Π°ΡƒΠ»ΠΈΠ² ΠΊΠΎΠ΄ ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ адрСсу $pc ΠΈ послС si ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π½Π° trap_entry. Π‘Π°ΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΈΠ· U-Boot ΡƒΠΌΠ΅Π΅Ρ‚ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для mcause = 0..4, поэтому Π³ΠΎΡ‚ΠΎΠ²ΡŒΡ‚Π΅ΡΡŒ Π·Π°Ρ†ΠΈΠΊΠ»ΠΈΡ‚ΡŒΡΡ Π½Π° Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅. Π’ΡƒΡ‚ я ΠΏΠΎΠ»Π΅Π· Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³, стал ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΆΠ΅ я мСнял, ΠΈ вспомнил: Ρ‚Π°ΠΌ ΠΆΠ΅ Π² conf/rvboot-fit.txt написано:

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

Π§Ρ‚ΠΎ ΠΆΠ΅, ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘ΠΌ всС Ρ„Π°ΠΉΠ»Ρ‹ Π² соотвСтствиС, Π·Π°ΠΌΠ΅Π½ΠΈΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡƒΡŽ строку ядра ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‚Π°ΠΊ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π΅ΡΡ‚ΡŒ подозрСния, Ρ‡Ρ‚ΠΎ SIF0 β€” это Π²Ρ‹Π²ΠΎΠ΄ ΠΊΡƒΠ΄Π°-Ρ‚ΠΎ ΠΏΠΎ PCIe:

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

И Π΄ΠΎ ΠΊΡƒΡ‡ΠΈ помСняСм Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ с SHA-256 Π½Π° MD5: криптостойкости ΠΌΠ½Π΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ (Ρ‚Π΅ΠΌ Π±ΠΎΠ»Π΅Π΅, ΠΏΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅), считаСтся ΠΎΠ½ΠΎ ΠΆΡƒΡ‚ΠΊΠΎ Π΄ΠΎΠ»Π³ΠΎ, Π° для ΠΎΡ‚Π»ΠΎΠ²Π° ошибок цСлостности ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ ΠΈ MD5 β€” Π·Π° Π³Π»Π°Π·Π°. Π§Ρ‚ΠΎ ΠΆΠ΅ Π² ΠΈΡ‚ΠΎΠ³Π΅? ΠŸΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ΠΌΡ‹ стали Π·Π°ΠΌΠ΅Ρ‚Π½ΠΎ быстрСС (Π·Π° счёт Π±ΠΎΠ»Π΅Π΅ простого Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ), ΠΈ открылся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ:

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

Π’ΠΎΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ часы Π½Π΅ Ρ‚ΠΈΠΊΠ°ΡŽΡ‚…

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

Упс, ΠΏΠΎΡ…ΠΎΠΆΠ΅, исправлСниС Ρ…ΠΎΠ΄Π° часов оказалось ΠΏΠ»Π°Ρ†Π΅Π±ΠΎ, хотя ΠΌΠ½Π΅ Ρ‚ΠΎΠ³Π΄Π° ΠΈ показалось, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π»ΠΎ. НСт, ΠΏΠΎΡ‡ΠΈΠ½ΠΈΡ‚ΡŒ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ Π½Π°Π΄ΠΎ, Π½ΠΎ Π΄Π°Π²Π°ΠΉΡ‚Π΅ для Π½Π°Ρ‡Π°Π»Π° ΠΏΠΎΠΊΡ€ΡƒΡ‚ΠΈΠΌ стрСлки Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΈ посмотрим, Ρ‡Ρ‚ΠΎ получится:

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.

Π’Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ…

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

НСт ΡƒΠΆ, ΠΏΠΎΠΉΠ΄Ρƒ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ…ΠΎΠ΄ часов β€” Π° Ρ‚ΠΎ, ΠΌΠΎΠΆΠ΅Ρ‚, ΠΎΠ½ Ρ‚Π°ΠΌ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π·Π΄ΡƒΠΌΠ°Π΅Ρ‚!

А адрСс Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ инструкции Ρ‚Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΊΡƒΠ΄Π°-Ρ‚ΠΎ Π²

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>

Π²Π½ΡƒΡ‚Ρ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ Berkeley Boot Loader. Π›ΠΈΡ‡Π½ΠΎ мСня Π² этом смущаСт ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π½ΠΈΠ΅ htif β€” host interface, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ для tethered-запуска ядра (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π² ΠΊΠΎΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с хостовым ARM), я-Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π» standalone. Π’ΠΏΡ€ΠΎΡ‡Π΅ΠΌ, Ссли Π½Π°ΠΉΡ‚ΠΈ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π² исходниках, Ρ‚ΠΎ Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π΅ всё Ρ‚Π°ΠΊ ΠΏΠ»ΠΎΡ…ΠΎ:

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

ΠšΠ²Π΅ΡΡ‚: запусти часы

Поиск рСгистров Π² CLINT Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ нас ΠΊ

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

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

ΠšΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² RTC, Π»ΠΈΠ±ΠΎ Π² Π·Π°Π³Π°Π΄ΠΎΡ‡Π½ΠΎΠΌ MockAON, ΠΏΡ€ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ я ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ рассудил: Β«Π’Π°ΠΊ, Ρ‡Ρ‚ΠΎ это Ρƒ нас Ρ‚ΡƒΡ‚? НСпонятно? ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ!Β» ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΠ½Π΅ Π΄ΠΎ сих ΠΏΠΎΡ€ нСпонятно, Ρ‡Ρ‚ΠΎ это Π·Π° тактовая магия Ρ‚Π°ΠΌ творится, поэтому просто ΠΏΠ΅Ρ€Π΅Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽ эту Π»ΠΎΠ³ΠΈΠΊΡƒ Π² 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
  }

ΠŸΡ€ΠΎΠ±ΠΈΡ€Π°ΡΡΡŒ ΠΊ Linux kernel

Π’ΡƒΡ‚ повСствованиС ΡƒΠΆΠ΅ ΠΈ Π±Π΅Π· Ρ‚ΠΎΠ³ΠΎ Π·Π°Ρ‚ΡΠ½ΡƒΠ»ΠΎΡΡŒ ΠΈ стало ΠΌΠ°Π»ΠΎΡΡ‚ΡŒ ΠΎΠ΄Π½ΠΎΠΎΠ±Ρ€Π°Π·Π½Ρ‹ΠΌ, поэтому ΠΎΠΏΠΈΡˆΡƒ ΠΏΠΎ Π²Π΅Ρ€Ρ…Π°ΠΌ:

BBL ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π» Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ FDT ΠΏΠΎ адрСсу 0xF0000000, Π° я вСдь ΡƒΠΆΠ΅ исправлял! Ну Ρ‡Ρ‚ΠΎ ΠΆΠ΅, ΠΏΠΎΠΈΡ‰Π΅ΠΌ Сщё… ΠΠ°ΡˆΡ‘Π» Π² HiFive_U-Boot/arch/riscv/lib/boot.c, Π·Π°ΠΌΠ΅Π½ΠΈΠ» Π½Π° 0x81F00000, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ U-Boot.

ΠŸΠΎΡ‚ΠΎΠΌ BBL Таловался, Ρ‡Ρ‚ΠΎ Π½Π΅Ρ‚ памяти. Мой ΠΏΡƒΡ‚ΡŒ Π»Π΅ΠΆΠ°Π» Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ mem_prop, Ρ‡Ρ‚ΠΎ Π² riscv-pk/machine/fdt.c: ΠΎΡ‚Ρ‚ΡƒΠ΄Π° я ΡƒΠ·Π½Π°Π», Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΡƒΠ·Π΅Π» fdt ram ΠΊΠ°ΠΊ device_type = "memory" β€” ΠΏΠΎΡ‚ΠΎΠΌ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ процСссора ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ, Π½ΠΎ ΠΏΠΎΠΊΠ° просто Π²ΠΏΠΈΡˆΡƒ Ρ€ΡƒΠΊΠ°ΠΌΠΈ β€” всё Ρ€Π°Π²Π½ΠΎ я этот Ρ„Π°ΠΉΠ» Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ пСрСносил.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ я ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» сообщСниС (ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΎ Π² ΠΎΡ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅, с Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π°ΠΌΠΈ ΠΊΠ°Ρ€Π΅Ρ‚ΠΊΠΈ):

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.

Π’Ρ€ΠΎΠ΄Π΅, ΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠΏΡ†ΠΈΠΈ riscv,kernel-start ΠΈ riscv,kernel-end Π² DTB, Π½ΠΎ парсятся Π½ΡƒΠ»ΠΈ. ΠžΡ‚Π»Π°Π΄ΠΊΠ° query_chosen ΠΏΠΎΠΊΠ°Π·Π°Π»Π°, Ρ‡Ρ‚ΠΎ BBL пытаСтся ΠΏΠ°Ρ€ΡΠΈΡ‚ΡŒ 32-Π±ΠΈΡ‚Π½Ρ‹ΠΉ адрСс, Π° Π΅ΠΌΡƒ попадаСтся ΠΏΠ°Ρ€Π° <0x0 0xADDR>, ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΏΠΎΡ…ΠΎΠΆΠ΅, младшиС разряды. Дописал Π² ΡΠ΅ΠΊΡ†ΠΈΡŽ chosen

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

ΠΈ ΠΏΠΎΠΏΡ€Π°Π²ΠΈΠ» Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ: Π½Π΅ Π΄ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ 0x0 ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ элСмСнтом.

Π­Ρ‚ΠΈ 100500 простых шагов позволят Π»Π΅Π³ΠΊΠΎ ΠΈ просто ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΏΠ°Π΄Π°Π΅Ρ‚ ΠΏΠΈΠ½Π³Π²ΠΈΠ½:

Π‘ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ тСкст

   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)

(эмблСму Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ BBL, Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ с ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ β€” ядро).

К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, Π½Π΅ знаю, ΠΊΠ°ΠΊ Π²Π΅Π·Π΄Π΅, Π½ΠΎ Π½Π° RocketChip ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠ° ΠΏΠΎ JTAG ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΎΠ²ΠΈΡ‚ΡŒ trap-Ρ‹ ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ β€” ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊ остановится Ρ€ΠΎΠ²Π½ΠΎ Π² этой Ρ‚ΠΎΡ‡ΠΊΠ΅.

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); // < Π’Π« НАΠ₯ΠžΠ”Π˜Π’Π•Π‘Π¬ Π—Π”Π•Π‘Π¬
}

Как Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ Π² старом Π°Π½Π΅ΠΊΠ΄ΠΎΡ‚Π΅, CPU not found, running software emulation. Ну ΠΈΠ»ΠΈ Π½Π΅ running. Π—Π°Π±Π»ΡƒΠ΄ΠΈΠ»ΠΈΡΡŒ Π² СдинствСнном ядрС процСссора.

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

Π₯ΠΎΡ€ΠΎΡˆΠΈΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ Π² linux/arch/riscv/kernel/setup.c β€” этакая покраска Π·Π°Π±ΠΎΡ€Π° ΠΏΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ Π’ΠΎΠΌΠ° Π‘ΠΎΠΉΠ΅Ρ€Π°. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, сСгодня ΠΏΠΎΠ±Π΅Π΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΏΠΎΡ‡Π΅ΠΌΡƒ-Ρ‚ΠΎ Π½Π΅ нашлось, ΠΏΡ€ΠΈΠ· пСрСносится Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΡ€Π°ΠΆ…

На этом ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΡ‚ΡŒ ΠΈ Π±Π΅Π· Ρ‚ΠΎΠ³ΠΎ Π·Π°Ρ‚ΡΠ½ΡƒΠ²ΡˆΡƒΡŽΡΡ ΡΡ‚Π°Ρ‚ΡŒΡŽ.

ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ слСдуСт. Π’ Π½Ρ‘ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π±ΠΎΠΉ с Ρ…ΠΈΡ‚Ρ€ΠΎΠΉ ошибкой, которая успСваСт ΡΠΏΡ€ΡΡ‚Π°Ρ‚ΡŒΡΡ, Ссли ΠΊ Π½Π΅ΠΉ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΏΠΎΠ΄ΠΊΡ€Π°Π΄Ρ‹Π²Π°Ρ‚ΡŒΡΡ singlestep-ΠΎΠΌ.

ВСкстовый скринкаст Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ (внСшняя ссылка):
Π§Π°ΡΡ‚ΡŒ 3: ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ‡Ρ‚ΠΎ Π³Ρ€ΡƒΠ·ΠΈΠΌ Linux с SD-ΠΊΠ°Ρ€Ρ‚Ρ‹ Π½Π° RocketChip

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com