GNAT cross-compiler: my various questions

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

GNAT cross-compiler: my various questions

Post by Ethin »

I'm a bit unsure about what target triplet I should use for my GNAT cross-compiler. I'm thinking about just using Limine, since its a really modern boot loader, so would I compile binutils/gnat for x86_64-elf? Or would I keep it as i686-elf?
Last edited by Ethin on Mon May 23, 2022 5:00 pm, edited 1 time in total.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: GNAT cross-compiler: what target triplet to use?

Post by Octocontrabass »

Do you want your cross-compiler to emit 64-bit code or 32-bit code? (Limine supports both.)
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: GNAT cross-compiler: what target triplet to use?

Post by Ethin »

Octocontrabass wrote:Do you want your cross-compiler to emit 64-bit code or 32-bit code? (Limine supports both.)
I'm not honestly sure. On one hand the fact that I can just tell Limine to set up page tables for me is pretty cool and that's one less thing I have to worry about. On the other hand, that deprives me of critical knowledge and experience because I'll have to set up paging eventually. I'm just unsure what would be easier: learning paging through starting a process/thread (for example) or learning it by setting up my kernel to jump into 64-bit mode (because I ultimately want 64-mode regardless_.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: GNAT cross-compiler: what target triplet to use?

Post by Octocontrabass »

Or you can learn paging by setting up your own page tables as soon as your memory manager is up and running. Who says you have to write a bootloader or wait until you're ready to start a process?
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: GNAT cross-compiler: what target triplet to use?

Post by Ethin »

aa
Octocontrabass wrote:Or you can learn paging by setting up your own page tables as soon as your memory manager is up and running. Who says you have to write a bootloader or wait until you're ready to start a process?
True.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: GNAT cross-compiler: what target triplet to use?

Post by iansjack »

You definitely want to go for 64-bit code from the start. Even with i386 you will want to use paging, so that makes no difference.

As an aside, as you are going to use Ada, you might want to look at this project: https://blog.adacore.com/cubit-a-genera ... -spark-ada if you haven't already seen it. I've been looking at Ada for OS work, and it seems to be a very good fit (once you get your head around its implementation of pointers, arrays, etc.). I'd been trying Rust but I found I was spending too much time fighting against the language to do simple things. Ada is much more amenable in that respect.

Also, if you haven't already got it, have a look at GNATstudio: https://www.adacore.com/gnatpro/toolsuite/gnatstudio It comes with the community edition of GNAT from AdaCore.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: GNAT cross-compiler: what target triplet to use?

Post by Ethin »

iansjack wrote:You definitely want to go for 64-bit code from the start. Even with i386 you will want to use paging, so that makes no difference.

As an aside, as you are going to use Ada, you might want to look at this project: https://blog.adacore.com/cubit-a-genera ... -spark-ada if you haven't already seen it. I've been looking at Ada for OS work, and it seems to be a very good fit (once you get your head around its implementation of pointers, arrays, etc.). I'd been trying Rust but I found I was spending too much time fighting against the language to do simple things. Ada is much more amenable in that respect.

Also, if you haven't already got it, have a look at GNATstudio: https://www.adacore.com/gnatpro/toolsuite/gnatstudio It comes with the community edition of GNAT from AdaCore.
I need to get the Gnat development tools for a cross-compilation environment working on my system (I'm on NixOS so things work a bit differently). I considered just doing development in a LXC container, but I lose a lot of benefits doing things that way. I hadn't heard of CuBit until you posted that link -- looks neat! But I'm glad I know to build for x86_64-elf; that's not overly hard and I can just swap out the paging tables that Limine gives me for my own (though that might be... Rather difficult if I go for KASLR/a randomized kernel... I think, anyway). Overall I really like Limine -- a lot more modern than Grub and I don't have to go get grub and fiddle around with its weird querks just to make it happy!
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: GNAT cross-compiler: what target triplet to use?

Post by iansjack »

I'm interested that, having used Rust, you are now looking at Ada.

Are your reasons the same as mine, or do you have another motivation. (Not that any motivation is needed to try our different programming languages - I'm alway interested in trying something different.)
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: GNAT cross-compiler: what target triplet to use?

Post by Octocontrabass »

Ethin wrote:(though that might be... Rather difficult if I go for KASLR/a randomized kernel... I think, anyway)
Limine will tell you your kernel's physical and virtual address (although you should be able to use symbols to find the virtual address). Limine guarantees there will be a fixed offset between the two, so you don't need to worry about parsing the bootloader's page tables or anything like that.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: GNAT cross-compiler: what target triplet to use?

Post by Ethin »

a
iansjack wrote:I'm interested that, having used Rust, you are now looking at Ada.

Are your reasons the same as mine, or do you have another motivation. (Not that any motivation is needed to try our different programming languages - I'm alway interested in trying something different.)
Kind of. I like Rust, I really do, and I have no plans of abandoning it or anything like that. But the downside is that there are a lot of crates one can use for OsDev, and though that sounds like a bonus, and something that's nice, it... Really isn't. So much is abstracted away from you in the process that actually learning how it all works is harder because now you have to go trundling through someone's 3rd-party implementation of x or y and that's no fun. But the other problem I suffered was that I followed this tutorial initially. I admit: the tutorial was (and still is) absolutely fantastic. It teaches you a lot and I was able to get up and running quicker than I otherwise would have, and it provided that "click" that I was desperately looking for. But it was x86_64 only, and my kernel was so full of x86_64-specific stuff that I couldn't see a way of porting it over to any other architecture, and I just felt... Too constrained. I saw Ada a few years ago and poked at it but back then I couldn't figure it out, but I picked it back up recently and its finally clicked with me, and all I've been looking for right now is something I can actually create in it that will allow me to actually work on mastering it. And I really, really think that Ada is a beautiful language, and its saddened me that every time Ada gets an opportunity to shine, something always comes a long and snatches it away. To be truthful, that's sparked some resentment in the Ada community; people over there look very... Uncharitably, shall we say... on languages like Rust, for effectively reinventing what Ada pretty much already gives you, and so I've fartially felt this... Very strong nudge, so to speak, for doing what I can and trying to push Ada back into the spotlight, because I really do think that it could be an extremely amazing language if it got more popular and people started using it for things other than high-security/high-integrity systems. The fact that you can use Spark in your ada projects whenever you want, and prove various properties about your code, is something that I think is another point in Ada's favor, which is something Rust still doesn't have. But what really made me like it was the fact that it prides itself on clarity, reliability, and safety -- those three qualities, together, are hard to find in modern languages today. Oh, Rust provides the "safety" part, up to a point, and the fact that you can use "unsafe" to explicitly indicate what code might be potentially safe and unsafe is a pretty nice feature: it means less auditing (theoretically at least). But it doesn't provide the reliability or readability parts, or any of the other things that Ada prides itself on, or if it does, it doesn't to the degree that Ada does.
But what finally tipped me in Ada's favor -- and its something that I marvel at every time I read the LRM -- is the annexes. Ada makes it super, super simple to communicate across the FFI boundary, as an example. By contrast, in Rust that's a pain in the @$$. So I think Ada has a lot going for it and me switching was not just for a major learning opportunity, but as a way of mastering Ada and trying to make it better (and maybe more popular) in the process. But the learning is the ultimate goal.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: GNAT cross-compiler: what target triplet to use?

Post by Ethin »

Question: The stivale2 specification contains C-defined structures like this:

Code: Select all

struct stivale2_struct_tag_smp {
    struct stivale2_tag tag;
    uint64_t flags;
    uint32_t bsp_lapic_id;
    uint32_t unused;
    uint64_t cpu_count;
    struct stivale2_smp_info smp_info[];
};
The stivale2_smp_info structure has always confused me -- how to exactly use it is a bit unclear even in the specification. But what's the right way to represent this information in Ada? Ada doesn't (to my knowledge) contain pointer arithmetic, so I have no idea how I'd read different CPUs.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: GNAT cross-compiler: what target triplet to use?

Post by Octocontrabass »

Ethin wrote:The stivale2_smp_info structure has always confused me -- how to exactly use it is a bit unclear even in the specification.
Which part of the specification is unclear? It's an array, the length is given by cpu_count, and each element of the array is a struct.

I don't know anything about Ada, but it looks like you have some choices for how to translate it.
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: GNAT cross-compiler: what target triplet to use?

Post by Ethin »

Octocontrabass wrote:
Ethin wrote:The stivale2_smp_info structure has always confused me -- how to exactly use it is a bit unclear even in the specification.
Which part of the specification is unclear? It's an array, the length is given by cpu_count, and each element of the array is a struct.

I don't know anything about Ada, but it looks like you have some choices for how to translate it.
I meant on how to actually activate the APs. That's what I found to be unclear.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: GNAT cross-compiler: what target triplet to use?

Post by Octocontrabass »

Write an address to the goto_address member and the AP will begin executing at that address. The AP will set its stack pointer to target_stack when it begins executing.

You have to perform the write to goto_address in a manner that guarantees memory consistency. For example, in C, you would use atomic_store_explicit with memory_order_release. I'm sure Ada has an equivalent, but I don't know what it would be.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: GNAT cross-compiler: what target triplet to use?

Post by iansjack »

Pointer arithmetic is supported in Ada via the System.Storage_Elements package. Here's a completely useless example that demonstrates pointer arithmetic (and how unsafe it is as it allows access beyond the bounds of the array!):

Code: Select all

with System;
with System.Storage_Elements; use System.Storage_Elements;
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is

   type IntegerAccess is access Integer;
   type IntegerArray is array (1 .. 4) of Integer;
   arr : IntegerArray := (1, 2, 3, 4);
   i   : System.Address;

begin
   i := arr'Address;
   for j in 1 .. 5 loop
      declare
         int : Integer;
         for int'Address use i;
      begin
         Put_Line (int'Image);
      end;
      i := i + Integer'Size /8;
   end loop;

end Main;
with output

Code: Select all

1
2
3
4
0
Post Reply