Forum: FPGA, VHDL & Co. Bare Metal Programm per U-Boot starten


von Andre (Gast)


Lesenswert?

Hallo,

das Problem welches ich habe hat zwar nur indirekt was mit einem FPGA zu 
tun, da ich aber das zc706 Board von Xilinx verwendet und als IDE das 
SDK zu Verfügung steht, hat es wohl doch mit einem FPGA zu tun :)

Was ich vorhabe ist folgendes:
Ich will eine freeRTOS Application von einen TFTP-Server laden und 
starten:
Das funktioniert auch soweit:
Nach dem ich den FSBL und das u-boot.elf File in ein Bin-File verpackt 
habe, start ich das Bin-File von der SD -Karte.
Nach dem der u-boot gestartet ist, gebe ich folgendes ein:
1
Zynq> setenv ipaddr 192.168.xxx.101 
2
Zynq> setenv netmask 255.255.255.0
3
Zynq> setenv gatewayip 192.168.xxx.1
4
Zynq> serverip=192.168.150.100
5
Zynq> tftpboot 0x8000 FreeRTOS_HelloWorld.elf
6
Using ethernet@e000b000 device
7
TFTP from server 192.168.xxx.100; our IP address is 192.168.xxx.101
8
Filename 'FreeRTOS_HelloWorld.elf'.
9
Load address: 0x8000
10
Loading: ###############
11
         3 MiB/s
12
done
13
Bytes transferred = 205675 (3236b hex)


Start ich jedoch mit dem "go" Befehl. resetted sich das Board.
1
Zynq> go 0x8000
2
## Starting application at 0x00008000 ...
3
data abort
4
pc : [<000085ec>]          lr : [<3ff443c4>]
5
reloc pc : [<c40c65ec>]    lr : [<040023c4>]
6
sp : 3eb21d78  ip : c004cf82     fp : 3ff4437c
7
r10: 00000002  r9 : 3eb21ee8     r8 : 3ffaef30
8
r7 : 3eb2f820  r6 : 00008000     r5 : 00000002  r4 : c0054f82
9
r3 : 00008000  r2 : 3eb2f824     r1 : 3eb2f824  r0 : 00001004
10
Flags: nzCv  IRQs off  FIQs off  Mode SVC_32
11
Resetting CPU ...

Die loadAddress scheint nicht zu passen.
Versuche ich die BaseAdress + Offest, bleibt der Load-Vorgang hängen
1
Zynq> tftpboot 0x80008000 FreeRTOS_HelloWorld.elf
2
Using ethernet@e000b000 device
3
TFTP from server 192.168.xxx.100; our IP address is 192.168.xxx.101
4
Filename 'FreeRTOS_HelloWorld.elf'.
5
Load address: 0x80008000
6
Loading: #

Welche ist die richtig loadAddress um das Elf-File an die richtige 
Stelle zu kopieren um den mit dem "go"-Befehl die Applikation starten zu 
können.

Danke

von S. R. (svenska)


Lesenswert?

Kann U-Boot das ELF-File überhaupt parsen oder nimmt er es als 
Binärdatei? Ist an deiner Load-Adresse RAM, und passt der ENTRY dazu?

Probiere mal, eine passend konditionierte Binärdatei (oder Hex-Datei) zu 
laden.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

was willst du mit nem U-Boot? Minen suchen?
duck und wech

von yesitsme (Gast)


Lesenswert?

Ich denke du mußt aus der ELF-Datei erst ein Binary machen und dann den 
U-Boot-header hinzufügen.

Irgendwie so: 
https://www.denx.de/wiki/DULG/HowCanICreateAnUImageFromAELFFile

von Andre (Gast)


Lesenswert?

Hallo,

danke für die Antworten.

Was ich bisher versucht hab, um das Elf-File in ein Bin-File zu 
konvertieren, ist:

1)
1
arm-xilinx-linux-gnueabi-objcopy -O binary FreeRTOS_ZC706_HelloWorld.elf FreeRTOS_ZC706_HelloWorld.bin

