Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Works on real hardware again! #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

FireFox317
Copy link

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".

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!
@andrewrk
Copy link
Owner

\o/

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

@FireFox317
Copy link
Author

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
Copy link
Author

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.

@andrewrk
Copy link
Owner

Here's the issue to get rid of the llvm-objcopy dependency: ziglang/zig#2826

@FireFox317
Copy link
Author

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.

@pixelherodev
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants