<div dir="auto">Gotcha. We can leave an #error directive in what we merge initially too, like we did for the i386 SMP support.</div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jun 14, 2018, 11:55 PM Gedare Bloom <<a href="mailto:gedare@rtems.org">gedare@rtems.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Thu, Jun 14, 2018 at 1:25 PM, Amaan Cheval <<a href="mailto:amaan.cheval@gmail.com" target="_blank" rel="noreferrer">amaan.cheval@gmail.com</a>> wrote:<br>
> Sounds good!<br>
><br>
> For shutdown and whatnot, I imagine I'll need to get our ACPI support<br>
> out there too, so that may be on the backburner for a little bit.<br>
><br>
> Maybe this should be a new thread, but; what is the minimal BSP we<br>
> will be willing to merge upstream? I'm thinking that this process of<br>
> booting, initialization, and reaching the init task (but not having<br>
> full or possibly any console support) can be the minimal.<br>
><br>
> Is that a reasonable assumption?<br>
><br>
<br>
The preferred "minimal" BSP is one with working console and clock<br>
driver. It would be OK to start merging once you reach the milestone<br>
of context switching to the Init task, though, and then add the<br>
console support, and then the clock driver, before you begin the<br>
other, more advanced BSP features.<br>
<br>
> On Thu, Jun 14, 2018 at 9:42 PM, Joel Sherrill <<a href="mailto:joel@rtems.org" target="_blank" rel="noreferrer">joel@rtems.org</a>> wrote:<br>
>><br>
>><br>
>> On Thu, Jun 14, 2018, 6:08 PM Amaan Cheval <<a href="mailto:amaan.cheval@gmail.com" target="_blank" rel="noreferrer">amaan.cheval@gmail.com</a>> wrote:<br>
>>><br>
>>> Thanks for your input, everyone! I appreciate it! :)<br>
>>><br>
>>> On Thu, Jun 14, 2018 at 11:25 AM, Chris Johns <<a href="mailto:chrisj@rtems.org" target="_blank" rel="noreferrer">chrisj@rtems.org</a>> wrote:<br>
>>> > On 14/06/2018 05:33, Joel Sherrill wrote:<br>
>>> >> On Wed, Jun 13, 2018, 6:57 PM Amaan Cheval <<a href="mailto:amaan.cheval@gmail.com" target="_blank" rel="noreferrer">amaan.cheval@gmail.com</a><br>
>>> >> <mailto:<a href="mailto:amaan.cheval@gmail.com" target="_blank" rel="noreferrer">amaan.cheval@gmail.com</a>>> wrote:<br>
>>> >><br>
>>> >>     On Wed, Jun 13, 2018 at 9:35 PM, Gedare Bloom <<a href="mailto:gedare@rtems.org" target="_blank" rel="noreferrer">gedare@rtems.org</a><br>
>>> >>     <mailto:<a href="mailto:gedare@rtems.org" target="_blank" rel="noreferrer">gedare@rtems.org</a>>> wrote:<br>
>>> >>     > On Wed, Jun 13, 2018 at 11:33 AM, Amaan Cheval<br>
>>> >> <<a href="mailto:amaan.cheval@gmail.com" target="_blank" rel="noreferrer">amaan.cheval@gmail.com</a><br>
>>> >>     <mailto:<a href="mailto:amaan.cheval@gmail.com" target="_blank" rel="noreferrer">amaan.cheval@gmail.com</a>>> wrote:<br>
>>> >>     >> Hi!<br>
>>> >>     >><br>
>>> >>     >> As we discussed in the last thread on the topic[1], I'm trying<br>
>>> >> to use<br>
>>> >>     >> FreeBSD's loader.efi directly with RTEMS' generated static<br>
>>> >> binaries<br>
>>> >>     >> (since FreeBSD's loader.efi has an ELF loader).<br>
>>> >>     >><br>
>>> >>     >> In brief, I did this by:<br>
>>> >>     >> - Installing FreeBSD in QEMU with UEFI firmware<br>
>>> >>     >> - Confirming that FreeBSD's loader.efi is in fact used<br>
>>> >>     >> - Replacing FreeBSD's ELF kernel with a "custom" kernel[2] with<br>
>>> >> an RTEMS ELF<br>
>>> >>     >> - Verifying that the code running after FreeBSD's loader.efi is<br>
>>> >> in<br>
>>> >>     >> fact the "RTEMS ELF" by attaching gdb to QEMU (the rtems ELF is<br>
>>> >> simply<br>
>>> >>     >> a while(1) loop compiled with RTEMS' tools - see later on why I<br>
>>> >> can't<br>
>>> >>     >> do something more elaborate)<br>
>>> >>     >><br>
>>> >>     >> Some more details of the process I followed for testing this:<br>
>>> >>     >> <a href="https://gist.github.com/AmaanC/42faa131ee97a1d6c4c7c25c29f0fde9z" rel="noreferrer noreferrer" target="_blank">https://gist.github.com/AmaanC/42faa131ee97a1d6c4c7c25c29f0fde9z</a><br>
>>> >>     >><br>
>>> >>     >> I think this method is superior to the PIC RTEMS method because:<br>
>>> >>     >> - FreeBSD uses it<br>
>>> >>     >> - RTEMS retains static ELF binaries, which can likely easily be<br>
>>> >>     >> combined with a Multiboot header + protect mode starter code<br>
>>> >>     >> - FreeBSD has methods to provide ACPI related hints to their ELF<br>
>>> >>     >> kernel - this might make our implementation with regards to ACPI<br>
>>> >>     >> simpler too<br>
>>> ><br>
>>> > I agree this is the best approach. In time we can host on our file<br>
>>> > server a<br>
>>> > package of FreeBSD binaries that boot an RTEMS kernel.<br>
>>> ><br>
>>> >>     >><br>
>>> >>     >> Regarding some concerns Chris had with linker options and<br>
>>> >> whatnot,<br>
>>> >>     >> here's what FreeBSD uses:<br>
>>> >>     >><br>
>>> >> <a href="https://www.freebsd.org/doc/en/books/arch-handbook/boot-kernel.html" rel="noreferrer noreferrer" target="_blank">https://www.freebsd.org/doc/en/books/arch-handbook/boot-kernel.html</a><br>
>>> >>     >><br>
>>> >>     >> Here's what I used (with the code being a simple while(1) loop):<br>
>>> >>     >>   x86_64-rtems5-gcc ktest.c -c -nostdlib<br>
>>> >>     >>   x86_64-rtems5-ld ktest.o -e main -o kernel<br>
>>> >>     >><br>
>>> ><br>
>>> > Nice, this looks fine. It is normal for a bare metal piece of C code.<br>
>>> ><br>
>>> >>     >><br>
>>> >><br>
>>> >> -------------------------------------------------------------------------------------<br>
>>> >>     >><br>
>>> >>     >> What I need input on:<br>
>>> >>     >> - Right now, we use the following RTEMS code for testing:<br>
>>> >>     >><br>
>>> >>     >> int main() {<br>
>>> >>     >>   while(1) {}<br>
>>> >>     >> }<br>
>>> >>     >><br>
>>> >>     ><br>
>>> >>     > It's not really an RTEMS code, it is a C program (ktest.c)<br>
>>> >> compiled<br>
>>> >>     > with the RTEMS-flavored toolchain, right?<br>
>>> >><br>
>>> >>     Yeah, for now that's right. I'm going to conduct the same gdb based<br>
>>> >>     debug-stepping style test for RTEMS setting boot_card as the entry<br>
>>> >>     point soon - for now, it crashes QEMU with:<br>
>>> >><br>
>>> >>     qemu: fatal: Trying to execute code outside RAM or ROM at<br>
>>> >> 0x00000000000b0000<br>
>>> >><br>
>>> >>     RAX=00000000006004c0 RBX=00000000006003d8 RCX=0000000037f36000<br>
>>> >>     RDX=0000000000400000<br>
>>> >>     RSI=0000000004000000 RDI=0000000000000180 RBP=00000000006003d8<br>
>>> >>     RSP=000000003c589fb8<br>
>>> >>     ...<br>
>>> >><br>
>>> >>     I see that it reaches that stage even from some code it ought not<br>
>>> >> to<br>
>>> >>     be executing, so I'll look into what that may be about.<br>
>>><br>
>>> It was quite simple, really - my stub doesn't define<br>
>>> _CPU_Context_restore yet - rtems_initialize_executive calls that<br>
>>> function expecting it to never return, but when it does, we lose<br>
>>> control and just start running code from virtual address 0 (or<br>
>>> possibly whatever happens to be on the stack as the return instruction<br>
>>> pointer).<br>
>>><br>
>>> What we _do_ know is a positive sign, though - an actual RTEMS static<br>
>>> binary does seem to be loaded just fine, and starts executing too,<br>
>>> until we call _CPU_Context_restore and lose control.<br>
>>><br>
>>> Next up: I'll work on the context-switching code to move past this,<br>
>><br>
>><br>
>> You will need context initialize and restore to get through initialization<br>
>> to the first task. You might as well complete all of the methods related to<br>
>> non-FP contexts and see if you can run base_sp. It may even call shutdown so<br>
>> you can do that.<br>
>><br>
>> But getting to a user init task would be success and return to printk.<br>
>><br>
>>> and then we can follow the original plan in my proposal<br>
>>> (context-switching, basic IRQ, idle thread based clock driver,<br>
>>> printk/console support - I'd like to get to the console driver as soon<br>
>>> as is viable - I could work on it directly outside of the RTEMS static<br>
>>> binary, using the "ktest" style kernel I mentioned earlier, but I<br>
>>> think we'd rather make progress directly on the BSP first).<br>
>>><br>
>>> ><br>
>>> > Hmm.<br>
>>> ><br>
>>> >><br>
>>> >>     ><br>
>>> >>     > It would be nice to get an RTEMS x86-64 BSP to start, at least to<br>
>>> >>     > confirm that you reach _start, and then even you can try to make<br>
>>> >> it to<br>
>>> >>     > the "boot_card" startup sequence.<br>
>>> >><br>
>>> >>     Right, I'll aim to have that working soon (using boot_card as the<br>
>>> >>     entry, since "_start" usually does the bootloader stuff that we're<br>
>>> >> now<br>
>>> >>     offloading to FreeBSD, and then calls boot_card anyway).<br>
>>> >><br>
>>> >><br>
>>> >> To be consistent with other BSPs, I have a start.c on the Deos BSPs. It<br>
>>> >> fetches<br>
>>> >> the boot arguments which are passed to boot_card() and does some other<br>
>>> >> setup<br>
>>> >> specific to Deos.<br>
>>> >><br>
>>> >> No need to do this now but there is a good reason to follow the<br>
>>> >> pattern. Start<br>
>>> >> doesn't have to be in assembly.<br>
>>><br>
>>> Noted for the future, thanks!<br>
>>><br>
>>> >><br>
>>> >><br>
>>> >>     ><br>
>>> >>     >> That's literally it, because we have no access to standard<br>
>>> >> libraries,<br>
>>> >>     >> and loader.efi calls ExitBootServices, after which we can't just<br>
>>> >>     >> easily directly access video memory (at 0xb8000 for eg.) to<br>
>>> >> print to<br>
>>> >>     >> the screen. The way FreeBSD handles this is by initializing the<br>
>>> >>     >> console and printing to that - I haven't been able to easily<br>
>>> >> port that<br>
>>> >>     >> yet.<br>
>>> >>     >><br>
>>> >>     >> The question is - should I start with that effort (i.e. bringing<br>
>>> >>     >> printk console functionality to RTEMS) the way FreeBSD does?<br>
>>> >> This way,<br>
>>> >>     >> we skip the bootloader for now by simply using the one built on<br>
>>> >> the<br>
>>> >>     >> real FreeBSD - if the console prints and more elaborate linking<br>
>>> >> tests<br>
>>> >>     >> work fine, we can be certain that this works. If _not_, I<br>
>>> >> believe the<br>
>>> >>     >> console initialization code will likely still remain the same<br>
>>> >> since<br>
>>> >>     >> we'll want to do it similar to how FreeBSD does it.<br>
>>> >>     >><br>
>>> >>     ><br>
>>> >>     > I think this approach to getting a console to work may be<br>
>>> >> reasonable,<br>
>>> >>     > assuming the FreeBSD console is not much more complicated than<br>
>>> >> what<br>
>>> >>     > RTEMS needs. ...<br>
>>> >><br>
>>> >>     I can't say about this yet, but I'll look into it (and perhaps<br>
>>> >>     simplifying it as we port it if it _is_ too complicated).<br>
>>> >><br>
>>> ><br>
>>> > It has been a couple of years but I think FreeBSD contains some of the<br>
>>> > Intel<br>
>>> > code to interface to UEFI and via this you can get to the UEFI console.<br>
>>> > This<br>
>>> > should be easy but it comes with a side effect.<br>
>>> ><br>
>>> > UEFI boots in graphics mode and so it's console on a PC is a slow scroll<br>
>>> > one. On<br>
>>> > boards like a Minnow using the UEFI console has the advantage of being<br>
>>> > able to<br>
>>> > support any redirection UEFI has enabled such as a serial port. The<br>
>>> > disadvantage<br>
>>> > of this is performance and overhead. In time this may be a boot option.<br>
>>> ><br>
>>> > What I am not sure is the boundary between UEFI and the kernel and what<br>
>>> > is<br>
>>> > enabled or available when the kernel is loaded.<br>
>>><br>
>>><br>
>>> That's good information, thank you! I'll look into it as I can - for<br>
>>> now, can we settle on these for next steps?<br>
>>><br>
>>> - We're using FreeBSD's loader.efi - to do so, we just need our BSP to<br>
>>> generate static ELFs, so nothing needs to go in the source tree<br>
>>> - I'll focus on the context-switching code for the BSP next, aiming to<br>
>>> get it to actually reach bsp_start - once that's done, we can focus on<br>
>>> the console output (this means that until then, verifying the progress<br>
>>> will likely still be done through emulators and debuggers).<br>
>>><br>
>>> Let me know!<br>
>>><br>
>>> ><br>
>>> >>     ><br>
>>> >>     >> What do you think?<br>
>>> >>     >><br>
>>> ><br>
>>> > Awesome work.<br>
>>> > Thanks<br>
>>> > Chris<br>
</blockquote></div>