2)
1
mkimage -A arm -O u-boot -T standalone -C none -a 0x00108000 -e 0x00108000 -n "FreeRTOS_ZC706_HelloWorld" -d FreeRTOS_ZC706_HelloWorld.bin uFreeRTOS_ZC706_HelloWorld.bin


Jedoch kommt beim "mkimage" Befehl diese Meldung:
1
mkimage: Can't map uFreeRTOS_ZC706_HelloWorld.bin: Invalid argument


Gruß
Andre

von Andre (Gast)


Lesenswert?

Eine weitere Frage:

In dem Doc steht:
http://elk.informatik.hs-augsburg.de/tmp/elinux/u-boot.git/doc/README.standalone 
(Abschnitt 4)

dass ist die Load bzw Start address für den ARM 0x0c100000 ist.

Kann man die Application nicht eine anderen Adresse zuweisen?

von Strubi (Gast)


Lesenswert?

Moin,

habe das bisher nur für andere Plattformen gemacht aber, prinzipiell 
musst du nur im Linker-Script die passenden Offsets einrichten. Dann 
kannst du's aus u-boot per 'bootelf' laden und die ganzen Klimmzüge mit 
mkimage usw. sind nicht nötig.

von Andre (Gast)


Lesenswert?

Strubi schrieb:
> habe das bisher nur für andere Plattformen gemacht aber, prinzipiell
> musst du nur im Linker-Script die passenden Offsets einrichten. Dann
> kannst du's aus u-boot per 'bootelf' laden und die ganzen Klimmzüge mit
> mkimage usw. sind nicht nötig.

Was ich bisher gesehen bzw gefunden habe, ist dass man die 
UIMAGE_LOADADDR beim Bauen eines Linux Images mit angeben kann.
1
make UIMAGE_LOADADDR 0x8000 uImage

Oder wo kann man den Offset beim U-boot setzen?

von Andre (Gast)


Lesenswert?

Ich habe das gleiche aus dem SDK versucht:
Xilinx Tools-> Create Boot Image:
Hier habe ich den folgende Partitionen angelegt:
FSBL
u-boot.elf
uFreeRTOS_ZC706_HelloWorld.elf       -> Offset= 0x0c100000

Hier fährt der u-boot hoch, jedoch wieder ohne die Applikation zu 
starten.



Die environment variables sind:
1
printenv
2
baudrate=115200
3
bitstream_image=system.bit.bin
4
boot_image=BOOT.bin
5
boot_size=0xF00000
6
bootcmd=run $modeboot
7
bootdelay=2
8
bootenv=uEnv.txt
9
devicetree_image=devicetree.dtb
10
devicetree_load_address=0x2000000
11
devicetree_size=0x20000
12
dfu_mmc=run dfu_mmc_info && dfu 0 mmc 0
13
dfu_mmc_info=set dfu_alt_info ${kernel_image} fat 0 1\\;${devicetree_image} fat 0 1\\;${ramdisk_image} fat 0 1
14
dfu_ram=run dfu_ram_info && dfu 0 ram 0
15
dfu_ram_info=set dfu_alt_info ${kernel_image} ram 0x3000000 0x500000\\;${devicetree_image} ram 0x2A00000 0x20000\\;${ramdisk_image} ram 0x2000000 0x600000
16
ethaddr=00:0a:35:00:01:22
17
fdt_high=0x20000000
18
fdtcontroladdr=3ffa6ee0
19
fileaddr=2000000
20
filesize=62
21
gatewayip=192.168.150.1
22
importbootenv=echo Importing environment from SD ...; env import -t ${loadbootenv_addr} $filesize
23
initrd_high=0x20000000
24
ipaddr=192.168.150.101
25
jtagboot=echo TFTPing Linux to RAM... && tftpboot ${kernel_load_address} ${kernel_image} && tftpboot ${devicetree_load_address} ${devicetree_image} && tftpboot ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
26
kernel_image=uImage
27
kernel_load_address=0x2080000
28
kernel_size=0x500000
29
loadbit_addr=0x100000
30
loadbootenv=load mmc 0 ${loadbootenv_addr} ${bootenv}
31
loadbootenv_addr=0x2000000
32
mmc_loadbit=echo Loading bitstream from SD/MMC/eMMC to RAM.. && mmcinfo && load mmc 0 ${loadbit_addr} ${bitstream_image} && fpga load 0 ${loadbit_addr} ${filesize}
33
modeboot=sdboot
34
nandboot=echo Copying Linux from NAND flash to RAM... && nand read ${kernel_load_address} 0x100000 ${kernel_size} && nand read ${devicetree_load_address} 0x600000 ${devicetree_size} && echo Copying ramdisk... && nand read ${ramdisk_load_address} 0x620000 ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
35
netmask=255.255.255.0
36
norboot=echo Copying Linux from NOR flash to RAM... && cp.b 0xE2100000 ${kernel_load_address} ${kernel_size} && cp.b 0xE2600000 ${devicetree_load_address} ${devicetree_size} && echo Copying ramdisk... && cp.b 0xE2620000 ${ramdisk_load_address} ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
37
preboot=if test $modeboot = sdboot && env run sd_uEnvtxt_existence_test; then if env run loadbootenv; then env run importbootenv; fi; fi; 
38
qspiboot=echo Copying Linux from QSPI flash to RAM... && sf probe 0 0 0 && sf read ${kernel_load_address} 0x100000 ${kernel_size} && sf read ${devicetree_load_address} 0x600000 ${devicetree_size} && echo Copying ramdisk... && sf read ${ramdisk_load_address} 0x620000 ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_loa
39
d_address}
40
ramdisk_image=uramdisk.image.gz
41
ramdisk_load_address=0x4000000
42
ramdisk_size=0x5E0000
43
rsa_jtagboot=echo TFTPing Image to RAM... && tftpboot 0x100000 ${boot_image} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
44
rsa_nandboot=echo Copying Image from NAND flash to RAM... && nand read 0x100000 0x0 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
45
rsa_norboot=echo Copying Image from NOR flash to RAM... && cp.b 0xE2100000 0x100000 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
46
rsa_qspiboot=echo Copying Image from QSPI flash to RAM... && sf probe 0 0 0 && sf read 0x100000 0x0 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
47
rsa_sdboot=echo Copying Image from SD to RAM... && load mmc 0 0x100000 ${boot_image} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
48
sd_uEnvtxt_existence_test=test -e mmc 0 /uEnv.txt
49
sdboot=if mmcinfo; then run uenvboot; echo Copying Linux from SD to RAM... && load mmc 0 ${kernel_load_address} ${kernel_image} && load mmc 0 ${devicetree_load_address} ${devicetree_image} && load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; fi
50
serverip=192.168.150.100
51
stderr=serial@e0001000
52
stdin=serial@e0001000
53
stdout=serial@e0001000
54
thor_mmc=run dfu_mmc_info && thordown 0 mmc 0
55
thor_ram=run dfu_ram_info && thordown 0 ram 0
56
uenvboot=if run loadbootenv; then echo Loaded environment from ${bootenv}; run importbootenv; fi; if test -n $uenvcmd; then echo Running uenvcmd ...; run uenvcmd; fi
57
usbboot=if usb start; then run uenvboot; echo Copying Linux from USB to RAM... && load usb 0 ${kernel_load_address} ${kernel_image} && load usb 0 ${devicetree_load_address} ${devicetree_image} && load usb 0 ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; fi
58
59
Environment size: 4949/131068 bytes

Gruss

von Andre (Gast)


Lesenswert?

In der Verzeichnisstruktur des u-boot unter ist das Config-File für den 
Arm:
1
u-boot-xlnx/arch/arm/config.mk

gibt es folgende Zeile
1
#ifndef CONFIG_STANDALONE_LOAD_ADDR
2
#ifneq ($(CONFIG_ARCH_OMAP2),)
3
CONFIG_STANDALONE_LOAD_ADDR = 0x80300000
4
#else
5
CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
6
#endif
7
#endif

An an beiden Speicher lässt sich eine Applikation laden.

von Andre (Gast)


Lesenswert?

Andre schrieb:
> In der Verzeichnisstruktur des u-boots ist das Config-File für den Arm:

> An an beiden Speicheradressen lässt sich keine Applikation laden.

von Strubi (Gast)


