From 320c30dac3a66ddc9acb9840444ce52a73d665e6 Mon Sep 17 00:00:00 2001 From: Drew Bednar Date: Sun, 18 Aug 2024 21:54:33 -0400 Subject: [PATCH] Initial commits --- README.md | 77 +++++++++ RISC-V-ALE/hello/Makefile | 9 ++ RISC-V-ALE/hello/README.md | 4 + RISC-V-ALE/hello/hello | Bin 0 -> 784 bytes RISC-V-ALE/hello/hello.o | Bin 0 -> 784 bytes RISC-V-ALE/hello/hello.s | 17 ++ chuckstechtalk/hello_asm/Makefile | 14 ++ chuckstechtalk/hello_asm/README.md | 219 ++++++++++++++++++++++++++ chuckstechtalk/hello_asm/baremetal.ld | 11 ++ chuckstechtalk/hello_asm/hello | Bin 0 -> 8756 bytes chuckstechtalk/hello_asm/hello.o | Bin 0 -> 920 bytes chuckstechtalk/hello_asm/hello.s | 27 ++++ chuckstechtalk/helloc/hello.c | 0 lowlevellearning/Makefile | 7 + lowlevellearning/hello | Bin 0 -> 1408 bytes lowlevellearning/hello.o | Bin 0 -> 1208 bytes lowlevellearning/hello.s | 30 ++++ 17 files changed, 415 insertions(+) create mode 100644 README.md create mode 100644 RISC-V-ALE/hello/Makefile create mode 100644 RISC-V-ALE/hello/README.md create mode 100755 RISC-V-ALE/hello/hello create mode 100644 RISC-V-ALE/hello/hello.o create mode 100644 RISC-V-ALE/hello/hello.s create mode 100644 chuckstechtalk/hello_asm/Makefile create mode 100644 chuckstechtalk/hello_asm/README.md create mode 100644 chuckstechtalk/hello_asm/baremetal.ld create mode 100755 chuckstechtalk/hello_asm/hello create mode 100644 chuckstechtalk/hello_asm/hello.o create mode 100644 chuckstechtalk/hello_asm/hello.s create mode 100644 chuckstechtalk/helloc/hello.c create mode 100644 lowlevellearning/Makefile create mode 100755 lowlevellearning/hello create mode 100644 lowlevellearning/hello.o create mode 100644 lowlevellearning/hello.s diff --git a/README.md b/README.md new file mode 100644 index 0000000..d768097 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# Hello RISCV + +To develop on your x86_64 desktop PC you need QEMU and the GNU riscv compiler toolchain. + +``` +sudo apt-get install qemu qemu-system-misc gcc-riscv64-linux-gnu sudo apt install gcc-riscv64-unknown-elf +``` + + + +## Checking your toolchain + +If you are building binaries to target a Linux system: +``` +riscv64-linux-gnu-as --version +``` + +For building standalone Executable and Linkable Format (ELF) binaries that are not tied to any specific operating system use: + +``` +riscv64-unknown-elf-as --version +``` + +The output object files are lined against a bare-metall environment or an embedded system that does not rely on an OS. Might use Newlib or another lightweight C lib instead of glibc. Good for embedded systems, bootloaders, or bare metal apps that have no operating system. + +### The typical build workflow + +You will want to know the following two(three) values for your build target: + +-`march=ISA` selects the architecture to target. This controls which instructions and registers are available for the compiler to use. Describes which hardware generated code can run on +-`mabi=ABI` selects the ABI to target. This controls the calling convention (which arguments are passed in which registers) and the layout of data in memory. Describes which software generated code can link against. In order for objects to be linked together, they must follow the same ABI. + - ilp32: int, long, and pointers are all 32bits, long is a 64 bit type, char 8 bit, short 16 bit. No floating point registers. + - lp64: long and pointers are 64 bits long, while int is 32 bit type. The other types remain the same as ilp32 + - ilp32f: Same as ipl32 but with 32 bit and smaller floating point arguments are passed in registers. This ABI requires the F extension. + - ilp32d: 64 bit and smaller floating point arguments,are passed in registers. ABI requires the D extension. + - etc. +-`mtune=CODENAME` selects the microarchitecture to target. This informs GCC about the performance of each instruction, allowing it to perform target-specific optimizations. Most times you will not need to use this argument. + +See: [The -march, -mabi, and -mtune arguments to RISC-V Compilers](https://www.sifive.com/blog/all-aboard-part-1-compiler-args) for more detail. + +Example: If our target has integer, multiplication, atomic memory operations, and compressed instructions extensions then our assembler command would look like: + +``` +riscv64-linux-gnu-as -march=rv32imac -mabi=ilp32 ... +``` + + +## Using QEMU + +Ensure it's installed + +``` +qemu-system-riscv --version +``` + +``` +qemu-system-riscv32 -machine help +Supported machines are: +none empty machine +opentitan RISC-V Board compatible with OpenTitan +sifive_e RISC-V Board compatible with SiFive E SDK +sifive_u RISC-V Board compatible with SiFive U SDK +spike RISC-V Spike board (default) +virt RISC-V VirtIO board +toor@toor-jammy-jellifish:~/experiments/learn_r +``` + +We are going to focus on the `virt` machine type. + +## Resources + +- [RISC-V Instruction Set Manual](https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf) +- [Linux Kernel system calls for all architectures](https://gpages.juszkiewicz.com.pl/syscalls-table/syscalls.html) +- [RISC-V ASM Manual](https://github.com/riscv-non-isa/riscv-asm-manual/blob/main/riscv-asm.md) +- [Sample RISC-V ASM Programs](https://marz.utk.edu/my-courses/cosc230/book/example-risc-v-assembly-programs/) +- [RISC-V Assembly Programming](https://riscv-programming.org/) Includes a book, exercises, and a simulator +- [The -march, -mabi, and -mtune arguments to RISC-V Compilers](https://www.sifive.com/blog/all-aboard-part-1-compiler-args) \ No newline at end of file diff --git a/RISC-V-ALE/hello/Makefile b/RISC-V-ALE/hello/Makefile new file mode 100644 index 0000000..c20d876 --- /dev/null +++ b/RISC-V-ALE/hello/Makefile @@ -0,0 +1,9 @@ +run: build + # qemu-system-riscv32 -machine virt -m 128M -bios none -device loader,file=./hello -nographic + qemu-system-riscv32 -machine virt -m 128M -bios none -kernel hello -nographic + + +build: + rm -rf hello + riscv64-unknown-elf-as -march=rv32i -mabi=ilp32 hello.s -o hello.o + riscv64-unknown-elf-ld -m elf32lriscv hello.o -o hello diff --git a/RISC-V-ALE/hello/README.md b/RISC-V-ALE/hello/README.md new file mode 100644 index 0000000..0157568 --- /dev/null +++ b/RISC-V-ALE/hello/README.md @@ -0,0 +1,4 @@ +# Another Hello World + +Unlike the Low Level Learning example that used `riscv64-linux-gnu-as` this project is targeting `riscv64-unknown-elf-as` and we will use QEMU to emulate a RISC-V environment to run our ELF executable in. + diff --git a/RISC-V-ALE/hello/hello b/RISC-V-ALE/hello/hello new file mode 100755 index 0000000000000000000000000000000000000000..7688be9f27a7379384709803af0e6021d155274a GIT binary patch literal 784 zcma)4%}&BV5S}fRpciY1i9eS%G0{^)fJCn#C?p0CaCXy51C5oE?uvNwWa5Dv2VcR* z@ezCh55@=3nU>blaBz~@Z@zD)vyt_QKvqWVyCU_~ngM7Xl_0zEah`1JW z25sc=eHwmulF6TC_*I5qXE@!T?hhkci0Olnfjb@ocg6$YeCYYMk`{m|9`B@OBg!DcQ5;EUCczB1Z(0(E zu{ZyU9A-6z&n*VO$2#35P# literal 0 HcmV?d00001 diff --git a/RISC-V-ALE/hello/hello.o b/RISC-V-ALE/hello/hello.o new file mode 100644 index 0000000000000000000000000000000000000000..1c6fe0f00fbd544c7b67efbf890896ffa7d607c8 GIT binary patch literal 784 zcma)4!A`r`s&3zP=vASts?>xY_78Ms@Pv;QrVMaQVx_ zMIlw}&65td1Zuf>jl7VH=aj^Shs|7~BGa@{{lN`7@t}vWUH8$^CQ?RZGG{9rCax(- zB0aOX;5Ls?Ki!+COK;T7-&&^PBnnOZXb|=y6CvzsjWE5WFf!bs`(R?Z(0{_GPM$1V z1M+UiGz)tNyG#f_$qFqt$va4&^h<4(wx7lJ#uLVQh*oe&lmGvh?r5eN(WQ`iI~f;e s=ZRm+DQaw#&&#=ZVMf6tp4R=O4Gynhq literal 0 HcmV?d00001 diff --git a/RISC-V-ALE/hello/hello.s b/RISC-V-ALE/hello/hello.s new file mode 100644 index 0000000..72a4fc0 --- /dev/null +++ b/RISC-V-ALE/hello/hello.s @@ -0,0 +1,17 @@ +.global _start + +_start: + li a0, 1 # file descriptor = 1 (stdout) + la a1, string # buffer + li a2, 19 # size + li a7, 64 # syscall write (64) + ecall + +_end: + + li a0, 0 # exit code + li a7, 93 # syscall exit + ecall + + +string: .asciz "Hello! It works!!!\n" diff --git a/chuckstechtalk/hello_asm/Makefile b/chuckstechtalk/hello_asm/Makefile new file mode 100644 index 0000000..1e36597 --- /dev/null +++ b/chuckstechtalk/hello_asm/Makefile @@ -0,0 +1,14 @@ +default: hello + +hello: hello.o baremetal.ld + riscv64-unknown-elf-gcc -T baremetal.ld -march=rv32i -mabi=ilp32 -nostdlib -static -o hello hello.o + +hello.o: hello.s + riscv64-unknown-elf-as -march=rv32i -mabi=ilp32 hello.s -o hello.o + +run: hello + @echo "Ctrl-A C for QEMU console, then quit to exit" + qemu-system-riscv32 -nographic -serial mon:stdio -machine virt -bios hello + +clean: + rm hello hello.o diff --git a/chuckstechtalk/hello_asm/README.md b/chuckstechtalk/hello_asm/README.md new file mode 100644 index 0000000..8b3f755 --- /dev/null +++ b/chuckstechtalk/hello_asm/README.md @@ -0,0 +1,219 @@ +# Baremetal RISC-V + +Ok this chuck guy knows his stuff it seems https://www.youtube.com/watch?v=qLzD33xVcRE + +`barmetal.ld` contains the linker scripts. + +The `SECTIONS` keyword indicates the beginning of the linker script sections where he specifies the memory layout, and the sections of the program. + +``` +{ + . = 0x800000000; +} +``` + +This sets the location counter to the 0x800000000 memory address. This means that the following sections of the linker script will be placed as if starting from this address in memory. This is important because we need to know where in memory to load our application, so that the cpu boots we know what address will be loaded into the program counter to start executing instructions. + +ADD MORE DETAILS + +## QEMU + +Run this command + +``` +qemu-system-riscv32 -nographic -serial mon:stdio -machine virt +``` + +If you encounter +``` +qemu-system-riscv32: Unable to load the RISC-V firmware "opensbi-riscv32-generic-fw_dynamic.bin" +``` + +Well it's going to suck a little. Running `sudo apt install opensbi` only appears to include qemu-system-riscv64 builds. I tried building from source and hit a ton of issues, so instead I untarred a binary release in my home directory + +``` +wget https://github.com/riscv-software-src/opensbi/releases/download/v1.5.1/opensbi-1.5.1-rv-bin.tar.xz +tar -xf opensbi-1.5.1-rv-bin.tar.xz -C ~/ +ls ~/opensbi-1.5.1-rv-bin +``` + +``` +qemu-system-riscv32 -nographic -serial mon:stdio -machine virt -bios ~/opensbi-1.5.1-rv-bin/share/opensbi/ilp32/generic/firmware/fw_dynamic.bin +``` + +Now we can continue... + +We start qemu in `-nographic` mode. We redirect the console input/output to our terminal `-serial mon:stdio`, and we start the `virt` machine type that we will do the simulation under. + + +``` +OpenSBI v1.5.1 + ____ _____ ____ _____ + / __ \ / ____| _ \_ _| + | | | |_ __ ___ _ __ | (___ | |_) || | + | | | | '_ \ / _ \ '_ \ \___ \| _ < | | + | |__| | |_) | __/ | | |____) | |_) || |_ + \____/| .__/ \___|_| |_|_____/|____/_____| + | | + |_| + +Platform Name : riscv-virtio,qemu +Platform Features : medeleg +Platform HART Count : 1 +Platform IPI Device : aclint-mswi +Platform Timer Device : aclint-mtimer @ 10000000Hz +Platform Console Device : semihosting +Platform HSM Device : --- +Platform PMU Device : --- +Platform Reboot Device : syscon-reboot +Platform Shutdown Device : syscon-poweroff +Platform Suspend Device : --- +Platform CPPC Device : --- +Firmware Base : 0x80000000 +Firmware Size : 319 KB +Firmware RW Offset : 0x40000 +Firmware RW Size : 63 KB +Firmware Heap Offset : 0x47000 +Firmware Heap Size : 35 KB (total), 2 KB (reserved), 9 KB (used), 23 KB (free) +Firmware Scratch Size : 4096 B (total), 240 B (used), 3856 B (free) +Runtime SBI Version : 2.0 + +Domain0 Name : root +Domain0 Boot HART : 0 +Domain0 HARTs : 0* +Domain0 Region00 : 0x00100000-0x00100fff M: (I,R,W) S/U: (R,W) +Domain0 Region01 : 0x02000000-0x0200ffff M: (I,R,W) S/U: () +Domain0 Region02 : 0x0c200000-0x0c20ffff M: (I,R,W) S/U: (R,W) +Domain0 Region03 : 0x80040000-0x8004ffff M: (R,W) S/U: () +Domain0 Region04 : 0x80000000-0x8003ffff M: (R,X) S/U: () +Domain0 Region05 : 0x0c000000-0x0c1fffff M: (I,R,W) S/U: (R,W) +Domain0 Region06 : 0x00000000-0xffffffff M: () S/U: (R,W,X) +Domain0 Next Address : 0x00000000 +Domain0 Next Arg1 : 0x87000000 +Domain0 Next Mode : S-mode +Domain0 SysReset : yes +Domain0 SysSuspend : yes + +Boot HART ID : 0 +Boot HART Domain : root +Boot HART Priv Version : v1.10 +Boot HART Base ISA : rv32imafdc +Boot HART ISA Extensions : zicntr +Boot HART PMP Count : 16 +Boot HART PMP Granularity : 2 bits +Boot HART PMP Address Bits: 32 +Boot HART MHPM Info : 0 (0x00000000) +Boot HART Debug Triggers : 0 triggers +Boot HART MIDELEG : 0x00000222 +Boot HART MEDELEG : 0x0000b109 +``` + +We see that our `Firmware Base : 0x80000000` is address where the firmware should be loaded from. You can also see that `Domain0 Region04 : 0x80000000-0x8003ffff M: (R,X) S/U: ()` this region is marked as X for executable. + +How do we know that the serial UART is at 0x10000000? This UART is defined as a NS16550 Uart in https://www.qemu.org/docs/master/system/riscv/virt.html +Looking at the [UART16550 Core technical manual](https://uart16550.readthedocs.io/en/latest/uart16550doc.html#registers) we see that `Transmitter Holding Register (THR)` is at Address 0. Lastly, we want to enter the qemu console, so `Ctrl-A C` will take us to the qemu console. We want to inspect the `info mtree` output we can see that the `0000000010000000-0000000010000007 (prio 0, i/o): serial` serial device memory location starts at 0x10000000. So since the register the THR is at 0, we know we can use that as our UART target. + + +``` +(qemu) info mtree +(qemu) info mtree +address-space: memory + 0000000000000000-ffffffffffffffff (prio 0, i/o): system + 0000000000001000-000000000000ffff (prio 0, rom): riscv_virt_board.mrom + 0000000000100000-0000000000100fff (prio 0, i/o): riscv.sifive.test + 0000000000101000-0000000000101023 (prio 0, i/o): goldfish_rtc + 0000000002000000-0000000002003fff (prio 0, i/o): riscv.aclint.swi + 0000000002004000-000000000200bfff (prio 0, i/o): riscv.aclint.mtimer + 0000000003000000-000000000300ffff (prio 0, i/o): gpex_ioport_window + 0000000003000000-000000000300ffff (prio 0, i/o): gpex_ioport + 000000000c000000-000000000c20ffff (prio 0, i/o): riscv.sifive.plic + 0000000010000000-0000000010000007 (prio 0, i/o): serial + 0000000010001000-00000000100011ff (prio 0, i/o): virtio-mmio + 0000000010002000-00000000100021ff (prio 0, i/o): virtio-mmio + 0000000010003000-00000000100031ff (prio 0, i/o): virtio-mmio + 0000000010004000-00000000100041ff (prio 0, i/o): virtio-mmio + 0000000010005000-00000000100051ff (prio 0, i/o): virtio-mmio + 0000000010006000-00000000100061ff (prio 0, i/o): virtio-mmio + 0000000010007000-00000000100071ff (prio 0, i/o): virtio-mmio + 0000000010008000-00000000100081ff (prio 0, i/o): virtio-mmio + 0000000010100000-0000000010100007 (prio 0, i/o): fwcfg.data + 0000000010100008-0000000010100009 (prio 0, i/o): fwcfg.ctl + 0000000010100010-0000000010100017 (prio 0, i/o): fwcfg.dma + 0000000020000000-0000000021ffffff (prio 0, romd): virt.flash0 + 0000000022000000-0000000023ffffff (prio 0, romd): virt.flash1 + 0000000030000000-000000003fffffff (prio 0, i/o): alias pcie-ecam @pcie-mmcfg-mmio 0000000000000000-000000000fffffff + 0000000040000000-000000007fffffff (prio 0, i/o): alias pcie-mmio @gpex_mmio_window 0000000040000000-000000007fffffff + 0000000080000000-0000000087ffffff (prio 0, ram): riscv_virt_board.ram + 0000000300000000-00000003ffffffff (prio 0, i/o): alias pcie-mmio-high @gpex_mmio_window 0000000300000000-00000003ffffffff + +address-space: I/O + 0000000000000000-000000000000ffff (prio 0, i/o): io + +address-space: cpu-memory-0 + 0000000000000000-ffffffffffffffff (prio 0, i/o): system + 0000000000001000-000000000000ffff (prio 0, rom): riscv_virt_board.mrom + 0000000000100000-0000000000100fff (prio 0, i/o): riscv.sifive.test + 0000000000101000-0000000000101023 (prio 0, i/o): goldfish_rtc + 0000000002000000-0000000002003fff (prio 0, i/o): riscv.aclint.swi + 0000000002004000-000000000200bfff (prio 0, i/o): riscv.aclint.mtimer + 0000000003000000-000000000300ffff (prio 0, i/o): gpex_ioport_window + 0000000003000000-000000000300ffff (prio 0, i/o): gpex_ioport + 000000000c000000-000000000c20ffff (prio 0, i/o): riscv.sifive.plic + 0000000010000000-0000000010000007 (prio 0, i/o): serial + 0000000010001000-00000000100011ff (prio 0, i/o): virtio-mmio + 0000000010002000-00000000100021ff (prio 0, i/o): virtio-mmio + 0000000010003000-00000000100031ff (prio 0, i/o): virtio-mmio + 0000000010004000-00000000100041ff (prio 0, i/o): virtio-mmio + 0000000010005000-00000000100051ff (prio 0, i/o): virtio-mmio + 0000000010006000-00000000100061ff (prio 0, i/o): virtio-mmio + 0000000010007000-00000000100071ff (prio 0, i/o): virtio-mmio + 0000000010008000-00000000100081ff (prio 0, i/o): virtio-mmio + 0000000010100000-0000000010100007 (prio 0, i/o): fwcfg.data + 0000000010100008-0000000010100009 (prio 0, i/o): fwcfg.ctl + 0000000010100010-0000000010100017 (prio 0, i/o): fwcfg.dma + 0000000020000000-0000000021ffffff (prio 0, romd): virt.flash0 + 0000000022000000-0000000023ffffff (prio 0, romd): virt.flash1 + 0000000030000000-000000003fffffff (prio 0, i/o): alias pcie-ecam @pcie-mmcfg-mmio 0000000000000000-000000000fffffff + 0000000040000000-000000007fffffff (prio 0, i/o): alias pcie-mmio @gpex_mmio_window 0000000040000000-000000007fffffff + 0000000080000000-0000000087ffffff (prio 0, ram): riscv_virt_board.ram + 0000000300000000-00000003ffffffff (prio 0, i/o): alias pcie-mmio-high @gpex_mmio_window 0000000300000000-00000003ffffffff + +address-space: gpex-root + 0000000000000000-ffffffffffffffff (prio 0, i/o): bus master container + +memory-region: pcie-mmcfg-mmio + 0000000000000000-000000001fffffff (prio 0, i/o): pcie-mmcfg-mmio + +memory-region: gpex_mmio_window + 0000000000000000-ffffffffffffffff (prio 0, i/o): gpex_mmio_window + 0000000000000000-ffffffffffffffff (prio 0, i/o): gpex_mmio + +memory-region: system + 0000000000000000-ffffffffffffffff (prio 0, i/o): system + 0000000000001000-000000000000ffff (prio 0, rom): riscv_virt_board.mrom + 0000000000100000-0000000000100fff (prio 0, i/o): riscv.sifive.test + 0000000000101000-0000000000101023 (prio 0, i/o): goldfish_rtc + 0000000002000000-0000000002003fff (prio 0, i/o): riscv.aclint.swi + 0000000002004000-000000000200bfff (prio 0, i/o): riscv.aclint.mtimer + 0000000003000000-000000000300ffff (prio 0, i/o): gpex_ioport_window + 0000000003000000-000000000300ffff (prio 0, i/o): gpex_ioport + 000000000c000000-000000000c20ffff (prio 0, i/o): riscv.sifive.plic + 0000000010000000-0000000010000007 (prio 0, i/o): serial + 0000000010001000-00000000100011ff (prio 0, i/o): virtio-mmio + 0000000010002000-00000000100021ff (prio 0, i/o): virtio-mmio + 0000000010003000-00000000100031ff (prio 0, i/o): virtio-mmio + 0000000010004000-00000000100041ff (prio 0, i/o): virtio-mmio + 0000000010005000-00000000100051ff (prio 0, i/o): virtio-mmio + 0000000010006000-00000000100061ff (prio 0, i/o): virtio-mmio + 0000000010007000-00000000100071ff (prio 0, i/o): virtio-mmio + 0000000010008000-00000000100081ff (prio 0, i/o): virtio-mmio + 0000000010100000-0000000010100007 (prio 0, i/o): fwcfg.data + 0000000010100008-0000000010100009 (prio 0, i/o): fwcfg.ctl + 0000000010100010-0000000010100017 (prio 0, i/o): fwcfg.dma + 0000000020000000-0000000021ffffff (prio 0, romd): virt.flash0 + 0000000022000000-0000000023ffffff (prio 0, romd): virt.flash1 + 0000000030000000-000000003fffffff (prio 0, i/o): alias pcie-ecam @pcie-mmcfg-mmio 0000000000000000-000000000fffffff + 0000000040000000-000000007fffffff (prio 0, i/o): alias pcie-mmio @gpex_mmio_window 0000000040000000-000000007fffffff + 0000000080000000-0000000087ffffff (prio 0, ram): riscv_virt_board.ram + 0000000300000000-00000003ffffffff (prio 0, i/o): alias pcie-mmio-high @gpex_mmio_window 0000000300000000-00000003ffffffff +``` \ No newline at end of file diff --git a/chuckstechtalk/hello_asm/baremetal.ld b/chuckstechtalk/hello_asm/baremetal.ld new file mode 100644 index 0000000..75d69ab --- /dev/null +++ b/chuckstechtalk/hello_asm/baremetal.ld @@ -0,0 +1,11 @@ +SECTIONS +{ + . = 0x80000000; + .text : { + *(.text) + } + . = ALIGN (CONSTANT (COMMONPAGESIZE)); + .data : { + *(.data) + } +} diff --git a/chuckstechtalk/hello_asm/hello b/chuckstechtalk/hello_asm/hello new file mode 100755 index 0000000000000000000000000000000000000000..c2a8624b857e908bcdf483352c3fad553184f95b GIT binary patch literal 8756 zcmeI2y-or_5Xb*~9DWptL1O%f9-)xJTny4!qQO{L7?s-a6(M4d91CjYCcc1gqmSbo zDDeSsW|spR6AME%lkD!y?A*=Vuf6|s`TR5zi6FEnzA=t;k&@e4dsBpqDDqf9!rrG$ zUem7kY2)S40_Dx~uJJX+I!P|C1TDT769Pg&2nYcoAOwVf5D)@FKnMr{As__iOJF?% zq#Xxu4pN`c@TvVv)Iojm0y$lwyA1rV-O;U{?_APN2nYcoAOwVf5D)@FKnMr{As_^V zfDrgU0%y%m$9GR!{rX*Y8Kn(+bI|V92Z*eY>jZwa2ohqH7ophDNpk literal 0 HcmV?d00001 diff --git a/chuckstechtalk/hello_asm/hello.o b/chuckstechtalk/hello_asm/hello.o new file mode 100644 index 0000000000000000000000000000000000000000..becc9792be862d2a37edca51e99741769e3edeec GIT binary patch literal 920 zcma)5%TC)+5Is&}2oJRhnb>1oq)Lo+?>RGb#=dv%_0QwRiDg+(v+#sh52$3K%)uDSm_i;)Ht@-| zac84&%lN|x@QJ@NHd^^JY>qCNUx5E-lWH7=ZH z7{VDJlj9l_^qK?H3FG&?14`7$J&KnKxj*R>mOY8d83;e*5F4?`BTAjrOHTH=9s7Ff zZTcTL)b!5oG9YbJU7&&(RVU4-rmtzyt*S#*onZV6jI+Nv-*ZT-WnHp9xp2~M{U#|I VEKClVzP_*cM)$}>T?%4T-3w$bMfm^# literal 0 HcmV?d00001 diff --git a/chuckstechtalk/hello_asm/hello.s b/chuckstechtalk/hello_asm/hello.s new file mode 100644 index 0000000..ec19693 --- /dev/null +++ b/chuckstechtalk/hello_asm/hello.s @@ -0,0 +1,27 @@ +.equ UART_BASE, 0x10000000 # a constant containing the base address for the uart that we will send data. +# This UART is defined as a NS16550 Uart in https://www.qemu.org/docs/master/system/riscv/virt.html +# UART16550 Core technical manual + +.section .text + la a0, helloworld # Load address of string + li a1, UART_BASE # Load uart tx base address. This will be used to send characters to the uart + call puts # Print string + +loop: j loop # This loop never exits, so the program will just continue to loop. + +# This is function +puts: + # a0 - String address + # a1 - UART Base address +1: # While string bytes is no null + lb t0, 0(a0) # Get byte at current string pos + beq zero, t0, 2f # is null? + sb t0, (a1) # Since not null write byte to port + addi a0, a0, 1 # Implement string pointer moving us to the next character in the string. + j 1b # Loop +2: # String byte is null. + ret + +.section .data +helloworld: .string "Hello Chuck!\n" + diff --git a/chuckstechtalk/helloc/hello.c b/chuckstechtalk/helloc/hello.c new file mode 100644 index 0000000..e69de29 diff --git a/lowlevellearning/Makefile b/lowlevellearning/Makefile new file mode 100644 index 0000000..4dc70a2 --- /dev/null +++ b/lowlevellearning/Makefile @@ -0,0 +1,7 @@ +default: + rm -rf hello + riscv64-linux-gnu-as hello.s -o hello.o + riscv64-linux-gnu-gcc -o hello hello.o -nostdlib -static + +run: + qemu-system-riscv64 -machine virt -nographic -kernel ./hello -bios none diff --git a/lowlevellearning/hello b/lowlevellearning/hello new file mode 100755 index 0000000000000000000000000000000000000000..497beb5022121a80c012b619a46980cdeb1cbb1b GIT binary patch literal 1408 zcmbtU&2G~`5T3+wl2$pSq*4o9Dv@JrRj8^sAmo&$KN93X3P%<@Hm#8xTlS_cr(WO* za)2{u4m<)E?iCVTc!6G!Ks-R1S?`oM#aviv_nZ0l+gaN)wsskznThExn&TGbzr zqJCUIGh61FvUmJ2jFy)k?e_04J(&gQte_wX(!mjwZlP%=N9$|B?RZrj(&EtaoE8rk z-2c}w@Ll*lCUpjsFY}S-by6ls`fL^Wc`-pLb4IOK<1{qCI#B~eEfnw^=iZe52I`x5 zuYH~Kr~<&U;>%#q<@tx2=Q_*O0Cx-YI|ck+0Y50?XrE-}ag>A}v^@}F zKa5-_6mb*`rJuBs>2G%SI%1={z1tH4{f&NKbbFi1cGFa((n%!pd71Ay(gEQQJpe0x zc_PrH z{l$I67jZwaPyJ1qt!jev+0f};W1+_B^R$mu98bxB`@ZP^!FsxepPf0vSl|CvBmHZr ncI&i>V=)88UF{;&X)@9}1|5!Fm_zGt=Z`hHb*apZ>GQtJEOT0BRJqR^9q*P5D03n?whTI&9d}hzBsx?pS%ODI#b?5r(rtRFW1DqXULNti)Ctw_)X+@LM)}T3V zbcduoQV*njR7tPjm6^L^026pD%Azpe6ZhLdXo z4v)zW`jxzM)uzy=c|MJz(1)52qSJ7o8%r;e$kFwQpRKC#6V_)#`MVh|K^o`zAmZnt z^m@3;C|ih|G+GMGvbz9&5py*LJuT(t0{j0U|&8PMbS2XU|l&AP;Dxyo-boZt8! z#tCy--dsI_JB3qyg7o}oP9%r;C!D`9x`RAXWf!43T2%9|{Nt26UKCV@?k`w?_a|R{ t(o31|%Ci+=4SoD%SI%EXjPISOABwk6PDXhDEsW*y8){SS43|vK{{|m=LPG!m literal 0 HcmV?d00001 diff --git a/lowlevellearning/hello.s b/lowlevellearning/hello.s new file mode 100644 index 0000000..f447d71 --- /dev/null +++ b/lowlevellearning/hello.s @@ -0,0 +1,30 @@ +.global _start +# let's us export an elf file so the linker can see it +_start: + ### Invoking the Write syscalls ### + # Check `man 2 write` + # ssize_t write(int fd, const void *buf, size_t count) + # stdout FD =1 by the way in standard linux + # Setup syscall number in a7 to be the write syscall (which is 64) + addi a7, zero, 64 + # put the file descriptor value into a0 + addi a0, zero, 1 + # We need to load into a1 the address of our helloworld label + la a1, helloworld + # Now we need to set the last argument to the string of the string we want to write + addi a2, zero, 15 + ecall + + ### SYSTEM EXIT ### + # Adding into a7 the number 93 which is syscall number for exit + addi a7, zero, 93 + # check man exit `void exit(int status)`. We need to put into a0 the argument to exit syscall + addi a0, zero, 13 + # invoke the syscall + ecall + + +# This is a label called helloworld. +# The string is 15 bytes long since this is ascii +helloworld: + .ascii "Hello, RISC V\n"