Hi,
makuc9 wrote:
I know this will sound foolish & noobish, but I couldn't really find anything useful about it.
I successfully finished FAT32 bootloader (well, depends on the prospective...I guess really completed is only part that loads next stage located within FAT32 by filename provided) for my USB, but now I am stuck with memory mapping- I read the articles about it here, I wrote the function to make it, but now I keep asking myself what the heck should I do with reserved memory that it returns?
I mean: Should I be doing some special privileges (ring 0 only or something) with it in GDT? Or should I just simply make "usable data" and only prevent access to it for anything other than kernel (in case the need arrives) within functions for dedicating memory to other processes? Or should I do both? (or is it only up to me in the end?)
In general, the 'reserved' parts of the memory map are areas that the OS shouldn't touch and never needs to access. However, during boot an OS may need to search for a few different tables (e.g. ACPI tables, SM BIOS tables, MP specification tables) and these searches typically include searching the BIOS area (which is reported as 'reserved'). For this reason, I'd search for these tables and copy them to normal usable RAM in the boot code somewhere (e.g. before paging is started) so that the rest of the OS can treat the tables like normal data (and so that the boot code can reclaim any 'ACPI reclaimable' areas before passing control to the rest of the OS, to avoid the need for the rest of the OS to worry about it).
makuc9 wrote:
A little off topic here:
I also know I should get myself better familiar with memory addressing first, but I still decided to ask about it here, since I am already creating this topic. I'd like to hear some more explaination on memory mapping (making higher half kernel) and for memory addressing within GDT (once it is created) - don't worry, I will do a lot more research on it, it is just that I am not a native english speaker, so I have difficulties finding correct keywords for searching (and understanding some of stuff written in wiki)... I'd just like to "remove" my kernel from 1MB memory (to leave it free...You never know when you'll need to jump back there, since I am planning on operating within 64bit mode mostly - no VMode there).
This is what paging is for - it lets you map any physical pages (at any physical address) into the virtual address space anywhere. For example, the kernel might be at the physical address 0x00100000, and paging might map it to the virtual address 0xFFFFFFFF80000000.
makuc9 wrote:
Also another (simple) question (for which I might know the answer already, but being sure is breing sure): About running 32bit programms within 64bit mode. Do I have to switch to compatibility mode? (within 64bit mode you CAN access 32bit registers, so I guess I wouldn't really have to do that, switch to compatibility mode, I mean, right? Only other bits, non 32bit ones of 64bit registers, gets zeroed?).
In protected mode, the GDT/LDT entry for a code descriptor has a flag to select 16-bit or 32-bit; and this allows you to run 16-bit code or 32-bit code in protected mode.
In long mode, the GDT/LDT entry for a code descriptor has 2 flags to select 16-bit, 32-bit or 64-bit; and this allows you to run 16-bit code, 32-bit code or 64-bit code in long mode. However, 64-bit code behaves a little differently (e.g. most segment bases and limits are ignored, some instructions are deprecated and used as prefixes, etc) so CPU manufacturers like to call it "the 64-bit sub-mode of long mode", and call 16-bit and 32-bit code in long mode "the compatibility sub-mode of long mode".
You can't (easily) run 32-bit programs in the 64-bit sub-mode of long mode; but you can run 16-bit and 32-bit programs in the compatibility sub-mode of long mode.
Note: For all of the above, "16-bit code" means 16-bit code designed for protected mode segmentation and protection rules; and does not include real mode code designed for real mode segmentation and real mode's complete lack of protection rules. You can run real mode code (safely) in protected mode using "the virtual8086 sub-mode of protected mode", but there isn't any "virtual8086 sub-mode of long mode" so you can't run real mode code in long mode at all.However; a lot of the opcodes for 32-bit instructions have the same meaning in 64-code code, so if 32-bit code is very carefully designed (e.g. doesn't make assumptions about stack alignment or offsets from ESP, doesn't use instructions like PUSHAD/POPAD, doesn't use smaller versions of INC/DEC, etc.) it would be possible to have code that will run in 32-bit protected mode and 32-bit long mode and 64-bit long mode. You'd have to write this code manually in assembly (while being extremely cautious) though, as there are no tools that will help (no compiler will generate "mixed mode" code, and no assembler will warn you when you've used a normal 32-bit instruction that doesn't behave the same in 64-bit code). Of course this would be difficult and mostly pointless (easier to just write normal 32-bit code, or normal 64-bit code).
Cheers,
Brendan