yet another noob pagging problem

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.
Post Reply
HJED
Member
Member
Posts: 61
Joined: Tue Sep 04, 2007 4:18 am
Location: the world wide web
Contact:

yet another noob pagging problem

Post 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
Last edited by HJED on Tue Sep 04, 2007 10:45 pm, edited 1 time in total.
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

You cannot do binary operations on pointers (|, &). You should cast them to unsigned long or something before trying.
HJED
Member
Member
Posts: 61
Joined: Tue Sep 04, 2007 4:18 am
Location: the world wide web
Contact:

yet another noob paging proble

Post 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
HJED
Member
Member
Posts: 61
Joined: Tue Sep 04, 2007 4:18 am
Location: the world wide web
Contact:

Post 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:
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

How much C programming experience do you have?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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
HJED
Member
Member
Posts: 61
Joined: Tue Sep 04, 2007 4:18 am
Location: the world wide web
Contact:

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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.
HJED
Member
Member
Posts: 61
Joined: Tue Sep 04, 2007 4:18 am
Location: the world wide web
Contact:

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

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