Reset when i enable paging

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
omin0us

Reset when i enable paging

Post by omin0us »

I started an OS before. but i decided to start over again, as last time i copied a lot of the paging code, so i didn't have a full understanding, and this time i want to make it multiboot compliant. anyways, right now, i am just Identity mapping the first 4 megs. here is my code so far.

boot.asm:

Code: Select all

extern meminit
[BITS 32]
global setup    ;GRUB loads kernel and enters here
setup:
     cmp     eax,0x2BADB002
     jne       notmb

     mov eax, 0xFFFF
     mov esp, eax  ;set temp stack pointer
     mov ebp, eax  ;set temp base pointer

     push ebx     ;push pointer to multiboot info
     call meminit
     pop ebx

notmb:
     hlt
     jmp notmb

;multiboot header info below
.
.
.
and here is meminit()

Code: Select all

static uint32_t pages;

void meminit(multiboot_info_t *mb_info)
{
     uint32_t *pdir, *ptab;
     int i;

     pages = ((mb_info->mem_lower + mb_info->mem_upper)*1024) / PAGESIZE;
     
     //Use the last page in memory for the page directory
     pdir = (uint32_t *)(--pages * PAGESIZE);
     //map the Page Directory to the last PDE
     //this will now be mapped to virtual 0xffc00000
     pdir[1023] = (uint32_t)pdir | PG_PRESENT | PG_WRITABLE;

     //Identity Map the first 4Megs of memory
     ptab = (uint32_t *)((--pages * PAGESIZE) | PG_PRESENT | PG_WRITABLE);
     for(i=0; i<1024; i++)
     {
          ptab[i]=(i*PAGESIZE)| PG_PRESENT | PG_WRITABLE;
     }
     pdir[0] = (uint32_t)ptab;

     //set page directory base address
     set_cr3(pdi

     //enable paging
     set_cr0(get_cr0 | CR0_PG);
}
using bochs, it reboots using that code.
but if i comment out the line that enables paging, it will hit the notmb loop fine and endlessly loop like its supposed to. I dont see any blatantly obvious problems. Could someone please help me with this?
paulbarker

Re:Reset when i enable paging

Post by paulbarker »

You're adding the PG_PRESENT and PG_WRITABLE flags to ptab before you use it as an array. You want to add the in afterwards. Think about it, you should be able to understand why this is a problem.
omin0us

Re:Reset when i enable paging

Post by omin0us »

Ah, yes, i do see why that is a problem. cause then all the offsets when using it in an array will be off by 0x03. anyways, even after changing that, it still resets :(
raywill

Re:Reset when i enable paging

Post by raywill »

omin0us wrote: Ah, yes, i do see why that is a problem. cause then all the offsets when using it in an array will be off by 0x03. anyways, even after changing that, it still resets :(
I ever had similar problem .
After I add indentity-mapping carefully ,everything went fine again :)
omin0us

Re:Reset when i enable paging

Post by omin0us »

So this is what the meminit() code looks like now, but it is still restarting the computer (bochs).

Code: Select all

static uint32_t pages;

void meminit(multiboot_info_t *mb_info)
{
    uint32_t *pdir, *ptab;
    int i;

    pages = ((mb_info->mem_lower + mb_info->mem_upper)*1024) /
PAGESIZE;

    //Use the last page in memory for the page directory
    pdir = (uint32_t *)(--pages * PAGESIZE);
    //map the Page Directory to the last PDE
    //this will now be mapped to virtual 0xffc00000
    pdir[1023] = (uint32_t)pdir | PG_PRESENT | PG_WRITABLE;

    //Identity Map the first 4Megs of memory
    ptab = (uint32_t *)(--pages * PAGESIZE);
    for(i=0; i<1024; i++)
    {
          ptab[i]=(i*PAGESIZE)| PG_PRESENT | PG_WRITABLE;
    }
    pdir[0] = (uint32_t)ptab | PG_PRESENT | PG_WRITABLE;

    //set page directory base addr[ess
    set_cr3(pdir);

    //enable paging
    set_cr0(get_cr0 | CR0_PG);

}
YeXo

Re:Reset when i enable paging

Post by YeXo »

Code: Select all

//Use the last page in memory for the page directory
pdir = (uint32_t *)(--pages * PAGESIZE);
This code doesn't work as it looks like. For example, if your memory looks like this:
0-600kb - free
1-15mb - free
16-32mb - free
with a memory hole for the bios and a memory hole at 15-16mb for isa.
You code initiate pdir to addr 30mb+596kb and not 31mb+1020kb.

in your boot.asm this line:

Code: Select all

pop ebx
is pretty useless as you code will do nothing after that. I think a

Code: Select all

cli
hlt
is better here dan an endless loop with hlt's
omin0us

Re:Reset when i enable paging

Post by omin0us »

YeXo wrote:

Code: Select all

//Use the last page in memory for the page directory
pdir = (uint32_t *)(--pages * PAGESIZE);
This code doesn't work as it looks like. For example, if your memory looks like this:
0-600kb - free
1-15mb - free
16-32mb - free
with a memory hole for the bios and a memory hole at 15-16mb for isa.
You code initiate pdir to addr 30mb+596kb and not 31mb+1020kb.
so where do you guys suggest i store the page directory and page tables? I dont think that is why it is rebooting though.
in your boot.asm this line:

Code: Select all

pop ebx
is pretty useless as you code will do nothing after that. I think a

Code: Select all

cli
hlt
is better here dan an endless loop with hlt's
i realize that the pop ebx is useless for now. but that will be used later on when i add more code.
omin0us

Re:Reset when i enable paging

Post by omin0us »

does no one have an answer for this?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Reset when i enable paging

Post by Brendan »

Hi,
omin0us wrote:
YeXo wrote:

Code: Select all

//Use the last page in memory for the page directory
pdir = (uint32_t *)(--pages * PAGESIZE);
This code doesn't work as it looks like. For example, if your memory looks like this:
0-600kb - free
1-15mb - free
16-32mb - free
with a memory hole for the bios and a memory hole at 15-16mb for isa.
You code initiate pdir to addr 30mb+596kb and not 31mb+1020kb.
so where do you guys suggest i store the page directory and page tables? I dont think that is why it is rebooting though.
You could store the page directory where you intended to store it, rather than where you are storing it...

For example:

Code: Select all

#define MEM_UPPER_BASE     (16*1024*1024)         // Address for start of upper memory

//Use the last page in memory for the page directory
pdir = (uint32_t *)(MEM_UPPER_BASE + mb_info->mem_upper*1024 - 4096);
pages--;
Of course this won't work if there is no upper memory and I'm not too sure what mb_info->mem_lower and mb_info->mem_upper actually are.

A better idea would be to get a list of RAM areas from the BIOS's "Int 0x15, eax=0xE820" function (or from GRUB's "memory map" if you use it - it's the same thing) and use the last page in the highest area. Designing your code to use 2 RAM areas at fixed starting addresses isn't such a good idea - there could only be one area or there could be more than 2 areas.


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.
paulbarker

Re:Reset when i enable paging

Post by paulbarker »

Upper memory started at 1MB last time I checked, according to GRUB anyway. Lower memory is everything below the ISA hole and upper memory is everything above.

Or so I thought.
YeXo

Re:Reset when i enable paging

Post by YeXo »

paulbarker wrote: Upper memory started at 1MB last time I checked, according to GRUB anyway. Lower memory is everything below the ISA hole and upper memory is everything above.

Or so I thought.
There is a contradiction in what you're saying now:
upper memory: start at 1mb
lower memory: below ISA hole (15-16mb)
upper memory: above ISA hole (16mb and above)

I thought upper memory was anything above 1 mb and lower memory was everything belows 1mb (and the bios).

The best way to check the end of the physical memory is indeed to use the memory map (from grub or from the bios).
paulbarker

Re:Reset when i enable paging

Post by paulbarker »

The ISA hole is 640k-1MB, theres another hole at 15MB-16MB but I dont know if thats also called the ISA hole.
JoeKayzA

Re:Reset when i enable paging

Post by JoeKayzA »

paulbarker wrote: The ISA hole is 640k-1MB, theres another hole at 15MB-16MB but I dont know if thats also called the ISA hole.
IIRC this has something to do with OS/2 support. OS/2 expects a memory hole between 15 and 16MB, but most BIOS should offer an option to disable this behaviour.

cheers Joe
B.E

Re:Reset when i enable paging

Post by B.E »

I thought that 0-640kb is convetional. 640kb to 1mb was upper memory, +1mb was extendard memory, that 's in MS-DOS. I know there is a ISA memory hole at 15-16MB.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Reset when i enable paging

Post by Brendan »

Hi,
JoeKayzA wrote:IIRC this has something to do with OS/2 support. OS/2 expects a memory hole between 15 and 16MB, but most BIOS should offer an option to disable this behaviour.
The ISA hole from 15 MB to 16 MB is a hardware requirement, and can't be attributed to any OS...

Basically the ISA bus itself only has 20 address lines, which means anything on that bus can only access the first 16 MB of physical addresses. This means if you've got an ISA card that supports some sort of memory mapped I/O (e.g. an ISA video card with linear frame buffer support), then it's memory mapped I/O region must be below 16 MB.

To allow for this chipsets have the ISA memory hole, which allows these cards to be mapped into the physical address space between 15 MB and 16 MB so that these older ISA cards can still work (hardware "backwards compatibility").

Most modern chipsets still support the ISA hole as a feature that can be enabled or disabled. Whether or not the motherboard/BIOS allows the ISA hole to be enabled/disabled depends on how the chipset is used by the motherboard/BIOS.

For example, if the motherboard supports ISA cards then it could always enable the ISA hole, and if the motherboard doesn't support ISA cards then it could always disable the ISA hole. In both cases the motherboard/BIOS could have an option to enable or disable the hole. This means you can have 4 different motherboards that use the same chipset but have different ISA hole support...

I'm not sure about OS/2 - I half-remember something about it requiring an ISA hole and I think it may have been a bug in OS/2. An OS should work regardless of whether the hole is present or not...

In addition to this some older chipsets support another hole from 512 KB to 640 KB (or from 0x00080000 to 0x0009FFFF). Newer chipsets don't support this hole, and I'm not too sure what it's purpose was (but I would assume it dates back to the original XT's that came with 512 KB of RAM). I've never seen a computer that has this hole.

For "traditional" memory area naming, from 0 to 640 KB was called "conventional memory", from 1 MB to "1 MB + 0xFFF0 bytes" was called "high memory" and anything above that was called "extended memory" (but often high memory was considered part of extended memory).

Terms like "lower memory" and "upper memory" could mean anything you like. Upper memory could be anything above 4 GB, above 16 MB, above 1 MB, etc. I'm not sure how GRUB (or the original poster) defines these terms.


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.
Post Reply