clashos icon indicating copy to clipboard operation
clashos copied to clipboard

Works on real hardware again!

Open FireFox317 opened this issue 6 years ago • 6 comments

This commit adds various changes to ClashOS to get the stack traces and bootloader to work again in qemu and on real hardware.

The linker scripts are changed to allow the binary to be linked at the address 0x80000. This is the default address at which the raspberry pi will load kernel8.img when no 'config.txt' file is present on the sd card.

To allow stack traces to work, the link register had to be zero'ed, because it contains random stuff on start up on real hardware. It work on qemu, because it sets the link register to zero.

The code for the framebuffer is currently comment out, because for some reason the loading over serial fails to work when that code is compiled. But loading over serial now works!

The current implementation of the DWARF debug info parsing doesn't work for freestanding, because of some assert, which is actually part of the DWARF specification according to @LemonBoy. Also in FixedBufferAllocator.alloc there is some code generated that causes an alignment exception on real hardware. The following patch was used to solve these two issues:

diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index 69b9e894b..c2a1cbf3a 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -1546,7 +1546,8 @@ pub const DwarfInfo = struct {
         const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir);
         const line_info_offset = try compile_unit.die.getAttrSecOffset(DW.AT_stmt_list);
 
-        assert(line_info_offset < di.debug_line.size);
+        // TODO: remove this workaround for to get stacktraces on freestanding
+        // assert(line_info_offset < di.debug_line.size);
 
         try di.dwarf_seekable_stream.seekTo(di.debug_line.offset + line_info_offset);
 
diff --git a/src/codegen.cpp b/src/codegen.cpp
index cad67e378..4e919a2c1 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8629,6 +8629,9 @@ static void init(CodeGen *g) {
         // TODO https://github.com/ziglang/zig/issues/2883
         target_specific_cpu_args = "pentium4";
         target_specific_features = (g->zig_target->os == OsFreestanding) ? "-sse": "";
+    } else if (g->zig_target->arch == ZigLLVM_aarch64) {
+        target_specific_cpu_args = "";
+        target_specific_features = "+strict-align";
     } else {
         target_specific_cpu_args = "";
         target_specific_features = "";

BTW: I know that the target_specific_features shouldn't be solved like this, but that's a different issue. For this to work it needs "+strict-align".

FireFox317 avatar Dec 16 '19 23:12 FireFox317

\o/

I'll work with you on upstreaming all the zig improvements needed to get this working again.

andrewrk avatar Dec 17 '19 00:12 andrewrk

Great! I guess the "+strict-align" is being solved with ziglang/zig#3927 ? It is actually a work around for unaligned code that is generated in the std, but it does solve the problem (with some performance penalty i guess).

For the issue with the DWARF spec, I'm not what the correct thing will be, we could just not assert, but maybe we have to find a workaround in ClashOS instead of the std library.

FireFox317 avatar Dec 18 '19 09:12 FireFox317

Note: I actually had to change llvm-objcopy with aarch64-linux-gnu-objcopy in the build.zig file, otherwise it doesn't work. I'm not sure why llvm-objcopy doesn't work.

FireFox317 avatar Dec 18 '19 15:12 FireFox317

Here's the issue to get rid of the llvm-objcopy dependency: https://github.com/ziglang/zig/issues/2826

andrewrk avatar Dec 18 '19 19:12 andrewrk

Jup, but actually it wasn't working at all on real hardware when using llvm-objcopy, so that is an issue with llvm-objcopy itself. I will compare the binaries, see what the difference is.

FireFox317 avatar Dec 18 '19 19:12 FireFox317

Okay, so I've had the stack tracing working in freestanding before in my LIMNOS project.

It's broken now though, and I'm not sure if it's due to changes on my side or in the standard library, because I started with a custom overridden standard library, updated it a couple times, then switched to the OS layer in the standard library. I might be able to find a working commit though and see what actually changed, because I'm very interested in that feature as well.

pixelherodev avatar Dec 19 '19 10:12 pixelherodev