Hey all, Just curious!
a) How much Stack space should I give the Kernel?
b) Ive spent some time tweaking my bootloader to do more!
It now does:
- FAT12 Loading of Stage2+Kernel file.
- Stage2 gets total count of system RAM.
- Stage2 also gets BIOS Equipment list and tells you what
it detected.
(More precisely, Stage2 saves the Memory count and
BIOS Equipment word, the Kernel has functions that
retrieves and interpretes it.)
So, In conclusion
- Whats a good size for Kernel stack?
- Would anyone like the Bootloader source?
~Zeii.
Generic questions!
Re:Generic questions!
I would love the Bootloader source... I've actually been looking for something like that this entire week.
(as for the kernel stack, I'm not sure myself... just started in OS development a month ago.)
(as for the kernel stack, I'm not sure myself... just started in OS development a month ago.)
- Kevin McGuire
- Member
- Posts: 843
- Joined: Tue Nov 09, 2004 12:00 am
- Location: United States
- Contact:
Re:Generic questions!
Give it 4096 bytes, and forget about it for a long time mabye?
Just a thought but you can find the function that has the most total local function space used by adding the size of each local varible in that function; sizeof(theVarible). Then find the biggest local function space call in the kernel.
main() used 12 bytes.
a() used 5 bytes.
b() used 2 bytes.
main() calls a() calls b() uses 19 bytes.
main() calls a() uses 17 bytes.
So the stack would need to be greater than 19 bytes. You could add about 12 bytes more for each function call. So that kernel might need around 63 bytes as a good rule of thumb! I myself would never go that low.
Just a thought but you can find the function that has the most total local function space used by adding the size of each local varible in that function; sizeof(theVarible). Then find the biggest local function space call in the kernel.
main() used 12 bytes.
a() used 5 bytes.
b() used 2 bytes.
main() calls a() calls b() uses 19 bytes.
main() calls a() uses 17 bytes.
So the stack would need to be greater than 19 bytes. You could add about 12 bytes more for each function call. So that kernel might need around 63 bytes as a good rule of thumb! I myself would never go that low.
Re:Generic questions!
Keep in mind...
The Citadel boot sequence is a little strange.
Stage1 Bootloader loads the file 'cstage2.bin'.
CSTAGE2.BIN is the Second stage bootloader and the Kernel, combined.
Second stage bootloader is 0x000 - 0x200 in the file.
Kernel is from 0x200 onwards.
Also, Second stage stores:
- Size of Memory (1MiB to 16MiB) at 0x7C00 to 0x7C01
- Size of Memory (16MiB +) at 0x7C02 to 0x7C03
- BIOS Equipment Word at 0x7C04 to 0x7C06
All ive got to do now is fix the Stack bug with the Bootloader itself.
Which shouldnt be hard. The stack atm is set at 0xFFFF, going down.
So once you load over that point, it dies. But, Ill relocate it somewhere crazy, so that wont happen .
Youll have to write the functions for your Kernel to interprete the BIOS Word, aswell as retrieve the Memory count.
~Zeii.
The Citadel boot sequence is a little strange.
Stage1 Bootloader loads the file 'cstage2.bin'.
CSTAGE2.BIN is the Second stage bootloader and the Kernel, combined.
Second stage bootloader is 0x000 - 0x200 in the file.
Kernel is from 0x200 onwards.
Also, Second stage stores:
- Size of Memory (1MiB to 16MiB) at 0x7C00 to 0x7C01
- Size of Memory (16MiB +) at 0x7C02 to 0x7C03
- BIOS Equipment Word at 0x7C04 to 0x7C06
All ive got to do now is fix the Stack bug with the Bootloader itself.
Which shouldnt be hard. The stack atm is set at 0xFFFF, going down.
So once you load over that point, it dies. But, Ill relocate it somewhere crazy, so that wont happen .
Youll have to write the functions for your Kernel to interprete the BIOS Word, aswell as retrieve the Memory count.
~Zeii.
Re:Generic questions!
Ive added another little feature.
The Bootloader now retrieves the filesize of the file being loaded.
In my case, CSTAGE2.BIN. Sweet.
Kernel size is tracked! Woohoo!
~Zeii.
The Bootloader now retrieves the filesize of the file being loaded.
In my case, CSTAGE2.BIN. Sweet.
Kernel size is tracked! Woohoo!
~Zeii.
Re:Generic questions!
Now it relocates code too.
CSTAGE2.BIN Layout...
0x0 - 0x1F7 = Bootloader Stage2 Binary.
0x1F8 - 0x1FB = Boot Kernel Size
0x1FC - 0x1FF = Microkernel Size.
0x200 - (0x200+B_KERNEL_SIZE) = Boot Kernel
(0x200+B_KERNEL_SIZE) - (0x200+(B_KERNEL_SIZE+M_KERNEL_SIZE)) = Microkernel.
Bootloader starts, fetches CSTAGE2.BIN.
Bootloader Stage2 executes, Using realmode to gather memory information and BIOS hardware list, saving 1-16MiB RAM size at 0x7c00-0x7c03, 16MiB+ RAM Size at 0x7c04-0x7c07. BIOS Equipment word at 0x7c08-0x7c0A. If using 0xE801 for Memory detection, it corrects the figure.
Sets up Protected Mode, GDT etc.
Once that is done, it relocates the Microkernel code from 0x8000+(B_KERNEL_SIZE) to 0x100000.
Does some other things, then jumps to Boot Kernel code.
Boot Kernel code does its stuff, Setting up IRQ/Exception handling, Paging, then (when there is a Microkernel to test), jumps to Microkernel code at 3GiB Virtual (mapped to 1MiB Phys).
The problem being - It wont boot on Phoenix BIOS Machines.
Im not really sure why, but it wouldnt boot before the new features.
And... Will 0-1MiB RAM range ever be erased?
The current GDT exists around the 0x7E00ish range.
The IDT exists somewhere around 0x8000, Paging structures im yet to decide where to put.
As far as ive learnt, 0x8000+B_KERNEL_SIZE isnt a safe place for anything, it all gets erased if anything is put in that range, almost likes its the programs data-zone - even though theres nothing that should be at that point, except the Microkernel code that was relocated.
*shrug*
So, this is my new task:
- Find a suitable place for Memory Management / Paging structures.
- Write new and improved Paging types/functions.
typedef struct kpt_pagedir
{
unsigned int* kp_page_directory;
unsigned int kp_page_map[524288];
// ^-- Bitmap for all possible entries.
// Each Integer stores the state of 32 pages.
}
void kp_initialize_table(kpt_pagedir* paget_initialize);
// Zeroes Page Directory (0-4096 = 0)
unsigned int* kp_add_directory_entry();
// Adds a PDE. 0-4096 in Entry zeroed.
// Returns Address to where the Entry is stored in Physical Memory.
unsigned int* kp_allocate_page(kpt_pagedir* paget_dir);
// Will allocate a Page from the Directory given as argument.
// Will set the respective Page as USED in the PageMap.
// Returns Physical Address of Page.
void kp_map_phys_virt(kpt_page_dir* paget_dir, unsigned int physical_addr, unsigned int virtual_addr);
// Will map the Virtual Address given to the Physical Address given,
// in the Page Directory given.
These are just me brainstorming.
Any input?
~Zeii.
CSTAGE2.BIN Layout...
0x0 - 0x1F7 = Bootloader Stage2 Binary.
0x1F8 - 0x1FB = Boot Kernel Size
0x1FC - 0x1FF = Microkernel Size.
0x200 - (0x200+B_KERNEL_SIZE) = Boot Kernel
(0x200+B_KERNEL_SIZE) - (0x200+(B_KERNEL_SIZE+M_KERNEL_SIZE)) = Microkernel.
Bootloader starts, fetches CSTAGE2.BIN.
Bootloader Stage2 executes, Using realmode to gather memory information and BIOS hardware list, saving 1-16MiB RAM size at 0x7c00-0x7c03, 16MiB+ RAM Size at 0x7c04-0x7c07. BIOS Equipment word at 0x7c08-0x7c0A. If using 0xE801 for Memory detection, it corrects the figure.
Sets up Protected Mode, GDT etc.
Once that is done, it relocates the Microkernel code from 0x8000+(B_KERNEL_SIZE) to 0x100000.
Does some other things, then jumps to Boot Kernel code.
Boot Kernel code does its stuff, Setting up IRQ/Exception handling, Paging, then (when there is a Microkernel to test), jumps to Microkernel code at 3GiB Virtual (mapped to 1MiB Phys).
The problem being - It wont boot on Phoenix BIOS Machines.
Im not really sure why, but it wouldnt boot before the new features.
And... Will 0-1MiB RAM range ever be erased?
The current GDT exists around the 0x7E00ish range.
The IDT exists somewhere around 0x8000, Paging structures im yet to decide where to put.
As far as ive learnt, 0x8000+B_KERNEL_SIZE isnt a safe place for anything, it all gets erased if anything is put in that range, almost likes its the programs data-zone - even though theres nothing that should be at that point, except the Microkernel code that was relocated.
*shrug*
So, this is my new task:
- Find a suitable place for Memory Management / Paging structures.
- Write new and improved Paging types/functions.
typedef struct kpt_pagedir
{
unsigned int* kp_page_directory;
unsigned int kp_page_map[524288];
// ^-- Bitmap for all possible entries.
// Each Integer stores the state of 32 pages.
}
void kp_initialize_table(kpt_pagedir* paget_initialize);
// Zeroes Page Directory (0-4096 = 0)
unsigned int* kp_add_directory_entry();
// Adds a PDE. 0-4096 in Entry zeroed.
// Returns Address to where the Entry is stored in Physical Memory.
unsigned int* kp_allocate_page(kpt_pagedir* paget_dir);
// Will allocate a Page from the Directory given as argument.
// Will set the respective Page as USED in the PageMap.
// Returns Physical Address of Page.
void kp_map_phys_virt(kpt_page_dir* paget_dir, unsigned int physical_addr, unsigned int virtual_addr);
// Will map the Virtual Address given to the Physical Address given,
// in the Page Directory given.
These are just me brainstorming.
Any input?
~Zeii.
Re:Generic questions!
as for kernel stack... I say 2pages(8k bytes)
for your bootloader.. I want to see your code to perhaps use it as an example as a reliable way to get ramsize
for your bootloader.. I want to see your code to perhaps use it as an example as a reliable way to get ramsize