Thank you for helping me(=newbies)
Now I will add one more step to the booting sequence for enabling paging.
Simple bootloader (512bytes : 0x7c00)
loading a kernel image from the FAT filesystem.
Jump to the loaded kernel
Kernel (now, this image is composite with 2 parts : one for enabling paging(0x7e00) and some initialization for the real kernel and the other for the real kernel(?) in the virtual memory space(0xC0000000)
when I try to write new image (has 2 parts mentioned above), one more things make me crazy,.
I think I should to write ld script to build it. one for setup stage, its base address will be the 0x7e00 and the other for kernel on virtual memory, so its base address will be the 0xC0000000
Am I right? do I need to write ld script?
ps. I try to avoid using the GRUB(or other bootloader which support virtual memory for the kernel) because this is for studying how OS works and understands how it can be implementing.
ps. of course, kernel image is only one, it just built with two parts. so I will make page table for second part in an image to map them to the 3GB area after enabling the paging.
How did you move your kernel to above 3GB area?
Re: How did you move your kernel to above 3GB area?
http://nicesj.com
With the software, What You Think Is What You Get.(WYTIWYG)
With the software, What You Think Is What You Get.(WYTIWYG)
Re: How did you move your kernel to above 3GB area?
Hi,
I'd ask the BIOS which areas are "safe to use" RAM before I loaded the kernel, and I'd use this information to setup some sort of memory management, and I'd allocate pages (and page tables, page directory, etc) to store the kernel in while the kernel is being loaded. For example, load 4 KiB of kernel into a buffer, allocate a new/free page of RAM, copy the 4 KiB of kernel code/data into this allocated page of RAM, then insert the page into a page table; and continue until the entire kernel is loaded (and then allocate and map more pages of RAM for the kernel's ".bss").
That way, if the kernel is 2 MiB (even if the kernel is 200 MiB!), you can load it into RAM *safely*, without accidentally overwriting any reserved areas, or ROM, or anything.
The next question is, what format will the kernel be in? If it's an ELF object file, then you'll need to parse the ELF header, etc. IMHO it's much easier to use a flat binary file format (and invent your own extremely simple header, if necessary, to avoid the need to parse anything complicated).
Of course the kernel will need to know about whatever is in the address space (and free RAM, etc). If your boot code already got this information from the BIOS then it can pass it to the kernel somehow. What other information might the kernel need from the BIOS (that would be easier to get when you can still use the BIOS)? Maybe you could gather information about hard disks and floppy drives, serial ports, parallel ports, etc; find out if a keyboard is present, find out if a video card is present, etc?
Now, about video - which video mode? You probably assume that the BIOS left you with 80*25 text mode (but that's not always the case). It might be a good idea to set a video mode and/or find out about the current video mode, so you can tell the kernel about it. Maybe you might want to setup a high resolution video mode or something too, like "640 * 480 * 32-bits per pixel" (or whatever is supported by the video card), and then tell the kernel the horizontal resolution, vertical resolution, address of the display memory buffer, bytes between screen lines and pixel format. Maybe you wouldn't mind a little boot menu so the user can choose which video mode to use (just in case there's no suitable video driver for your OS yet).
You could pass a lot of useful information to the kernel. For my OS, I build a large structure containing entries, where each entry begins with an entry type, so that I can add different types of entries whenever I like (without breaking older kernels).
Another very common idea is to use compression. For example, compress the kernel (and anything else), and have decompression code in the boot loader. This usually improves boot speeds, because loading data from disk is slow (and loading half as much data from disk is only half as slow, even if the decompression adds a little time).
Of course all of this won't fit in a 512 byte boot loader, but nobody said a boot loader needs to be 512 bytes - you could have a 200 KiB boot loader (where code in the first 512-bytes loads the remaining sectors of the boot loader).
Cheers,
Brendan
If you want to do things properly, then it's rarely that simple. Which physical pages are you going to use (to store the kernel and to use for page tables, page directory, etc); and, once you've got paging working how will you use the BIOS functions to determine how much RAM is installed (and where that RAM is, and whatever else is in the physical address space)?nicesj wrote:Simple bootloader (512bytes : 0x7c00)
loading a kernel image from the FAT filesystem.
Jump to the loaded kernel
Kernel (now, this image is composite with 2 parts : one for enabling paging(0x7e00) and some initialization for the real kernel and the other for the real kernel(?) in the virtual memory space(0xC0000000)
I'd ask the BIOS which areas are "safe to use" RAM before I loaded the kernel, and I'd use this information to setup some sort of memory management, and I'd allocate pages (and page tables, page directory, etc) to store the kernel in while the kernel is being loaded. For example, load 4 KiB of kernel into a buffer, allocate a new/free page of RAM, copy the 4 KiB of kernel code/data into this allocated page of RAM, then insert the page into a page table; and continue until the entire kernel is loaded (and then allocate and map more pages of RAM for the kernel's ".bss").
That way, if the kernel is 2 MiB (even if the kernel is 200 MiB!), you can load it into RAM *safely*, without accidentally overwriting any reserved areas, or ROM, or anything.
The next question is, what format will the kernel be in? If it's an ELF object file, then you'll need to parse the ELF header, etc. IMHO it's much easier to use a flat binary file format (and invent your own extremely simple header, if necessary, to avoid the need to parse anything complicated).
Of course the kernel will need to know about whatever is in the address space (and free RAM, etc). If your boot code already got this information from the BIOS then it can pass it to the kernel somehow. What other information might the kernel need from the BIOS (that would be easier to get when you can still use the BIOS)? Maybe you could gather information about hard disks and floppy drives, serial ports, parallel ports, etc; find out if a keyboard is present, find out if a video card is present, etc?
Now, about video - which video mode? You probably assume that the BIOS left you with 80*25 text mode (but that's not always the case). It might be a good idea to set a video mode and/or find out about the current video mode, so you can tell the kernel about it. Maybe you might want to setup a high resolution video mode or something too, like "640 * 480 * 32-bits per pixel" (or whatever is supported by the video card), and then tell the kernel the horizontal resolution, vertical resolution, address of the display memory buffer, bytes between screen lines and pixel format. Maybe you wouldn't mind a little boot menu so the user can choose which video mode to use (just in case there's no suitable video driver for your OS yet).
You could pass a lot of useful information to the kernel. For my OS, I build a large structure containing entries, where each entry begins with an entry type, so that I can add different types of entries whenever I like (without breaking older kernels).
Another very common idea is to use compression. For example, compress the kernel (and anything else), and have decompression code in the boot loader. This usually improves boot speeds, because loading data from disk is slow (and loading half as much data from disk is only half as slow, even if the decompression adds a little time).
Of course all of this won't fit in a 512 byte boot loader, but nobody said a boot loader needs to be 512 bytes - you could have a 200 KiB boot loader (where code in the first 512-bytes loads the remaining sectors of the boot loader).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.