I've finally started getting my head wrapped around how paging works, converted my system to operate as a higher half kernel, and now I'm moving into the memory management portion of things. One item that has me rather concerned is the size of my kernel, and the initial page table that gets set up. I'm still learning, so I'm designing a 32-bit non-PAE system just to get my head wrapped around things. When I initialize paging I create a page directory with one entry, and one page table with the minimal number of entries needed to map the kernel. This is working alright for now, but I'm starting to get concerned about the size of my kernel. Once my kernel becomes larger than 4MB in size a single page table will no longer be sufficient to map the whole thing when the system boots. As things currently stand the kernel starts at virtual address 0xC0101026, and ends at virtual address 0xC012DDD0. When I set up my page directory I'm mapping everything from physical address 0x0 - 0x12DDD0 to the virtual address range 0xC0000000 - 0xC012DDD0. This is to make sure I map everything in low memory (what I'm thinking of as "GRUB space"), the kernel, the page directory, and a page table. In order to simplify things while setting up my bitmap for frame allocation I simply declared an array using C, and it has a data type of u8int with 131072 elements. Doing so ended up making my kernel a full megabyte larger, but I figured that such a direct approach was simpler than trying to map an additional 32 page tables for the bitmap. As it stands, my whole system (in memory) is currently around 1.18 MB so I'm using a little more than a quarter of the virtual address space on the page table, but the overwhelming majority of that space is for the bitmap. I'm not doing any recursive mapping of the page directory (yet) because I'm keeping its virtual address stored in a static pointer, and it's residing within the kernel.
Here's the code that's concerning me.
Here's my code for my bitmap.
I'm worried that as I keep programming the kernel will inevitably grow beyond 4MB in size, and that once it does I'll have major issues with sections of the kernel not being mapped to any virtual address because I'm only setting up a single page table. What's the best way to avoid, or address, these concerns? Should I just alter the way I'm initializing paging, and create as many page tables that are required to map the whole kernel? Should I be dynamically mapping the space I'll use for my bitmap instead of letting C worry about it? Is there a concept I'm missing, or am I going down a nonproductive road with this avenue of development? Am I worrying about nothing?
Kernel size considerations when initializing paging
Kernel size considerations when initializing paging
Last edited by PatSanf on Fri Mar 13, 2015 12:20 pm, edited 1 time in total.
Re: Kernel size considerations when initializing paging
Just add as many page tables as you need?
Re: Kernel size considerations when initializing paging
So just go with the simple, and dirty approach. I was hoping there was a solution that's a little more elegant. Thank you for your input!kzinti wrote:Just add as many page tables as you need?
Re: Kernel size considerations when initializing paging
I'm not sure what you had in mind. If you need more memory mapped, then you have to map more memory. If your only page table is full and you want to map more memory, then you need more page tables. There is no way around this.
Re: Kernel size considerations when initializing paging
Obviously. What I'm more concerned about is the system getting stupidly large for no reason. At this point, with the space for the bitmap, it's more than a floppy disk would hold. I'm obviously not going to be writing anything to a floppy, but I'm thinking that the overall system should be rather small for a simple *nix clone type system. Another thing I'm worried about is the original mappings that are set up by the boot loader, as found in the Higher Half Bare Bones article on the wiki. How can I be sure, other than using the linker, that all of the code required by the kernel to get itself up and running is within that 4MB that's initially mapped before the kernel is actually called?kzinti wrote:I'm not sure what you had in mind. If you need more memory mapped, then you have to map more memory. If your only page table is full and you want to map more memory, then you need more page tables. There is no way around this.
-
- Member
- Posts: 29
- Joined: Tue Jan 20, 2015 8:33 pm
Re: Kernel size considerations when initializing paging
I think you're a little misinformed about the state of your system when GRUB hands control to your kernel - paging is disabled at that point, meaning the only page mappings that ever get set up are yours. The Higher Half Bare Bones article is indeed limited to a 4MB kernel size, as it's written - but that's only because at the top of the loader.asm file it sets up page tables with only one 4MB page mapped in, not because of any GRUB limitation.PatSanf wrote:Obviously. What I'm more concerned about is the system getting stupidly large for no reason. At this point, with the space for the bitmap, it's more than a floppy disk would hold. I'm obviously not going to be writing anything to a floppy, but I'm thinking that the overall system should be rather small for a simple *nix clone type system. Another thing I'm worried about is the original mappings that are set up by the boot loader, as found in the Higher Half Bare Bones article on the wiki. How can I be sure, other than using the linker, that all of the code required by the kernel to get itself up and running is within that 4MB that's initially mapped before the kernel is actually called?kzinti wrote:I'm not sure what you had in mind. If you need more memory mapped, then you have to map more memory. If your only page table is full and you want to map more memory, then you need more page tables. There is no way around this.
You can map as much memory as you like to use your kernel, but before you have paging set up, you don't need to worry about whether or not your kernel is mapped
- Alexis211
- Posts: 14
- Joined: Mon Sep 14, 2009 9:19 am
- Libera.chat IRC: lxpz
- Location: France
- Contact:
Re: Kernel size considerations when initializing paging
There is no reason that the space you allocate for your frame bitmap should take up space in the kernel binary that you write on a floppy or whatever. It's juste a bunch of uninitialized data (or zeroes), and the ELF format handles that by saying : I have no data for this section, just reserve me this address range and zero it out when loading the kernel.PatSanf wrote: Obviously. What I'm more concerned about is the system getting stupidly large for no reason. At this point, with the space for the bitmap, it's more than a floppy disk would hold. I'm obviously not going to be writing anything to a floppy, but I'm thinking that the overall system should be rather small for a simple *nix clone type system. Another thing I'm worried about is the original mappings that are set up by the boot loader, as found in the Higher Half Bare Bones article on the wiki. How can I be sure, other than using the linker, that all of the code required by the kernel to get itself up and running is within that 4MB that's initially mapped before the kernel is actually called?
Also, rather than allocating the bitmap as a fixed-sized static variable in your C code, you should think of a way to allocate that bitmap on-demand at kernel initalization time (before setting up paging, typically), so that you can use the information GRUB gives you about the available RAM and only allocate a bitmap big enough for your needs. Then you have a problem if you are running in higher half and have only mapped the first 4MB of ram for your kernel but your bitmap won't fit in the space between the end of your kernel and the 4MB mark. In that case just find out a way to map more pages at fixed addresses. Then you mark in your bitmap that all the pages until the end of the bitmap are used, and the rest is free.
- eryjus
- Member
- Posts: 286
- Joined: Fri Oct 21, 2011 9:47 pm
- Libera.chat IRC: eryjus
- Location: Tustin, CA USA
Re: Kernel size considerations when initializing paging
I'm willing to bet (your bitmap.c link is broken) that you are statically allocating a number of structures (in your .data section and not in your .bss section). To confirm this, I would investigate the size of your object files and start with your largest file and determine where you are using space. The result of this analysis will help you determine where to focus your attention changing things from statically allocated to dynamically allocated.PatSanf wrote:I'm worried that as I keep programming the kernel will inevitably grow beyond 4MB in size, and that once it does I'll have major issues with sections of the kernel not being mapped to any virtual address because I'm only setting up a single page table. What's the best way to avoid, or address, these concerns?
So, dynamic allocation required a memory manager. In fact, there are 3 memory managers to consider:
- Your physical memory manager
- Your virtual memory manager
- Your kernel heap manager
I offered in another post that you should hand-code the paging tables in order to learn and understand the structures. Now, it's time to build the functions to set this up dynamically and replace the hand-coded stuff with dynamically built stuff.
I hope this helps.
Adam
The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal
"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal
"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
Re: Kernel size considerations when initializing paging
I'm worrying about something similar these days. My kernel is somewhat established and a bit large-ish, for hobby kernels at least, and it's just using over 1-2 MiB for its own code, data, and other things present in the ELF kernel. That's still a good deal's distance from 2 MiB considering I've been working on this for a couple years. I wouldn't worry that much about it early on. Besides, the loading 1 MiB scheme multiboot kernels usually use is fundamentally broken as it makes assumptions about the layout and availability of physical memory. Isn't there sometimes a hole at 16 MiB for ISA, at least on older systems? That can be an issue. I'll eventually design a better boot protocol with paging enabled, so the kernel can be linked at 3 GB directly, and the bootloader sets up paging and puts it there, using whatever physical frames it decided to use. But not when using multiboot, that is just too broken assumptionwise.