В
Uskunaga SPI interfeysi orqali ulangan SD-karta, shuningdek, UART kiradi. Dasturiy ta'minot qismida BootROM bilan almashtiriladi xip
haqida sdboot
va, aslida, quyidagi yuklash bosqichlari qo'shilgan (SD-kartada).
Uskunani tugatish
Shunday qilib, vazifa: siz "katta" yadroga o'tishingiz va UART (Raspberry-dan) va SD adapterini ulashingiz kerak (biz Catalex-dan oltita pinli kartadan foydalandik: GND, VCC, MISO, MOSI, SCK, CS) .
Aslida, hamma narsa juda oddiy edi. Ammo buni anglamasdan oldin, men u yoqdan-bu yoqqa otildim: oldingi vaqtdan keyin men yana aralashishim kerak deb qaror qildim. System
shunga o'xshash narsa HasPeripheryUART
(va shunga mos ravishda amalga oshirish), SD-karta uchun ham xuddi shunday - va hamma narsa tayyor bo'ladi. Keyin men "jiddiy" dizaynda qanday amalga oshirilganligini ko'rishga qaror qildim. Xo'sh, buning nimasi jiddiy? Arti, aftidan, mos kelmaydi - yirtqich hayvon qoladi unleahshed.DevKitConfigs
. Va to'satdan hamma joyda parametrlar orqali kalitlar orqali qo'shilgan ba'zi qoplamalar borligi ma'lum bo'ldi. O'ylaymanki, bu juda moslashuvchan va sozlanishi mumkin, lekin men hech bo'lmaganda avval biror narsani ishga tushirishni xohlayman ... Sizda ham xuddi shunday, oddiyroq va zerikarliroq emasmi?.. O‘shanda men duch keldim vera.iofpga.FPGAChip
Microsemi FPGA-lar uchun va darhol uni qo'shtirnoq uchun ajratib oldim va o'xshatish bo'yicha o'zimni amalga oshirishga harakat qildim, xayriyatki, bitta faylda ko'proq yoki kamroq "ana plata tartibi" mavjud.
Siz haqiqatan ham qo'shishingiz kerakligi ma'lum bo'ldi System.scala
chiziqlar
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
...
Sinf tanasidagi chiziq System
dts fayliga SoC ning ushbu qismi ishlash chastotasi haqida ma'lumot qo'shadi. Men tushunganimdek, DTS/DTB o'rnatilgan qurilmalar uchun plagin va o'ynatish texnologiyasining statik analogidir: dts tavsifi daraxti ikkilik dtb fayliga kompilyatsiya qilinadi va yuklovchi tomonidan yadroga uzatiladi, shunda u to'g'ri sozlashi mumkin. apparat. Qizig'i shundaki, bilan chiziqsiz tlclock
hamma narsa mukammal sintezlanadi, lekin BootROM-ni kompilyatsiya qilish (eslatmaga ruxsat beraman, endi bu allaqachon bo'ladi sdboot
) ishlamaydi - kompilyatsiya jarayonida u dts faylini tahlil qiladi va makros bilan sarlavha yaratadi. TL_CLK
, buning yordamida u tashqi interfeyslar uchun chastota ajratgichlarni to'g'ri sozlashi mumkin.
Shuningdek, siz "simlarni" biroz tuzatishingiz kerak bo'ladi:
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
}
Ro'yxatga olish zanjirlari, rostini aytsam, asl koddagi boshqa joylarga o'xshash tarzda qo'shilgan. Katta ehtimol bilan ular himoya qilishlari kerak dq
? Men javobni hali topa olmadim, lekin kodning qolgan qismi aynan shunday aloqaga tayanganga o'xshaydi.
Jismoniy jihatdan, men oddiygina dizayn pinlarini blokdagi bo'sh kontaktlarga tayinladim va kuchlanishni tanlash o'tish moslamasini 3.3V ga o'tkazdim.
SD adapter
Yuqoridan ko'rinish:
Pastki ko'rinish:
Dasturiy ta'minotni tuzatish: asboblar
Birinchidan, mavjud disk raskadrovka vositalari va ularning cheklovlari haqida gapiraylik.
Minikom
Birinchidan, biz qandaydir tarzda bootloader va yadro chiqishini o'qishimiz kerak. Buni Linuxda qilish uchun (bu holda, RaspberryPi-da) bizga Minicom dasturi kerak. Umuman olganda, ketma-ket port bilan ishlaydigan har qanday dastur ishlaydi.
Shuni esda tutingki, ishga tushirishda port qurilma nomi sifatida ko'rsatilishi kerak -D /dev/ttyS0
- variantdan keyin -D
. Xo'sh, asosiy ma'lumot: chiqish, foydalanish Ctrl-A, X
. Menda bu kombinatsiya ishlamagan holat bo'lgan - keyin siz shunchaki qo'shni SSH sessiyasidan aytishingiz mumkin killall -KILL minicom
.
Yana bitta xususiyat bor. Xususan, RaspberryPi ikkita UARTga ega va ikkala port ham biror narsaga moslashtirilishi mumkin: biri Bluetooth uchun, ikkinchisi sukut bo'yicha yadro konsolini chiqaradi. Yaxshiyamki, bu xatti-harakatni bekor qilish mumkin
Xotirani qayta yozish
Nosozliklarni tuzatishda, gipotezani sinab ko'rish uchun men ba'zan majbur bo'ldim yuklash vositasini yuklang (kechirasiz) to'g'ridan-to'g'ri xostdan RAMga. Ehtimol, buni to'g'ridan-to'g'ri GDB-dan qilish mumkin, lekin oxirida men oddiy yo'lni tutdim: men kerakli faylni Raspberry-ga ko'chirdim, shuningdek, SSH (OpenOCD-dan telnet) orqali 4444-portni yo'naltirdim va buyruqni ishlatdim. load_image
. Buni qilganingizda, hamma narsa muzlatilganga o'xshaydi, lekin aslida "U uxlamaydi, sekin miltillaydi": U faylni yuklab oladi, u buni soniyasiga bir necha kilobayt tezlikda bajaradi.
To'xtash nuqtalarini o'rnatish xususiyatlari
Ko'p odamlar, ehtimol, muntazam dasturlarni disk raskadrovka qilishda bu haqda o'ylamagan bo'lishi mumkin, ammo to'xtash nuqtalari har doim ham apparatda o'rnatilmaydi. Ba'zan to'xtash nuqtasini o'rnatish maxsus ko'rsatmalarni to'g'ri joyda vaqtincha yozishni o'z ichiga oladi to'g'ridan-to'g'ri mashina kodiga. Misol uchun, mening standart buyrug'im shunday ishlagan b
GDBda. Quyidagilar:
- BootROM ichiga nuqta qo'ya olmaysiz, chunki ROM
- SD-kartadan RAMga yuklangan kodda to'xtash nuqtasini o'rnatishingiz mumkin, lekin u yuklanmaguncha kutishingiz kerak. Aks holda, biz kod qismini qayta yozmaymiz, lekin yuklovchi bizning to'xtash nuqtamizni qayta yozadi.
Ishonchim komilki, siz aniq apparat uzilish nuqtalaridan foydalanishni so'rashingiz mumkin, ammo baribir ularning soni cheklangan.
BootROMni tez almashtirish
Nosozliklarni tuzatishning dastlabki bosqichida ko'pincha BootROM-ni tuzatish va qayta urinib ko'rish istagi paydo bo'ladi. Ammo muammo bor: BootROM FPGA-ga yuklangan dizaynning bir qismidir va uning sintezi bir necha daqiqa vaqtni oladi (va bu C va Assembler-dan BootROM tasvirining o'zi deyarli bir zumda kompilyatsiya qilinganidan keyin...). Yaxshiyamki, aslida hamma narsa ancha tezroq: harakatlar ketma-ketligi quyidagicha:
- regenerate bootrom.mif (men HEX o'rniga MIFga o'tdim, chunki men har doim HEX bilan ba'zi muammolarga duch kelganman va MIF Alterning mahalliy formati)
- Kvartda deyishadi
Processing -> Update Memory Initialization File
- Assembler elementida (Vazifalarning chap ustunida) Qayta boshlash buyrug'i
Hamma narsa haqida - bir necha o'n soniya.
SD karta tayyorlanmoqda
Bu erda hamma narsa nisbatan sodda, lekin siz sabrli bo'lishingiz va taxminan 14 Gb disk maydoniga ega bo'lishingiz kerak:
git clone https://github.com/sifive/freedom-u-sdk
git submodule update --recursive --init
make
Shundan so'ng siz toza, to'g'rirog'i, hech qanday zarur bo'lmagan SD-kartani kiritishingiz va uni bajarishingiz kerak.
sudo make DISK=/dev/sdX format-boot-loader
… Qayerda sdX
— kartaga tayinlangan qurilma. DIQQAT: kartadagi ma'lumotlar o'chiriladi, ustiga yoziladi va umuman olganda! Butun montajni pastdan bajarish qiyin sudo
chunki u holda barcha qurilish artefaktlari tegishli bo'ladi root
, va montajni pastdan bajarish kerak bo'ladi sudo
doimiy.
Natijada GPT-da to'rtta bo'limga ega bo'lgan karta paydo bo'ladi, ulardan birida FAT mavjud uEnv.txt
va FIT formatidagi yuklanadigan tasvir (uning har biri o'z yuklab olish manziliga ega bo'lgan bir nechta pastki rasmlarni o'z ichiga oladi), boshqa bo'lim bo'sh, u Linux uchun Ext4 formatida formatlangan bo'lishi kerak. Yana ikkita bo'lim - sirli: U-Boot birida yashaydi (uning ofseti, men tushunganimdek, BootROM-ga qattiq kodlangan), boshqa tomondan, uning muhit o'zgaruvchilari yashaydi, lekin men ulardan hali foydalanmayapman.
Birinchi daraja, BootROM
Xalq donoligida shunday deyilgan: "Agar dasturlashda daf bilan raqs tushsa, elektronikada ham o't o'chirgich bilan raqs tushadi." Bu hatto bir marta men "Yaxshi, GND bir xil past daraja" deb qaror qilib, taxtani deyarli yoqib yuborganim haqida emas. (Aftidan, rezistor zarar ko'rmaydi ...) Bu ko'proq, agar qo'llar u erdan o'smasa, elektronika hech qachon kutilmagan hodisalar keltirishni to'xtatmaydi: ulagichni taxtaga lehimlashda men hali ham kontaktlarni to'g'ri lehimlay olmadim - videoda lehimning to'g'ridan-to'g'ri qanday tarqalishi ko'rsatilgan. butun ulanish bo'ylab, shunchaki lehim temirini qo'llang, men uchun u tasodifan "tarsa" tashladi. Xo'sh, ehtimol, lehim lehimli temirning haroratiga mos kelmadi, ehtimol boshqa narsa ... Umuman olganda, men allaqachon o'nlab kontaktlarim borligini ko'rganimda, men voz kechdim va disk raskadrovka qilishni boshladim. Va keyin boshlandi sirli: UART dan RX/TX ni uladim, proshivkani yukladim - deydi
INIT
CMD0
ERROR
Xo'sh, hamma narsa mantiqiy - men SD-karta modulini ulamadim. Biz vaziyatni to'g'irlaymiz, proshivkani yuklaymiz ... Va sukunat ... Nima uchun men o'z fikrimni o'zgartirmadim, lekin kichik quti faqat ochildi: modul pinlaridan biri VCC ga ulanishi kerak edi. Mening holatimda modul quvvat manbai uchun 5V ni qo'llab-quvvatladi, shuning uchun ikki marta o'ylamasdan, moduldan keladigan simni taxtaning qarama-qarshi tomoniga uladim. Natijada, egri lehimli konnektor qiyshayib ketdi va UART aloqasi shunchaki yo'qoldi. facepalm.jpg Umuman olganda, “yomon bosh oyoqqa orom bermaydi”, qiyshiq qo‘llar esa boshga tinchlik bermaydi...
Natijada men uzoq kutilgan narsani ko'rdim
INIT
CMD0
CMD8
ACMD41
CMD58
CMD16
CMD18
LOADING /
Bundan tashqari, u harakat qiladi va yuklash indikatori aylanadi. Darhol maktab kunlarimni va MinuetOS-ni floppi diskdan bemalol yuklaganimni eslayman. Drayv silliqlashmasa.
Muammo shundaki, BOOT xabaridan keyin hech narsa sodir bo'lmaydi. Bu shuni anglatadiki, OpenOCD orqali Raspberry-ga, xostdagi GDB-ga ulanish va uning nima ekanligini ko'rish vaqti keldi.
Birinchidan, GDB yordamida ulanish darhol buni ko'rsatdi $pc
(dastur hisoblagichi, joriy ko'rsatma manzili) ga uchadi 0x0
- bu, ehtimol, bir nechta xatolardan keyin sodir bo'ladi. Shuning uchun, xabar chiqarilgandan so'ng darhol BOOT
Keling, cheksiz halqa qo'shamiz. Bu uni biroz vaqtga kechiktiradi ...
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;
}
Bunday hiyla-nayrang kod "ishonchlilik uchun" ishlatiladi: men qaerdadir cheksiz tsikl aniqlanmagan xatti-harakat ekanligini eshitdim, lekin kompilyator taxmin qila olmaydi (sizga eslatib o'taman: 0x10000
BootROM joylashgan).
Ko'rinishidan, yana nimani kutish kerak - qattiq o'rnatilgan, qanday manba kodlari bor? Lekin ichida
(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.
Siz shunchaki MIF fayli yoki qutini emas, balki ELF formatidagi asl nusxasini yuklab olishingiz kerak.
Endi siz n-urinishda bajarilish davom etadigan manzilni taxmin qilishingiz mumkin (bu kompilyator tsiklning cheksiz ekanligini taxmin qilmasligining yana bir sababi). Jamoa
set variable $pc=0xADDR
registr qiymatini tezda o'zgartirishga imkon beradi (bu holda, joriy ko'rsatma manzili). Uning yordami bilan siz xotiraga yozilgan qiymatlarni o'zgartirishingiz mumkin (va xotira xaritasi registrlari).
Oxir-oqibat, men (qaysi biri to'g'ri ekanligiga ishonchim komil emas) bizda "noto'g'ri tizimning SD-karta tasviri" bor degan xulosaga keldim va biz yuklab olingan ma'lumotlarning eng boshiga emas, balki 0x89800
yana bayt:
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
Ehtimol, bunga qo'limda keraksiz 4 Gb karta yo'qligi sababli men 2 Gb kartani olib, tasodifiy Makefile-ga almashtirganim ham ta'sir qilgandir. DEMO_END=11718750
haqida DEMO_END=3078900
(aniq ma'noda ma'no izlamang - yo'q, shunchaki rasm kartaga joylashtirilgan).
Ikkinchi daraja, U-Boot
Endi biz hali ham "tushib ketyapmiz", lekin biz allaqachon to'g'ri joydamiz 0x0000000080089a84
. Bu erda tan olishim kerak: aslida taqdimot "barcha to'xtashlar bilan" o'tmaydi, lekin qisman "keyin" deb yoziladi, shuning uchun men allaqachon SoC-dan to'g'ri dtb faylini kiritishga muvaffaq bo'ldim, uni sozlamalarda to'g'rilab qo'ydim. HiFive_U-Boot
o'zgaruvchan CONFIG_SYS_TEXT_BASE=0x80089800
(o'rniga 0x08000000
) yuklab olish manzili haqiqiy manzilga mos kelishi uchun. Endi biz keyingi darajadagi xaritani, boshqa rasmni yuklaymiz:
(gdb) file ../freedom-u-sdk/work/HiFive_U-Boot/u-boot
(gdb) tui en
Va biz ko'ramiz:
│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) │
Bundan tashqari, biz 308 va 309 qatorlar orasiga o'tamiz. Va bu ajablanarli emas. $sp
ma'no yotadi 0xfffffffe31cdc0a0
. Afsuski, u ham 307-qator tufayli doimiy ravishda “qochib ketadi”. Shuning uchun, toʻxtash nuqtasini oʻrnatishga harakat qilaylik. trap_entry
, va keyin ga qayting 0x80089800
(U-Bootning kirish nuqtasi) va keling, u o'tishdan oldin registrlarni to'g'ri o'rnatishni talab qilmaydi deb umid qilaylik... Ishlayotganga o'xshaydi:
(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
Ochig'ini aytganda, stek ko'rsatkichi shunday: u RAMni butunlay chetlab o'tishni ko'rsatadi (agar, albatta, bizda manzil tarjimasi bo'lmasa, lekin oddiy variantga umid qilaylik).
Keling, ko'rsatgichni bilan almashtirishga harakat qilaylik 0x881cf950
. Natijada shunday xulosaga kelamiz handle_trap
qo'ng'iroq qildi va qo'ng'iroq qildi va shu bilan birga biz kiramiz _exit_trap
argument bilan epc=2148315240
(o'nlik bo'yicha):
(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
To'xtash nuqtasini o'rnating strnlen
, biz davom etamiz va ko'ramiz:
(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
Bo'lishi mumkin, _exit_trap
yuzaga kelgan istisno haqida disk raskadrovka ma'lumotlarini taqdim qilmoqchi, lekin qila olmaydi. Shunday qilib, qandaydir tarzda bizning manbalarimiz yana ko'rsatilmaydi. set directories ../freedom-u-sdk/HiFive_U-Boot/
HAQIDA! Endi ko'rsatiladi!
Keling, uni yana ishga tushiramiz va stekdan birinchi xatoga sabab bo'lgan asl muammoning sababini ko'rib chiqamiz (mcause == 5
). Agar nima yozilganini to'g'ri tushunsam Load access fault
. Buning sababi shu erda bo'lganga o'xshaydi
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
bir xil noto'g'ri ma'noga ega va ichida board_init_f_init_reserve
xatolik yuzaga keladi. Bu aybdorga o'xshaydi: aniq nomga ega o'zgaruvchi CONFIG_SYS_INIT_SP_ADDR
. Bu faylda aniqlangan HiFive_U-Boot/include/configs/HiFive-U540.h
. Bir payt men hatto protsessor uchun yuklash moslamasini qo'shishim kerak deb o'yladim - balki protsessorni biroz tuzatish osonroq bo'larmidi? Ammo keyin men bu ko'proq to'liq tugallanmagan artefaktga o'xshashligini ko'rdim#if 0
-boshqa xotira konfiguratsiyasi uchun maxsus sozlamalar va buni amalga oshirishga urinib ko'rishingiz mumkin:
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 */
Bir nuqtada tayoqchalar soni
Xo'sh, taxminan, bu erda kichik stol bor
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
Tafsilotlar bilan tanishishingiz mumkin
Ma'lum bo'lishicha, ushbu SiFive platasida ba'zi qurilmalar registrlari turli xil manzillarga ega. Bundan tashqari, U-Boot Linux yadrosidan allaqachon tanish bo'lgan Kconfig mexanizmi yordamida sozlanganligi ma'lum bo'ldi - masalan, siz buyruq berishingiz mumkin. make menuconfig
, va sizning oldingizda parametrlarning tavsiflarini ko'rsatadigan qulay matn interfeysi paydo bo'ladi ?
va hokazo. Umuman olganda, ikkita plataning tavsifidan uchinchisining tavsifini birlashtirib, u erdan har qanday dabdabali PLL rekonfiguratsiyasini chiqarib tashladik (ko'rinishidan, bu qandaydir tarzda PCIe orqali asosiy kompyuterdan boshqarish bilan bog'liq, ammo bu aniq emas) , Men Marsda to'g'ri ob-havo sharoitida UART orqali u qaysi xeshdan tuzilganligi va menda qancha DRAM borligi haqida xabar bergan ba'zi proshivka oldim (lekin men o'zim bu ma'lumotni sarlavhada yozganman).
Afsuski, shundan keyin plata odatda JTAG protsessori orqali javob berishni to'xtatdi va SD-kartadan yuklash, afsuski, mening konfiguratsiyamda tez emas. Boshqa tomondan, ba'zida BootROM bu haqda xabar berdi ERROR
, yuklanmadi va U-Boot darhol paydo bo'ldi. O'shanda bu menga tushdi: aftidan, bit oqimini FPGA-ga qayta ishga tushirgandan so'ng, xotira o'chirilmaydi, "mashqdan chiqarish" uchun vaqt yo'q va hokazo. Muxtasar qilib aytganda, siz shunchaki xabar paydo bo'lganda mumkin LOADING /
tuzatuvchi va buyruq bilan ulaning set variable $pc=0x80089800
, shu bilan bu uzoq yuklashni chetlab o'tish (albatta, oxirgi marta u etarlicha erta buzilgan va asl kodning ustiga hech narsa yuklashga ulgurmagan degan taxmin bilan).
Aytgancha, protsessorning to'liq muzlashi va JTAG tuzatuvchisi unga xabarlar bilan ulana olmasligi odatda normalmi?
Error: unable to halt hart 0
Error: dmcontrol=0x80000001
Error: dmstatus =0x00030c82
Xo'sh, kuting! Men buni allaqachon ko'rganman! TileLink blokirovka qilinganda shunga o'xshash narsa sodir bo'ladi va men qandaydir tarzda xotira kontrolleri muallifiga ishonmayman - men buni o'zim yozganman ... To'satdan, kontrollerni tahrir qilgandan so'ng protsessorni birinchi muvaffaqiyatli qayta qurishdan so'ng, men ko'rdim:
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
Oldin bu g'alati chiziqqa In: serial
e'tibor bermang - men osilgan protsessorda uning atrof-muhit bilan to'g'ri ishlashini tushunishga harakat qilardim. "O'n daqiqadan beri shunday osilgan" deganingiz nimani anglatadi? Hech bo'lmaganda u boshqa joyga ko'chib o'tishga va yuklash menyusiga o'tishga muvaffaq bo'ldi! Kichkina chekinish: U-Boot SD-kartadan dastlabki 2^24 baytda yuklangan bo'lsa-da, u ishga tushirilganda o'zini konfiguratsiya sarlavhasida yozilgan uzoqroq manzilga yoki oddiygina operativ xotiraning yuqori manzillariga ko'chiradi. , va ELF ko'chirish -belgilarni amalga oshiradi va u erda boshqaruvni uzatadi. Shunday qilib: biz bu darajadan o'tganga o'xshaymiz va bundan keyin protsessor mahkam osib qo'yilmagani uchun bonus oldik.
Xo'sh, nega taymer ishlamayapti? Negadir soat ishlamayapti shekilli...
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000
Agar o'qlarni qo'lda aylantirsangiz nima bo'ladi?
(gdb) set variable *0x0200bff8=310000000
(gdb) c
Keyin:
Hit any key to stop autoboot: 0
MMC_SPI: 0 at 0:1 hz 20000000 mode 0
Xulosa: soat tiqilmayapti. Ehtimol, shuning uchun klaviatura kiritish ishlamaydi:
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 == '[') {
...
Muammo shundaki, men juda aqlli edim: men kalitni protsessor konfiguratsiyasiga qo'shdim:
case DTSTimebase => BigInt(0)
... izohda "agar bilmasangiz, 0 qo'ying" deb yozilganiga asoslanib. Va nihoyat WithNBigCores
Men uni 1 MGts ga o'rnatdim (aytmoqchi, u U-Boot konfiguratsiyasida ko'rsatilgan). Lekin la'nat, men toza va sinchkovman: u erda bilmayman, bu erda 25 MGts! Oxir-oqibat, hech narsa ishlamaydi. Men "yaxshilanishlarimni" olib tashladim va...
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 #
Siz hatto buyruqlar kiritishingiz mumkin! Misol uchun, bir oz aylanib yurganingizdan so'ng, siz nihoyat kirishni taxmin qilishingiz mumkin mmc_spi 1 10000000 0; mmc part
, SPI chastotasini 20 MGts dan 10 MGts gacha kamaytirish. Nega? Xo'sh, 20MHz maksimal chastotasi konfiguratsiyada yozilgan va u hali ham u erda yozilgan. Lekin, men tushunganimdek, interfeyslar, hech bo'lmaganda, bu erda ishlaydi: kod apparat birligining chastotasini (meniki hamma joyda 25 MGts) maqsad bo'yicha ajratadi va natijada olingan qiymatni tegishli boshqaruvda bo'linuvchi sifatida o'rnatadi. ro'yxatdan o'tish. Muammo shundaki, agar 115200 Gts chastotali UART uchun taxminan zarur bo'lgan narsa bo'lsa, 25000000 ni 20000000 ga bo'lsangiz, siz 1 ni olasiz, ya'ni. u 25 MGts chastotada ishlaydi. Ehtimol, bu normaldir, lekin agar cheklovlar o'rnatilgan bo'lsa, demak, kimdir bunga muhtoj (lekin bu aniq emas) ... Umuman olganda, uni o'rnatish va davom ettirish osonroq - uzoq va, afsuski, uzoq vaqt. 25 MGts Core i9 emas.
Konsol chiqishi
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
Mayli, biz keyingi bosqichga yetdik, lekin u hali ham sovuq. Va ba'zida u ham istisnolarni sepadi. Ko'rsatilgan manzilda kodni kutish orqali mcauseni ko'rishingiz mumkin $pc
va keyin si
bo'l trap_entry
. U-Boot ishlov beruvchisining o'zi faqat mcause = 0..4 uchun chiqishi mumkin, shuning uchun noto'g'ri yuklashda qolib ketishga tayyor bo'ling. Keyin men konfiguratsiyaga kirdim, nimani o'zgartirayotganimni ko'rishni boshladim va esladim: u erda conf/rvboot-fit.txt
yozilgan:
fitfile=image.fit
# below much match what's in FIT (ugha)
Keling, barcha fayllarni moslashtiraylik, yadro buyruq qatorini shunga o'xshash narsa bilan almashtiraylik, chunki shubhalar mavjud. SIF0
- bu PCIe orqali chiqadigan joy:
-bootargs=console=ttySIF0,921600 debug
+bootargs=console=ttyS0,125200 debug
Va keling, xeshlash algoritmini SHA-256 dan MD5 ga o'zgartiraylik: menga kriptografik kuch kerak emas (ayniqsa disk raskadrovka paytida), bu juda uzoq vaqt talab etadi va yuklash paytida yaxlitlik xatolarini aniqlash uchun MD5 juda oson. Yakuniy natija nima? Biz oldingi darajani sezilarli darajada tezroq yakunlay boshladik (oddiyroq xeshlash tufayli) va keyingisi ochildi:
...
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
Lekin soat taqillamayapti...
(gdb) x/x 0x0200bff8
0x200bff8: 0x00000000
Voy, soatni to'g'rilash platsebo bo'lib chiqdi, garchi o'sha paytda menga yordam bergandek tuyuldi. Yo'q, albatta, uni tuzatish kerak, lekin avval o'qlarni qo'lda aylantiramiz va nima bo'lishini ko'raylik:
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.
Shu vaqtda…
Loading Kernel Image ... OK
Booting kernel in
3
2
1
0
## Starting application at 0x80000000 ...
Yo'q, men soatni avtomatlashtirishga boraman - aks holda u o'sha erda taymerni sozlashga qaror qiladi!
Ayni paytda, joriy yo'riqnomaning manzili biron bir joyga ishora qiladi
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>
yuklangan Berkeley Boot Loader ichida. Shaxsan meni bu haqda chalg'itadigan narsa bu eslatma htif
— yadroni bogʻlangan ishga tushirish uchun foydalaniladigan xost interfeysi (yaʼni ARM xost bilan hamkorlikda), men mustaqil deb hisobladim. Ammo, agar siz ushbu funktsiyani manba kodida topsangiz, hamma narsa unchalik yomon emasligini ko'rishingiz mumkin:
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"); }
}
}
Topshiriq: soatni boshlang
CLINT da registrlarni qidirish bizni olib boradi
val io = IO(new Bundle {
val rtcTick = Bool(INPUT)
})
val time = RegInit(UInt(0, width = timeWidth))
when (io.rtcTick) { time := time + UInt(1) }
Qaysi biri RTC yoki sirli MockAON bilan bog'lanadi, men dastlab o'ylagan edim: “Xo'sh, bu erda bizda nima bor? Tushunarsiz? Keling, uni o'chiraylik!" Men u erda qanday soat sehri sodir bo'layotganini hali ham tushunmaganim uchun, men bu mantiqni qayta ishlataman. 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 yadrosiga yo'l olamiz
Bu erda hikoya allaqachon cho'zilgan va biroz monoton bo'lib qolgan, shuning uchun men uni yuqoridan pastgacha tasvirlab beraman:
BBL da FDT mavjudligini taxmin qildi 0xF0000000
, lekin men uni allaqachon tuzatdim! Xo'sh, keling, yana ko'rib chiqaylik ... Uni ichidan topdim HiFive_U-Boot/arch/riscv/lib/boot.c, bilan almashtirildi 0x81F00000
, U-Boot yuklash konfiguratsiyasida ko'rsatilgan.
Keyin BBL xotira yo'qligidan shikoyat qildi. Mening yo'lim funktsiyada edi mem_prop
, qaysi riscv-pk/machine/fdt.c: u yerdan men fdt ram tugunini shunday belgilash kerakligini bilib oldim device_type = "memory"
- keyin, ehtimol, protsessor generatorini tuzatish kerak bo'ladi, lekin hozircha men uni qo'lda yozaman - baribir, men ushbu faylni qo'lda o'tkazdim.
Endi men xabarni oldim (formatlangan shaklda, vagon qaytarilishi bilan):
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.
Variantlar kerak bo'lganda ko'rsatilganga o'xshaydi riscv,kernel-start
и riscv,kernel-end
DTB da, lekin nollar tahlil qilinadi. Nosozliklarni tuzatish query_chosen
BBL 32-bitli manzilni tahlil qilishga urinayotganini ko'rsatdi, lekin u juftlikka duch keladi <0x0 0xADDR>
, va birinchi qiymat eng kam ahamiyatli bitlar kabi ko'rinadi. Bo'limga qo'shildi chosen
chosen {
#address-cells = <1>;
#size-cells = <0>;
...
}
va qadriyatlar avlodini tuzatdi: qo'shmang 0x0
birinchi element.
Ushbu 100500 XNUMX oddiy qadam pingvinning qulashini kuzatishni osonlashtiradi:
Yashirin matn
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)
(logotip BBL tomonidan, vaqt belgilariga ega bo'lgan esa yadro tomonidan ko'rsatiladi).
Yaxshiyamki, bu hamma joyda qandayligini bilmayman, lekin RocketChip-da, JTAG orqali tuzatuvchini ulaganingizda, siz qutidan tuzoqlarni ushlashingiz mumkin - tuzatuvchi aynan shu nuqtada to'xtaydi.
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
free-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); // < ВЫ НАХОДИТЕСЬ ЗДЕСЬ
}
Eski hazil aytganidek, CPU topilmadi, dasturiy ta'minot emulyatsiyasi ishlaydi. Xo'sh, yoki yugurmaslik. Bitta protsessor yadrosida yo'qolgan.
/* The lucky hart to first increment this variable will boot the other cores */
atomic_t hart_lottery;
unsigned long boot_cpu_hartid;
Yaxshi izoh linux/arch/riscv/kernel/setup.c - Tom Soyer usuli yordamida devorni bo'yashning bir turi. Umuman, bugun negadir g‘oliblar aniqlanmadi, sovrin keyingi o‘yinga o‘tkazildi...
Bu erda men allaqachon uzoq bo'lgan maqolani tugatishni taklif qilaman.
Davomi bor. Agar siz asta-sekin yakka qadam bilan o'rmalab chiqsangiz, yashirinishga muvaffaq bo'lgan ayyor xato bilan kurash bo'ladi.
Matnni yuklab olish skrinshoti (tashqi havola):
Manba: www.habr.com