<oriansj>indeed, I've stopped telling people that I wrote one as they keep assuming I used GCC -S to generated the assembly as "No one programs in assembly" <lanodan>I wonder how those do when they see assembly in kernels, bootloaders, compilers, standard libraries, cryptographic and multimedia libraries, … <oriansj>lanodan: how many programmers these days read other people's code that isn't posted on stack exchange? <stikonas>there isn't that much assembly in compilers though <fossy>"completely crash UEFI and cause a reboot..." oh. that's quite impressively poor from uefi.. <stikonas>well, I didn't have time to debug what happened. But I guess if you overwrite incorrect memory region or something like that it could happen <fossy>given uefi is quite low level as well <stikonas>hmm, another issue I hit is that I can't print anything using stderr... Which is strange but oh well... I'll just use stdout for errors <oriansj>stikonas: write errors to an openned file? <stikonas>oriansj: well, I'm writing to stdout as we don't print anything to stdout anyway <oriansj>well if one specifies an output file, otherwise the default was stdout <stikonas>none of my earlier applications did that <stikonas>partially because printing to stdout requires a bit more code <oriansj>and always required a second argument <stikonas>now with cc_* I have higher level language than hex <stikonas>in posix it's a bit simpler, just use file descriptor 2... <oriansj>indeed, doing the posix port probably was good practice so you had the core down before dealing with UEFI's brokenness <stikonas>yeah, that's why I first got relocatable stuff <stikonas>because it's hard to debug both at the same time <stikonas>which I was doing for earlier programs... <stikonas>but in hindsight that's not the best way <stikonas>now I still need to figure out what causes the crash when building M2-0.c <stikonas>and I'm not yet sure how to debug it anyway <stikonas>probably will start with debug_list function and hope that it gives some clue <oriansj>stikonas: well the easiest path forward would be first verify cc_* on posix can run the M2-0.c correctly and dump its debug at a couple points into separate files and then try to do the same on uefi and that should narrow things down quickly <oriansj>so the question is where the difference shows up <stikonas>oriansj: oh I wonder if it's stack overflow <oriansj>unlikely as the default stack on linux is 64KiB <za3k>i was thinking of trying to reduce the number of micro-stages in stage0's C bootstrapping <za3k>is there an argument for this being a bad idea (aside from amount of work, of course) <za3k>i can't find the docs with the zillion micro-stages any more. maybe i am confused, disregard for now <oriansj>za3k: you are probably thinking of the steps between M2-Planet and GCC as there are a good few needed to get TCC to the state needed to build GCC. <sam_>they left very quickly sadly <sam_>that's why i was a bit stunned <stikonas>oriansj: so on my stack ulimit -s is 8192 (KiB) and cc_amd64 still crashes if it's smaller than 2 MiB (you can go a bit smaller but 1950 already cause crashes) <stikonas>so I think it's looking likely that this is the problem on UEFI too <oriansj>so we need to allocate a new memory block and use that as a stack instead <stikonas>so I found a bit of reference in UEFI specs <stikonas>it says you get 128 KiB or more of stack space <stikonas>and 4 KiB+ after calling ExitBootServices (so just before kernel is started) <oriansj>and if I remember correctly, don't arguments get passed on the stack to UEFI; would it have an issue with us using our own stack? <stikonas>oriansj: it would but we don't have to fully use out own stack <stikonas>we can keep two stacks and just offload heavy stuff to our own stack <stikonas>I've freed up a register now to track our own stack <stikonas>though that means heavy modifications to cc_amd64.S... <stikonas>all those push rax, pop rax will have to be changed <stikonas>and M2-Planet will also suffer from this problem... <oriansj>on start we write the stack to UEFI_STACK <oriansj>switch RSP to point to the end of the new stack <oriansj>then inside of our syscalls we do the following: write the stack to USER_STACK <stikonas>that will indeed hide most of the complexity behind a single function <oriansj>and you can do it in two simple functions <oriansj>ENTER_UEFI_STACK and EXIT_UEFI_STACK <stikonas>yeah, those will move rsp to the required stack and save state of the other stack <oriansj>indeed and we can steal that trick in M2-Planet as well <stikonas>cc_amd.M1 (codegen part of cc_amd64) and I guess in M2-Planet/M2libc <oriansj>but that is much better than the althernate <stikonas>which should let me compile M2-0.c but won't let M2-Planet to compile complex programs (ignoring for the moment that M2 is not ported to UEFI yet) <stikonas>I guess 8 MiB should be fine for user stack <stikonas>as we haven't encountered any problems in stage0-posix <stikonas>and I guess reboot was happening because stack overflow was overwriting some critical parts of UEFI <oriansj>well technicallly M2-Planet isn't ported to Operating systems, only hardware platforms. It is M2libc that needs to be ported to UEFI and M2-Planet will happily use the new arbitrary rules humans put ontop of the hardware. <stikonas>well, yes, but cc_amd64 thing has two parts in it <stikonas>well, maybe the second one goes to m2libc too... <stikonas>to make sure that bootstrap M2 binary also has ENTER_UEFI_STACK and EXIT_UEFI_STACK <oriansj>So the output of M2-Planet will always work on the hardware but it is the C code in M2libc is what breaks on different Operating systems (as they have different syscall methods and ways of passing arguments and different values to pass to the operating system) <oriansj>so the changes would be entirely in M2libc and with a bit of special work in the libc-core.M1 and libc-full.M1 <oriansj>so we might end up having to make libc-uefi.M1 <stikonas>libc-uefi.M1 was always going to be the case <stikonas>we need to deal with command line arguments, etc... <oriansj>well we can do that entirely in C code <oriansj>just have libc-uefi.M1 call FUNCTION__init_arguments which builds an array and returns it <stikonas>cause it will have to me more sophisticated than what I have in early prototypes <stikonas>(I think right now arguments are split on space, so double space means an empty argument which we might not want in M2libc) <stikonas>anyway, let's first get cc_amd64.S working <stikonas>well, at the very least soon it will be C code + some light assembly <oriansj>with the added bonus of being able to use normal C code directly on UEFI rather than having to do the weird song and dance you need to do for UEFI right now <stikonas>but don't we need a patch to M2-Planet to support UEFI/Windows calling convention? <stikonas>actually if I remember correctly, M2-Planet passes all arguments on stack <stikonas>so that might be fine, but we also need to populate rcx, rdx, r8 and r9 <oriansj>stikonas: no because M2-Planet doesn't even deal with POSIX's calling convention <oriansj>the only dealing with the calling convention is in M2libc in ASM blocks <stikonas>well, so we might still need to insert small asm blocks in uefi wrappers then... <oriansj>well we would be making a clone of the Linux subfolder <stikonas>or how else would you get required arguments into rcx...r9 ? <stikonas>and then replace all those fgetc, etc with uefi equivalents <oriansj>with nothing but the UEFI specific crap <oriansj>but we can make them behave the same but be UEFI compatible <stikonas>yes, in cc_amd64 I already tried to make fputc slightly more compatible (so it special cases file descriptor 2 and then uses different uefi function) <stikonas>hmm, though I wonder whether real UEFI file can have file descriptor 2... <stikonas>(though this shouldn't affect cc_amd64 as I was careful and used another variable/register for that stderr flag) <oriansj>well we can flush that out with a good deal of experiments in M2libc <oriansj>stikonas: it is a pointer in M2libc as well <oriansj>if you look in M2libc/stdio.c it shows up real quick <oriansj>stdin, stdout and stderr are full structs <oriansj>so whatever arbitrary things UEFI needs, shouldn't be a problem <oriansj>only in Mes.c does one have the hardcoded value of 0,1,2 for stdin, stdout and stderr <stikonas>oriansj: so things are even simpler than what you planned for <stikonas>we don't need to restore uefi stack before each uefi call <stikonas>so I just need to call enter/exit_uefi_stack at the beginning and end of program <stikonas>and M2-0.c compiles to at least good size <stikonas>and in total I had to allocate 32 MiB of heap space <stikonas>though maybe I can try to reduce it a bit... <stikonas>ok, 16 MiB (out of which 4 goes to stack) seems enough to build M2 <stikonas>wait, that looks wrong... Not sure why it works <stikonas>exit_uefi_stack is b0rked but mov rsp, rbp # restore stack just before termination saves us <stikonas>and I can start working on GAS->M1 conversion ***ay is now known as Andrew
<Hagfish>"soon it will be C code + some light assembly" <Hagfish>i was thinking that october would be another great month for bootstrapping, and it seems to be off to a great start already :)