-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Para migrar el proyecto del RiscvForth a un Riscv Real tengo que implementar rutinas que sustituyan las llamadas al sistema del Rars... Especialmente las llamadas al sistema de lectura de cadenas e impresión en la consola
Para ello voy a investigar y estudiar la herramienta "Keyboard and display MMIO emultaor" que viene con el RARs
Ya tengo un programa simple para imprimir caracteres (01-transiter.s). Las funciones de la UART están en el fichero uart.s
Para ponerlo en marcha hay que arrancar la herramienta del Keyboard and dipslay MMIO emulator. Ensamblar el programa, pinchar RESET en el emulador (NO EN EL RARS) y ejecutar. En la consola del emulador se mosgtrara el mensaje HI
Listo! Ya tengo la función de impresión implementada! (02-print.s)
Funcion de lectura funcionando!! (03-key.s)
Con la idea de hacer un ensamblador en Forth, que genere directamente código máquina, necesito evaluar un emulador de RV32I que sea sencillo... Veo que hay muchas alternativas, pero tengo que encontrar una que me sirva
Esta es una opción:
Pero lo veo demasiado complejo... no tengo claro si acepta fichero .bin con código máquina crudo (ni elf ni leches)...
He creado con el rars este programa: addi.s:
addi x1,x0,0xaaY he generado el fichero con el código máquina: addi.bin
Lo intento ejecutar con rv32emu, pero no lo consigo porque espera un elf:
obijuan@JANEL:~/Develop/rv32emu$ ./build/rv32emu addi.bin
rv32emu: src/riscv.c:231: rv_create: Assertion `elf && elf_open(elf, (attr->data.user)->elf_program)' failed.
Aborted (core dumped)
Este emulador tiene buena pinta, pero no me vale para hacer cosas básicas
Este es otro emulador, pero me temo que pasa lo mismo. Sólo admite elfs... (aunque no estoy 100% seguro)
Este otro funciona en el navegador... y tiene MUY BUENA PINTA... pero no permite cargar un .bin!!! o al menos no lo he encontrado!
Siiii!!! Tiene una opción para cargar un fichero .bin en la memoria... y se puede desensamblar... Joder.. este emulador es muy muy muy bueno!! De momento es el que voy a usar!!!!
Es una putada porque NO es opensource... vaya mierda....
Este emulador es buenísimo, y corre linux. En su momento lo he probado...PERO me da la sensación de que hay que pasarle un ELF... Tengo que probarlo. Le he dado a compilar pero parece que se está bajando las fuentes del kernel y lo está compilando!!!
obijuan@JANEL:~/Develop/mini-rv32ima$ make testdlimage
make -C mini-rv32ima testdlimage
make[1]: Entering directory '/home/obijuan/Develop/mini-rv32ima/mini-rv32ima'
./mini-rv32ima -f DownloadedImage
[ 0.000000] Linux version 6.1.14 (cnlohr@cnlohr-1520) (riscv32-buildroot-linux-uclibc-gcc.br_real (Buildroot 2023.02-145-gf6c5488ad2) 12.2.0, GNU ld (GNU Binutils) 2.38) #4 Sat Mar 25 09:20:08 EDT 2023
[ 0.000000] Machine model: riscv-minimal-nommu,qemu
[ 0.000000] earlycon: uart8250 at MMIO 0x10000000 (options '1000000')
[ 0.000000] printk: bootconsole [uart8250] enabled
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000080000000-0x0000000083ffefff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080000000-0x0000000083ffefff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x0000000083ffefff]
[ 0.000000] riscv: base ISA extensions aim
[ 0.000000] riscv: ELF capabilities aim
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 16255
[ 0.000000] Kernel command line: earlycon=uart8250,mmio,0x10000000,1000000 console=ttyS0
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[...]
[ 0.094783] printk: bootconsole [uart8250] disabled
[ 0.094783] printk: bootconsole [uart8250] disabled
``m[ 0.098349] Freeing unused kernel image (initmem) memory: 1464K
[ 0.098442] This architecture does not have kernel memory protection.
[ 0.098530] Run /init as init process
Welcome to Buildroot
buildroot login: root
Jan 1 00:00:03 login[28]: root login on 'console'
~ # ls
coremark duktapetest fizzbuzz.js hello_linux
~ # halt
~ # ls: /etc/init.d/S??*: No such file or directory
umount: devtmpfs busy - remounted read-only
umount: can't unmount /: Invalid argument
The system is going down NOW!
Sent SIGTERM to all processes
~ # [ 67.412651] reboot: System halted
POWEROFF@0x000000000b6293da
make[1]: Leaving directory '/home/obijuan/Develop/mini-rv32ima/mini-rv32ima'
obijuan@JANEL:~/Develop/mini-rv32ima$Voy a probar con el baremetal...
obijuan@JANEL:~/Develop/mini-rv32ima$ make testbare
make -C baremetal
make[1]: Entering directory '/home/obijuan/Develop/mini-rv32ima/baremetal'
../buildroot/output/host/bin/riscv32-buildroot-linux-uclibc-gcc -o baremetal.elf baremetal.c baremetal.S -fno-stack-protector -static-libgcc -fdata-sections -ffunction-sections -g -Os -march=rv32ima_zicsr -mabi=ilp32 -static -T flatfile.lds -nostdlib -Wl,--gc-sections
/home/obijuan/Develop/mini-rv32ima/buildroot/output/host/riscv32-buildroot-linux-uclibc/bin/ld.real: warning: baremetal.elf has a LOAD segment with RWX permissions
../buildroot/output/host/bin/riscv32-buildroot-linux-uclibc-objcopy baremetal.elf -O binary baremetal.bin
../buildroot/output/host/bin/riscv32-buildroot-linux-uclibc-objdump -t baremetal.elf > baremetal.debug.txt
../buildroot/output/host/bin/riscv32-buildroot-linux-uclibc-objdump -S baremetal.elf >> baremetal.debug.txt
make[1]: Leaving directory '/home/obijuan/Develop/mini-rv32ima/baremetal'
make -C mini-rv32ima testbare
make[1]: Entering directory '/home/obijuan/Develop/mini-rv32ima/mini-rv32ima'
./mini-rv32ima -f ../baremetal/baremetal.bin
Hello world from RV32 land.
main is at: 8000004c
Assembly code: I'm an assembly function.
Processor effective speed: 399 Mcyc/s
POWEROFF@0x00000000006ad000
make[1]: Leaving directory '/home/obijuan/Develop/mini-rv32ima/mini-rv32ima'
obijuan@JANEL:~/Develop/mini-rv32ima$Me he fijado en esta línea:
../buildroot/output/host/bin/riscv32-buildroot-linux-uclibc-objcopy baremetal.elf -O binary baremetal.binParece que pasa el elf a binario... a ver si hay suerte... Voy a probar con mi addi.bin:
Siiii.... He modificado addi.s para tener 2 instrucciones:
addi x1,x0,0xaa
addi x2,x0,0xbbEste es el resultado:
obijuan@JANEL:~/Develop/mini-rv32ima$ ./mini-rv32ima/mini-rv32ima -f addi.bin -c 1 -s
PC: 80000000 [0x0aa00093] Z:00000000 ra:00000000 sp:00000000 gp:00000000 tp:00000000 t0:00000000 t1:00000000 t2:00000000 s0:00000000 s1:00000000 a0:00000000 a1:83fff940 a2:00000000 a3:00000000 a4:00000000 a5:00000000 a6:00000000 a7:00000000 s2:00000000 s3:00000000 s4:00000000 s5:00000000 s6:00000000 s7:00000000 s8:00000000 s9:00000000 s10:00000000 s11:00000000 t3:00000000 t4:00000000 t5:00000000 t6:00000000
PC: 80000004 [0x0bb00113] Z:00000000 ra:000000aa sp:00000000 gp:00000000 tp:00000000 t0:00000000 t1:00000000 t2:00000000 s0:00000000 s1:00000000 a0:00000000 a1:83fff940 a2:00000000 a3:00000000 a4:00000000 a5:00000000 a6:00000000 a7:00000000 s2:00000000 s3:00000000 s4:00000000 s5:00000000 s6:00000000 s7:00000000 s8:00000000 s9:00000000 s10:00000000 s11:00000000 t3:00000000 t4:00000000 t5:00000000 t6:00000000
PC: 80000008 [0x00000000] Z:00000000 ra:000000aa sp:000000bb gp:00000000 tp:00000000 t0:00000000 t1:00000000 t2:00000000 s0:00000000 s1:00000000 a0:00000000 a1:83fff940 a2:00000000 a3:00000000 a4:00000000 a5:00000000 a6:00000000 a7:00000000 s2:00000000 s3:00000000 s4:00000000 s5:00000000 s6:00000000 s7:00000000 s8:00000000 s9:00000000 s10:00000000 s11:00000000 t3:00000000 t4:00000000 t5:00000000 t6:00000000
obijuan@JANEL:~/Develop/mini-rv32ima$ Vemos que al ejecutarse la primera instrucción (en la dirección 0x80000000) se pone ra a 0xaa (x1). Y con la siguiente instrucción sp (x2) a 0xbb... ¡Ya simulo!
Con esto puedo hacer pruebas...
Las BINutils de GNU tienen muchas utilidades para trabajar con código máquina, ensamblar, desensamblar... Quiero aprender a utilizarlas. He visto que en ubuntu se pueden instalar muy fácilmente de esta manera
sudo apt install binutils-riscv64-unknown-elfHay documentación de las binutils en estos enlaces:
- https://sourceware.org/binutils/docs/
- Wiki: https://sourceware.org/binutils/wiki/HomePage
- Wikipedia: https://es.wikipedia.org/wiki/GNU_Binutils
Biblioteca: Binary File Descriptor
Esta biblioteca contiene todo lo necesario para trabajar con ficheros objeto, que están en código máquina. Todas las herramientas que tienen que realizar operaciones con ficheros objetos usan esta biblioteca
Voy a leer la documentación para aprender más
No he encontrado mucha información que me interese. Hay mucha información para programar en C y hacerte tus aplicaciones, pero de momento no me interesa
Voy a echar un vistazo a este manual:
Aquí se describen todas las utilidades... Voy a elegir alguna
Esta utilidad sirve para mostrar información sobre ficheros objetos (y ejecutables)
Partimos de este programa de prueba en ensamblador:
- addi.s:
.text
addi x1,x0,0xaa
addi x2,x0,0xbbLo ensamblamos con el Rars 1.6 desde la línea de comandos: java -jar rars1_6.jar a dump .text Binary addi.bin addi.s
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ java -jar rars1_6.jar a dump .text Binary addi.bin addi.s
RARS 1.6 Copyright 2003-2019 Pete Sanderson and Kenneth VollmarPara desensamblar se utiliza -d. Pero si lo hacemos directamente se obtiene un error:
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-objdump -d addi.bin
riscv64-unknown-elf-objdump: addi.bin: file format not recognizedHay que espeficiar el formato del fichero objeto. Objdump normalmente detecta este formato automáticamente, pero en este caso tenemos un fichero binario, sin ninguna cabecera con información
Para conocer todos los formatos y arquitecturas de Objdump usamos el parámetro -i
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-objdump -i
BFD header file version (2.42-1ubuntu1+6) 2.42
elf64-littleriscv
(header little endian, data little endian)
riscv
elf32-littleriscv
(header little endian, data little endian)
riscv
elf32-bigriscv
(header big endian, data big endian)
riscv
elf64-bigriscv
(header big endian, data big endian)
riscv
pei-riscv64-little
(header little endian, data little endian)
riscv
elf64-little
(header little endian, data little endian)
riscv
elf64-big
(header big endian, data big endian)
riscv
elf32-little
(header little endian, data little endian)
riscv
elf32-big
(header big endian, data big endian)
riscv
srec
(header endianness unknown, data endianness unknown)
riscv
symbolsrec
(header endianness unknown, data endianness unknown)
riscv
verilog
(header endianness unknown, data endianness unknown)
riscv
tekhex
(header endianness unknown, data endianness unknown)
riscv
binary
(header endianness unknown, data endianness unknown)
riscv
ihex
(header endianness unknown, data endianness unknown)
riscv
plugin
(header little endian, data little endian)
elf64-littleriscv elf32-littleriscv elf32-bigriscv elf64-bigriscv
riscv elf64-littleriscv elf32-littleriscv elf32-bigriscv elf64-bigriscv
pei-riscv64-little elf64-little elf64-big elf32-little elf32-big srec
riscv pei-riscv64-little elf64-little elf64-big elf32-little elf32-big srec
symbolsrec verilog tekhex binary ihex plugin
riscv symbolsrec verilog tekhex binary ihex ------Para desensamblar entonces hay que usar -b binary para indicar que el fichero está en formato binario (y por tanto no tiene cabeceras) y -m riscv. Además hay que usar -D para indicar que desensamble TODAS las secciones. Como el binario no tiene cabecera, supone por defecto que son datos (y por defecto los datos no se desensamblan)
El comando para desensamblar es: riscv64-unknown-elf-objdump -b binary -m riscv -D -d addi.bin
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-objdump -b binary -m riscv -D -d addi.bin
addi.bin: file format binary
Disassembly of section .data:
0000000000000000 <.data>:
0: 0aa00093 li ra,170
4: 0bb00113 li sp,187Utilizando la opción -M no-aliases no se visualizan las pseudoinstrucciones, sino las instrucciones básicas:
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-objdump -b binary -m riscv -D -d -M no-aliases addi.bin
addi.bin: file format binary
Disassembly of section .data:
0000000000000000 <.data>:
0: 0aa00093 addi ra,zero,170
4: 0bb00113 addi sp,zero,187He visto en la documentación una opción para mostrar los registros con valores numéricos en vez de los nombres de la ABI, pero no me lo detecta. No sé si es porque en esta versión NO está implementando (que podría ser...)
La opción es -M gpr-names=numeric
Al probarla sale esto:
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-objdump -b binary -m riscv -D -d -M no-aliases -M gpr-names=numeric addi.bin
addi.bin: file format binary
Disassembly of section .data:
0000000000000000 <.data>:
0: BFD: unrecognized disassembler option: gpr-names
0aa00093 addi ra,zero,170
4: 0bb00113 addi sp,zero,187La versión que tengo instalada de las binutils es:
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-objdump -v
GNU objdump (2.42-1ubuntu1+6) 2.42
Copyright (C) 2024 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.La documentación que estoy leyendo es para la 2.43.... podría ser eso... o no
Con la opción --disassembler-color=on sale el código con resaltado de sintáxis...
Este es el comando que voy a usar para desensamblar:
riscv64-unknown-elf-objdump -b binary -m riscv -D -d -M no-aliases --disassembler-color=on addi.binOK, ya lo he encontrado, el parámetro es -M numeric. Con esto salen los registros como x0, x1, etc... en vez de los nombres de la ABI:
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-objdump -b binary -m riscv -D -d -M no-aliases -M numeric --disassembler-color=on addi.bin
addi.bin: file format binary
Disassembly of section .data:
0000000000000000 <.data>:
0: 0aa00093 addi x1,x0,170
4: 0bb00113 addi x2,x0,187Para mostrar los nemónicos en hexadecimal no encuentro la opción... bueno, de momento puedo vivir sin ello..
Esta es la utilidad para mostrar el tamaño de las secciones
obijuan@JANEL:~/Develop/Learn-RISCV/Log/2024-12-14$ riscv64-unknown-elf-size --target=binary addi.bin
text data bss dec hex filename
0 8 0 8 8 addi.binUtilidad para pasar el fichero objeto de un formato a otro
Hoy he recibido el libro "RISC-V Assembly Language" de Antohony J. Dos Reis. El libro es muy básico. Tal vez pensado para gente que empieza desde cero. Utiliza sus propias herramientas: El ensamblador rv, que te lo envía por correo. No he encotrado las fuentes... una pena. El contenido del fichero recibido lo he metido en este repo: rv
Los experimentos los estoy poniendo en esta otra parte de la wiki: RISCV Assembly Language