Lesenswert?

Jo, dann musst du einfach dein ELF per Linkerscript an diesen Bereich 
allozieren. Der ELF-Loader macht den Rest. Du musst nur gucken, dass du 
keine bestehenden u-boot-Routinen überschreibst, sonst sollte das gehen.
Sonst musst du halt mit dem Debugger ran.

von Andre (Gast)


Lesenswert?

Aber eine generelle Frage:
Musst im Image(FSBL,SSBL, Hello_World.elf) ein Bit-File enthalten sein, 
welches den FPGA programmiert, um nur den PS-Bereich zu steuern?

von Andre (Gast)


Angehängte Dateien:

Lesenswert?

Strubi schrieb:
> Jo, dann musst du einfach dein ELF per Linkerscript an diesen Bereich
> allozieren. Der ELF-Loader macht den Rest. Du musst nur gucken, dass du
> keine bestehenden u-boot-Routinen überschreibst, sonst sollte das gehen.
> Sonst musst du halt mit dem Debugger ran.


Was ich bisher gemacht habe um das Memory-Mapping zuverstehen:
1
1)Xilinx SDK
2
  Xilinx Tools -> Create Image:
3
  FSBL              (bootloader)
4
  Hello_World.elf   (datafile)
5
  
6
  
7
  lscript.ld (FSBL)                       Base Address    Size
8
  ps7_ram_0_S_AXI_BASEADDR                0x00000000      0x00030000
9
  ps7_ram_1_S_AXI_BASEADDR                0xFFFF0000      0x0000FE00
10
  
11
  lscript.ld (Hello_World.elf)            Base Address    Size
12
  ps7_ddr_0_S_AXI_BASEADDR                0x100000        0x3FF00000                    
13
  ps7_qspi_linear_0_S_AXI_BASEADDR        0xFC000000      0x2000000
14
  ps7_ram_0_S_AXI_BASEADDR                0x0             0x30000
15
  ps7_ram_1_S_AXI_BASEADDR                0xFFFF0000      0x0000FE00
  ---> Die Applikation startet.

Füge ich nun den u-boot in das Image ein, startet der  SSBL(u-boot) 
jedoch nicht die Applikation.
1
2)Xilinx SDK
2
  Xilinx Tools -> Create Image:
3
  FSBL              (bootloader)
4
  u-boot.elf        (datafile)
5
  Hello_World.elf   (datafile)
  ---> Die Applikation startet nicht.

Wie passt das Memory-Mapping mit dem Standalone-Angaben des u-boots 
zusammen?
1
#ifndef CONFIG_STANDALONE_LOAD_ADDR
2
#ifneq ($(CONFIG_ARCH_OMAP2),)
3
CONFIG_STANDALONE_LOAD_ADDR = 0x80300000
4
#else
5
CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
6
#endif
7
#endif


Kann es sein, dass bestimmte Adressen bei der Erstellung der Partition 
eingegeben werden müssen (siehe Bild)?

von Andre (Gast)


Lesenswert?

Nach dem Starten des u-boots und des Befehlts "bdinfo", kommt folgende 
Ausgabe:
1
Zynq> bdinfo
2
arch_number = 0x00000000
3
boot_params = 0x00000000
4
DRAM bank   = 0x00000000
5
-> start    = 0x00000000
6
-> size     = 0x40000000
7
baudrate    = 115200 bps
8
TLB addr    = 0x3FFF0000
9
relocaddr   = 0x3FF42000
10
reloc off   = 0x3BF42000
11
irq_sp      = 0x3EB21ED0
12
sp start    = 0x3EB21EC0
13
ARM frequency = 666 MHz
14
DSP frequency = 0 MHz
15
DDR frequency = 533 MHz
16
Early malloc usage: 49c / 600

von Andre (Gast)


Lesenswert?

Zur Lösung, falls jemand über die gleiche oder ähnliche Problematik 
stolpert:
Das Xilinx SDK liefert als Output ein Elf-File, was der u-boot versteht:
1
tftpboot 0x000000 FreeRTOS_ZC706_HelloWorld.elf
2
bootelf 0x0

Schönes Wochenende

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.