Why does my kernel work ?!?
Why does my kernel work ?!?
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.
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.
Last edited by kzinti on Mon May 09, 2016 1:11 pm, edited 1 time in total.
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: Why does my kernel work ?!?
When bit 16 (value 0x10000) of CR0 register is cleared, the kernel can write to read-only pages.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
-
- Member
- Posts: 501
- Joined: Wed Jun 17, 2015 9:40 am
- Libera.chat IRC: glauxosdever
- Location: Athens, Greece
Re: Why does my kernel work ?!?
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
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
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: Why does my kernel work ?!?
Actually, AMD released x86_64 (or AMD64 really) in 2000.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).
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: Why does my kernel work ?!?
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.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.
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?
-
- Member
- Posts: 501
- Joined: Wed Jun 17, 2015 9:40 am
- Libera.chat IRC: glauxosdever
- Location: Athens, Greece
Re: Why does my kernel work ?!?
Hi,
Regards,
glauxosdever
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.omarrx024 wrote:Actually, AMD released x86_64 (or AMD64 really) in 2000.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).
Sorry, I misread. But anyway, I think it's a good idea for later.kzinti wrote:Beside, where did you get the idea that this was my final design / implementation?
Regards,
glauxosdever
- Kazinsal
- Member
- Posts: 559
- Joined: Wed Jul 13, 2011 7:38 pm
- Libera.chat IRC: Kazinsal
- Location: Vancouver
- Contact:
Re: Why does my kernel work ?!?
The WP bit was introduced on the 486.omarrx024 wrote:Actually, AMD released x86_64 (or AMD64 really) in 2000.
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: Why does my kernel work ?!?
You mentioned above that your kernel was 64-bit.Kazinsal wrote:The WP bit was introduced on the 486.omarrx024 wrote:Actually, AMD released x86_64 (or AMD64 really) in 2000.
What I meant was that every x86-64 CPU supports the WP bit.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: Why does my kernel work ?!?
It's fascinating how no one reads the whole post and then start nitpicking each other's reply.
Re: Why does my kernel work ?!?
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.kzinti wrote: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.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.
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?
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 ?!?
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:It's still better to have a proper memory management.
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: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.
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.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.
This wasn't a design question, this was a very specific technical question. It got answered, correctly, by omarrx024.
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.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.