Hi,
My name is José J. many years ago, in a college operating systems class,
the professor mentioned Plan 9 as a curiosity — an OS where "everything is
a file". Recently, I’ve had more time, so I installed 9front from the ISO
on a few machines to explore and learn.
To get started with RISC-V, I tried creating a simple "Hello World" for
TinyEMU. I managed to output some characters using HTIF:
---h.c---
#include <u.h>
#define HTIFADDR_BASE 0x40008000
void
f(void)
{
*((volatile uvlong *) HTIFADDR_BASE) = 0x0101000000000031ull;
*((volatile uvlong *) HTIFADDR_BASE) = 0x0101000000000032ull;
*((volatile uvlong *) HTIFADDR_BASE) = 0x0101000000000033ull;
for(;;);
}
---
Compiled with:
%ic -FVw h.c
%il -l -H 1 -T0x80000000 -o h32.bin h.i
Then I wanted to improve it to print "Hello World", following this video
and GitHub repo:
- https://www.youtube.com/watch?v=HC7b1SVXoKM
- https://github.com/chuckb/riscv-helloworld-c/
The example is for Linux, but I tried to adapt it for Plan 9. Using QEMU in
Linux, I was able to print characters like before (with just h.c and no
functions). However, when I switched to using functions (helloq.c) and a
loader (chuck.s), it stopped working.
Here is the code:
---helloq.c---
#include <u.h>
#define UART_BASE 0x10000000
void
uartputc(char c)
{
*((volatile ulong *) UART_BASE) = c;
}
void
printstr(char *s)
{
while (*s)
uartputc(*s++);
}
void
main(void)
{
printstr("Hello world\n");
for (;;);
}
---
---chuck.s---
TEXT start(SB), $0
/* set stack pointer */
MOVW $0x80020000, R2
/* set frame pointer */
ADD R0, R2, R8
/* call main */
JAL R1, main(SB)
---
Compiled with:
ic -FVSw helloq.c
il -l -a -H 1 -T0x80000000 -R4 -o helloq.bin chuck.i helloq.i
The assembler generated is:
80000000: (1) TEXT start+0(SB),$4
* 80000000: 1161 (1) ADD $-8,R2 80000002: c006 (1)
MOVW R1,0(R2)*
80000004: 80020137 (3) MOV $-2147352576,R2
80000008: 00010433 (6) ADD R0,R2,R8
8000000c: 2091 (9) JAL ,R1,main+80000050(BRANCH)
8000000e: 0001 (0) ADD $0,R0,R0
80000010: (74) TEXT uartputc+0(SB),R0,$-4
80000010: 10000637 (74) MOV $268435456,R12
80000014: 01841593 4185d593(74) MOVB R8,R11
8000001c: 01859513 41855513(76) MOVB R11,R10
80000024: c208 (76) MOVW R10,0(R12)
80000026: 8082 (76) JMP ,0(R1)
80000028: (80) TEXT printstr+0(SB),R0,$4
80000028: 1161 (80) ADD $-8,R2
8000002a: c006 (80) MOVW R1,0(R2)
8000002c: 84a2 (80) MOV R8,R9
8000002e: 00048583 (82) MOVB 0(R9),R11
80000032: c999 (82) BEQ R11,80000048(BRANCH)
80000034: 00148613 (83) ADD $1,R9,R12
80000038: c632 (83) MOVW R12,s+0(FP)
8000003a: 00048403 (83) MOVB 0(R9),R8
8000003e: 3fc9 (83) JAL ,uartputc+80000010(BRANCH)
80000040: 44b2 (83) MOVW s+0(FP),R9
80000042: 00048583 (82) MOVB 0(R9),R11
80000046: f5fd (82) BNE R11,80000034(BRANCH)
80000048: 4082 (83) MOVW 0(R2),R1
8000004a: 0121 (83) ADD $8,R2
8000004c: 8082 (83) JMP ,0(R1)
8000004e: 0001 (0) ADD $0,R0,R0
80000050: (87) TEXT main+0(SB),R0,$4
80000050: 1161 (87) ADD $-8,R2
80000052: c006 (87) MOVW R1,0(R2)
80000054: 80018413 (89) MOV $.string<>+0(SB),R8
80000058: 3fc1 (89) JAL ,printstr+80000028(BRANCH)
8000005a: a001 (90) JMP ,30(APC)
----
However, when debugging with GDB in QEMU, I found that the instruction at
address *0x80000002* causes the PC (program counter) to reset, and
execution does not continue. I believe these extra instructions are added
by the loader automatically, but I don’t know how to prevent this.
I also tried using l.s from the 9legacy compiler sources, but had the same
result. I’ve been reading through start.s from the RISC-V kernel and
looking at the mkfile, suspecting I might need to pass specific options to
compile correctly, but there are too many and I don’t fully understand them
yet.
Can someone explain how to compile without these extra instructions, or why
the PC is being reset and how to avoid it?
Thanks in advance, and apologies for my English and the length of this
email.
Best regards,
José J.
------------------------------------------
9fans: 9fans
Permalink:
https://9fans.topicbox.com/groups/9fans/T3f252d4d7c5389ee-Maed6f4ac773a82fcbebf2b64
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription