Page 1 of 1

yet another noob pagging problem

Posted: Tue Sep 04, 2007 6:30 pm
by HJED
hi all i followed this tutorial http://www.osdever.net/tutorials/paging.php for my pagging and made a modification so as to make it map more memory
but it just wont compile
i am using NASM for asm and MinGW for c++
this is my NASM code for pagging

Code: Select all

[global _read_cr0]
_read_cr0:
	mov eax, cr0
	retn

[global _write_cr0]
_write_cr0:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr0,  eax
	pop ebp
	retn

[global _read_cr3]
_read_cr3:
	mov eax, cr3
	retn

[global _write_cr3]
_write_cr3:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr3, eax
	pop ebp
	retn
[global _long_mode1]
_long_mode1:
  ; cr0.PG is alread at 0 

  ; Set cr4.PAE 
mov eax , cr4
or eax , 0x2000000
mov cr4 , eax  
  ; L4PT loaded in pagging.cpp
  retn
[global _long_mode2]
_long_mode2:
  
;Set EFER.LME
mov  ecx , 0xC0000080
rdmsr
or  eax , 0x100
wrmsr 
  rent
  ;rest in paging
and here is my c++ code

Code: Select all

#include <system.h>
//this is 4mb of paging ten enables long mode
void pagtable_AND_LM_Setup() {
    unsigned long *page_directory[4][1024] = (unsigned long *) 0x9C000; 
    unsigned long * address = 0; // holds the physical address of where a page is
    unsigned int i;
    
// map the memory
    for(i=0; i<1024; i++) {
        unsigned int c;
        for(c=0; c<1024; c++) {
            page_directory[i][c] = address | 3; // attribute set to: supervisor level, read/write, present(011 in binary)
            address = address + 4096; // 4096 = 4kb
        };
        // fill  entrys of the page directory
        page_directory[i] = page_directory[i] | 3;// attribute set to: supervisor level, read/write, present(011 in binary)
    };
    
    
    
    // write_cr3, read_cr3, write_cr0, and read_cr0 all come from the assembly function
    long_mode1(); // start long mode int
    write_cr3(page_directory); // put that page directory address into CR3
    long_mode2(); // pagging int 2
    write_cr0( read_cr0() | (unsigned long *) 0x80000000); // set the paging bit in CR0 to 1
}
my NASM code asembles but my C++
code will not compile :cry:
here is the compiler output
C:\DOCUME~1\HandE\MYDOCU~1\HARRYH~1\HSim\OSCAT~1\src\b8>C:\MinGW\bin\c++ -Wall -
O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-built
in -I./include -c -o paging.o paging.cpp
paging.cpp: In function `void pagtable_AND_LM_Setup()':
paging.cpp:4: error: invalid initializer
paging.cpp:12: error: invalid operands of types `long unsigned int*' and `int' t
o binary `operator|'
paging.cpp:16: error: invalid operands of types `long unsigned int*[1024]' and `
int' to binary `operator|'
paging.cpp:23: error: cannot convert `long unsigned int* (*)[1024]' to `long uns
igned int*' for argument `1' to `void write_cr3(long unsigned int*)'
paging.cpp:25: error: invalid operands of types `long unsigned int*' and `long u
nsigned int*' to binary `operator|'
can anyone tell me why its not compileing
becouse i followed the tutorial step by step
and it dosen`t work whithout any mods ether

Posted: Tue Sep 04, 2007 6:59 pm
by frank
You cannot do binary operations on pointers (|, &). You should cast them to unsigned long or something before trying.

yet another noob paging proble

Posted: Tue Sep 04, 2007 7:44 pm
by HJED
could i call

Code: Select all

 write_cr3((unsigned long *)0x9C000) 
instead of

Code: Select all

write_cr3(page_directory)
becouse page_directory points to 0x9C000

Code: Select all

unsigned long *page_directory[4][1024] = (unsigned long *) 0x9C000; 
also
frank wrote:You cannot do binary operations on pointers (|, &). You should cast them to unsigned long or something before trying.
can`t cast arrays how would i fix those?
plz help i realy whant to get this working

Posted: Wed Sep 05, 2007 1:29 am
by HJED
plz help i know i am a NOOB and the anser to this qustion is probley quite oviuse to anyone who is good at this but i am not so plz help :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry:

Posted: Wed Sep 05, 2007 1:40 am
by pcmattman
How much C programming experience do you have?

Posted: Wed Sep 05, 2007 1:51 am
by JamesM

Code: Select all

page_directory[i][c] = address | 3;
->

Code: Select all

page_directory[i][c] = (unsigned int)address | 3;
And likewise:

Code: Select all

page_directory[i] = page_directory[i] | 3;
->

Code: Select all

page_directory[i] = (unsigned int)page_directory[i] | 3;
I would also, like pcmattman, question just how much experience you have with c++/c before starting to make an OS.

Also it looks like you are trying to enable long mode, before even getting it working in x86_32 mode. Bad plan.

As a quick sidenote the generally accepted mnemonic for the 'near return' instruction in x86 is 'ret', not 'retn'. 'ret' implies near return.

JamesM

Posted: Wed Sep 05, 2007 1:58 am
by JamesM
And, I would LOVE to know why you have declared your page directory as:

Code: Select all

unsigned long *page_directory[4][1024]
Why?! Why not just declare it as

Code: Select all

unsigned long **page_directory = blah
Then, when you want to extend yourself to more than 4 pagedirectory entries it wont be such of a chore.

And, you'll want to do

Code: Select all

write_cr3((unsigned int *)page_directory);
And, btw, sizeof(unsigned long) === sizeof(unsigned int). And int has one less character in it. So most people just write int. :P

JamesM

Posted: Wed Sep 05, 2007 2:11 am
by HJED
Also it looks like you are trying to enable long mode, before even getting it working in x86_32 mode. Bad plan.
i intend to write a 64 bit os so i whant to write it as a 64 bit os from scrach also that bit of the code works
Code:
page_directory[c] = address | 3;


->

Code:
page_directory[c] = (unsigned int)address | 3;

thks for this tip it realy helped

Code:
page_directory = page_directory | 3;


->

Code:
page_directory = (unsigned int)page_directory | 3;

my compiler dosent like that!
:cry:
As a quick sidenote the generally accepted mnemonic for the 'near return' instruction in x86 is 'ret', not 'retn'. 'ret' implies near return.

i was not aware of this thank u :D
And, I would LOVE to know why you have declared your page directory as:

Code:
unsigned long *page_directory[4][1024]


Why?! Why not just declare it as

Code:
unsigned long **page_directory = blah


Then, when you want to extend yourself to more than 4 pagedirectory entries it wont be such of a chore.

And, you'll want to do
Code:
write_cr3((unsigned int *)page_directory);


becouse i did not know u could do that!
And, btw, sizeof(unsigned long) === sizeof(unsigned int). And int has one less character in it. So most people just write int. Razz

it was long in the tutorial i thought it might be somthing to do whith the addres lenth and i know the difrence between long and int

also i started learning c++ to write this os but i was orignaly using java (thats why i ussed c++ instead of c)
so all the basic prisaples are the same
but u cant wright and os in java :cry:
PS
i still get the orignal errors on lines
12 & 4
thks

Posted: Wed Sep 05, 2007 2:22 am
by JamesM
i intend to write a 64 bit os so i whant to write it as a 64 bit os from scrach also that bit of the code works
I heavily suggest you get SOMETHING working in 32bit mode before moving on to long mode.
my compiler dosent like that!
Sorry, try

Code: Select all

page_directory[i] = (unsigned int *)((unsigned int)page_directory[i] | 3  );
Line 4, your crazy pagedir format is why you're getting that error.
Do

Code: Select all

unsigned long **page_directory = (unsigned long **) 0x9C000;
instead.

JamesM

Posted: Wed Sep 05, 2007 2:34 am
by pcmattman
HJED wrote:
Also it looks like you are trying to enable long mode, before even getting it working in x86_32 mode. Bad plan.
i intend to write a 64 bit os so i whant to write it as a 64 bit os from scrach also that bit of the code works
I could've sworn 32-bit paging is different (in small ways) from 64-bit paging...

Also, I'm pretty sure NASM should give you problems if you're trying to compile 64 bit code because iirc registers are not "e*" but "r*".

Have you written a 32-bit OS? I'd suggest you start there, and then once you understand the basics of 32-bit you can then apply those to 64-bit.

Posted: Wed Sep 05, 2007 3:38 am
by HJED
thks 4 your help
my c++ code is now
pagging.cpp

Code: Select all

#include <system.h>
//this is 4mb of paging ten enables long mode
void pagtable_AND_LM_Setup() {
    unsigned long ** page_directory = (unsigned long **) 0x9C000; 
    unsigned long * address = 0; // holds the physical address of where a page is
    unsigned int i;
    
// map the memory
    for(i=0; i<1024; i++) {
        unsigned int c;
        for(c=0; c<1024; c++) {
            page_directory[i][c] = (unsigned long)address | 3; // attribute set to: supervisor level, read/write, present(011 in binary)
            address = address + 4096; // 4096 = 4kb
        };
        // fill  entrys of the page directory
       page_directory[i] = (unsigned long *)((unsigned long)page_directory[i] | 3  );// attribute set to: supervisor level, read/write, present(011 in binary)
    };
    
    
    
    // write_cr3, read_cr3, write_cr0, and read_cr0 all come from the assembly function
    long_mode1(); // start long mode int
    write_cr3(page_directory); // put that page directory address into CR3
    long_mode2(); // pagging int 2
    write_cr0( (unsigned long *)((unsigned long) read_cr0() | (unsigned long) 0x80000000)); // set the paging bit in CR0 to 1
}
once again thank you 4 your help :D
pcmattman wrote:
HJED wrote:
Also it looks like you are trying to enable long mode, before even getting it working in x86_32 mode. Bad plan.
i intend to write a 64 bit os so i whant to write it as a 64 bit os from scrach also that bit of the code works
I could've sworn 32-bit paging is different (in small ways) from 64-bit paging...

Also, I'm pretty sure NASM should give you problems if you're trying to compile 64 bit code because iirc registers are not "e*" but "r*".

Have you written a 32-bit OS? I'd suggest you start there, and then once you understand the basics of 32-bit you can then apply those to 64-bit.
i don`t think so becouse you have to creat a pagetable to enable long mode acording to the intel manule
also so far all my asm code excuted in 32 bit mode
(i think) and yes nasm dose not suport 64bit code yet

Posted: Wed Sep 05, 2007 9:04 am
by JamesM
Also, I'm pretty sure NASM should give you problems if you're trying to compile 64 bit code because iirc registers are not "e*" but "r*".
You can use e* registers in long mode. They correspond to the low-order 32 bits of the 64-bit register, thus:

Code: Select all

64       32   16 8  0
|--------|----|--|--|
rax----------------->
         eax-------->
              ax---->
              ah>
                 al->
Heh, ascii art ftw
JamesM