Page 1 of 1

Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:08 pm
by kzinti
I have a multiboot loader that loads a 64 bits kernel in memory. I setup memory mapping this way:

I start by identity-mapping the first 4 GB of physical memory using large pages (2MB):
https://github.com/kiznit/rainbow-os/bl ... #L176-L215

Then I map my kernel where I want it to be in virtual memory (0xFFFFFFFF F0000000):
https://github.com/kiznit/rainbow-os/bl ... #L219-L283

I then setup long mode and jump to my kernel:
https://github.com/kiznit/rainbow-os/bl ... m#L91-L151

I have verified all page mappings and everything is good.

My problem? The kernel works. Why is that a problem? Well notice that I mapped the first 4 GB as read-only. Yet my kernel is happy to use the stack that is still around 0x00100800.
https://github.com/kiznit/rainbow-os/bl ... t.cpp#L214

Why is using the stack not triggering a CPU exception?


The same thing is happening with the 32 bits kernel. The page mapping is a bit more invovled, but I basically do the same thing: identity map 4 GB and then map the kernel at 0xF0000000. It also works.

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:11 pm
by BrightLight
When bit 16 (value 0x10000) of CR0 register is cleared, the kernel can write to read-only pages.

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:14 pm
by kzinti
That must be it. Thanks!

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:20 pm
by glauxosdever
Hi,


I'm not sure if it is good to identity map everything in a range (whether it is used or not). Determine what is free, what is used, and map the used. Don't map the free. It is a better step towards proper memory management.

Also, I implement read-only pages in the kernel-space. As mentioned above, you need to set bit 16 of cr0 in order this to work. Note that on some old CPUs it may not be supported (from around early 1990s at most).


Regards,
glauxosdever

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:25 pm
by BrightLight
glauxosdever wrote:Also, I implement read-only pages in the kernel-space. As mentioned above, you need to set bit 16 of cr0 in order this to work. Note that on some old CPUs it may not be supported (from around early 1990s at most).
Actually, AMD released x86_64 (or AMD64 really) in 2000.

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:27 pm
by kzinti
glauxosdever wrote:I'm not sure if it is good to identity map everything in a range (whether it is used or not). Determine what is free, what is used, and map the used. Don't map the free. It is a better step towards proper memory management.
This is a bootloader. I am not going to start implementing a "proper" memory manager in my bootloader. I just want to get the data to the kernel so that it can do proper memory management. Multiboot and EFI can decide to put my data anywhere in memory. ACPI, EFI firmware and other reserved memory ranges can be anywhere in the first 4 GB. Much easier to map it all than starting figuring out where things got allocated by GRUB2 or the firmware.

The reason I want these pages read-only is just as a safety net in case my kernel decides to write in the first 4 GB (i.e.: to catch bugs). I fully intend on un-mapping it all once the kernel initialization is completed.

Beside, where did you get the idea that this was my final design / implementation?

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:35 pm
by glauxosdever
Hi,

omarrx024 wrote:
glauxosdever wrote:Also, I implement read-only pages in the kernel-space. As mentioned above, you need to set bit 16 of cr0 in order this to work. Note that on some old CPUs it may not be supported (from around early 1990s at most).
Actually, AMD released x86_64 (or AMD64 really) in 2000.
This bit exists in 32-bit x86 architectures too. I meant that the latest CPUs that don't support it are from early 1990s, not later.
kzinti wrote:Beside, where did you get the idea that this was my final design / implementation?
Sorry, I misread. But anyway, I think it's a good idea for later.


Regards,
glauxosdever

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:40 pm
by Kazinsal
omarrx024 wrote:Actually, AMD released x86_64 (or AMD64 really) in 2000.
The WP bit was introduced on the 486.

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:44 pm
by BrightLight
Kazinsal wrote:
omarrx024 wrote:Actually, AMD released x86_64 (or AMD64 really) in 2000.
The WP bit was introduced on the 486.
You mentioned above that your kernel was 64-bit.
What I meant was that every x86-64 CPU supports the WP bit.

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 1:53 pm
by kzinti
It's fascinating how no one reads the whole post and then start nitpicking each other's reply.

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 4:27 pm
by zdz
kzinti wrote:
glauxosdever wrote:I'm not sure if it is good to identity map everything in a range (whether it is used or not). Determine what is free, what is used, and map the used. Don't map the free. It is a better step towards proper memory management.
This is a bootloader. I am not going to start implementing a "proper" memory manager in my bootloader. I just want to get the data to the kernel so that it can do proper memory management. Multiboot and EFI can decide to put my data anywhere in memory. ACPI, EFI firmware and other reserved memory ranges can be anywhere in the first 4 GB. Much easier to map it all than starting figuring out where things got allocated by GRUB2 or the firmware.

The reason I want these pages read-only is just as a safety net in case my kernel decides to write in the first 4 GB (i.e.: to catch bugs). I fully intend on un-mapping it all once the kernel initialization is completed.

Beside, where did you get the idea that this was my final design / implementation?
It's still better to have a proper memory management. Even if it is for a basic thing that is done just once. Map only what you use, it's a waste of time to map anything. And it may hide bugs that will make your life harder in the future.
Consider that in the future you will probably need to adapt your code to match other boot loaders, or other boot requirements.
Ideally, your boot loader will transfer control to a preliminary component that will receive a memory map and will decide what to do with it.

It's okay to use it like this for now, you probably just want to see some things working in order to make an idea. But remember to come back sooner or later.

Re: Why does my kernel work ?!?

Posted: Mon May 09, 2016 4:56 pm
by kzinti
zdz wrote:It's still better to have a proper memory management.
I don't agree that having any kind of advanced memory management in a boot loader is a good idea. It is a over-engineering, a waste of time and a form of mental masturbation.
zdz wrote:Even if it is for a basic thing that is done just once. Map only what you use, it's a waste of time to map anything.
It's actually much faster (programmer time *and* runtime) to just identity-map the first 4 GB of memory than to do what you propose.
zdz wrote:Ideally, your boot loader will transfer control to a preliminary component that will receive a memory map and will decide what to do with it.
That's exactly what I am doing. Go read this thread again. Go read the code. You obviously didn't do either. Instead you just repeat generic advice given to every newbie about memory management. The design you propose is what I am implementing: a bootloader that transfers control to my kernel and pass in a memory map as a parameter.

This wasn't a design question, this was a very specific technical question. It got answered, correctly, by omarrx024.
zdz wrote:It's okay to use it like this for now, you probably just want to see some things working in order to make an idea. But remember to come back sooner or later.
Ideally you would understand from my post and my code that I have a lot of experience as a programmer and that I was stuck with a technicality of the x86 processor. I wasn't looking for bad / unrelated advise on how to design my boot code.