help with initialising 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.
Post Reply
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

help with initialising paging

Post by yemista »

I can get paging to work using JamesM's tutorial, but Ive been trying to map my kernel to the higher half using the bootloader. My goal is to have the first 4MB identity mapped, and also to have 0xC0000000-0xC03FFFFF mapped to 0x00000000-0x003FFFFF. I have been racking my brain on this for hours, but for some reason it always fails once paging is enabled.

Code: Select all

	mov ecx, 0x000
	mov eax, 0x00000003

loop:	mov dword [pte1 + ecx*4], eax
	add eax, 0x1000
	inc ecx
	cmp ecx, 1024
	jl loop
	
	mov dword [pde], pte1
	mov dword [pde + 768], pte1
	mov eax, pde
	mov cr3, eax
	mov eax, cr0
	or eax, 0x80000001
	mov cr0, eax
Does anyone see anything wrong with the code? Ive been tracing the tables through bochs, and everything seems like it should be. Ive made sure my page tables are 4kb aligned as well, and I verified that through the symbol table
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: help with initialising paging

Post by neon »

Are you really sure you want to map starting from the page at 3gb to the page at physical address 0 (where the rmode IVT is at)? Most systems map 3gb virtual->1mb physical do to several reasons, this being one of them.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: help with initialising paging

Post by yemista »

Well I see your point, but I dont plan to ever use real mode interrupts. My kernel itself is after the 1mb mark. The only reason it is working out that way is as of the moment Im still trying to get paging to work properly, so Im identity mapping 0-4mb, and just using the same page table for the 3gb mark to see if the addresses translate correctly. However, I put in some nop instructions right after loading cr0 to see if the program will continue, but it fails right away. There is something wrong with the way the tables are being setup, and from all my pen and paper calculations, i seem to be doing it correctly. it will probably be a good idea to map 3gb -> 1mb, but right now I am not at the point of figuring that out

The really weird thing is, when I run the kernel that has paging working, and examine the page tables, aside from being located at different addresses, the content is virtually the same, but for some reason it wont work in this situation

[edit]
oh and in case it may help, the error I get after enabling paging is

Next at t=167138962
(0).[167138962] ??? (physical address not available)

[/edit]
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Re: help with initialising paging

Post by hailstorm »

I guess that you probably get a fault when you make jump to an address >= 0xc0000000.
You should change the following piece of code:

Code: Select all

mov dword [pde + 768], pte1
into this:

Code: Select all

mov dword [pde + 768*4], pte1; or: mov dword [pde + 3072], pte1
Hope this helps...
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: help with initialising paging

Post by Love4Boobies »

The IVT isn't the real concern, nor is the BDA. However, the EBDA gets used even if you aren't aware of it - since the BIOS works in SMM mode.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: help with initialising paging

Post by yemista »

hailstorm wrote:I guess that you probably get a fault when you make jump to an address >= 0xc0000000.
You should change the following piece of code:

Code: Select all

mov dword [pde + 768], pte1
into this:

Code: Select all

mov dword [pde + 768*4], pte1; or: mov dword [pde + 3072], pte1
Hope this helps...

The program would fail before it made the jump to address > 0xc0000000, but just to make sure i tried this change, and it does still fail. I have no idea what could be wrong.
User avatar
kop99
Member
Member
Posts: 120
Joined: Fri May 15, 2009 2:58 am

Re: help with initialising paging

Post by kop99 »

If you have any bochs log, it will help us to debugging your code...
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: help with initialising paging

Post by yemista »

ok, so where i stand is ive had this problem for a while, but ive ignored it since its not essential to map to the higher half, but now i feel i have to solve it to show myself i really understand paging and to rewrite my memory manager to aid in future development. so, here is alot of information, except the assembly code ive posted earlier:

symbol table:

Code: Select all

0010004d T _cr1
0010006d t loop
00100082 t real
001000a9 t blank
00101000 d pde
00102000 d pte1
00103000 d pte2
c0104000 T kbd_init
c0104046 T kbd_read
c010408e T kbd_isr
pde after initialisation:

Code: Select all

<bochs:4> x /10 0x00101000
[bochs]:
0x00101000 <bogus+       0>:	0x00102000  0x00000000 0x00000000 0x00000000
0x00101010 <bogus+      16>:	0x00000000	  0x00000000 0x00000000 0x00000000
0x00101020 <bogus+      32>:	0x00000000  0x00000000
pte1 after initialisation:

Code: Select all

<bochs:5> x /10 0x00102000
[bochs]:
0x00102000 <bogus+       0>:	0x00000003	 0x00001003 0x00002003 0x00003003
0x00102010 <bogus+      16>:	0x00004003 0x00005003 0x00006003 0x00007003
0x00102020 <bogus+      32>:	0x00008003	 0x00009003
and to show pte continues like this to map up to 4mb, here is the end part

Code: Select all

0x00102fa0 <bogus+    4000>:	0x003e8003 0x003e9003 0x003ea003 0x003eb003
0x00102fb0 <bogus+    4016>:	0x003ec003 0x003ed003 0x003ee003 0x003ef003
0x00102fc0 <bogus+    4032>:	0x003f0003	0x003f1003	0x003f2003	0x003f3003
0x00102fd0 <bogus+    4048>:	0x003f4003	0x003f5003	0x003f6003	0x003f7003
0x00102fe0 <bogus+    4064>:	0x003f8003	0x003f9003	0x003fa003	0x003fb003
0x00102ff0 <bogus+    4080>:	0x003fc003	0x003fd003	0x003fe003	0x003ff003
and here is the bochs log

Code: Select all

00000000000i[     ] Bochs x86 Emulator 2.4
00000000000i[     ]   Build from CVS snapshot on May 3, 2009
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1 (cores=1, HT threads=1)
00000000000i[     ]   A20 line support: yes
00000000000i[     ]   load configurable MSRs from file "msrs.def"
00000000000i[     ] CPU configuration
00000000000i[     ]   level: 5
00000000000i[     ]   SMP support: no
00000000000i[     ]   APIC support: no
00000000000i[     ]   FPU support: yes
00000000000i[     ]   MMX support: yes
00000000000i[     ]   SSE support: no
00000000000i[     ]   CLFLUSH support: no
00000000000i[     ]   VME support: yes
00000000000i[     ]   3dnow! support: no
00000000000i[     ]   PAE support: no
00000000000i[     ]   PGE support: no
00000000000i[     ]   PSE support: yes
00000000000i[     ]   x86-64 support: no
00000000000i[     ]   SEP support: no
00000000000i[     ]   MWAIT support: no
00000000000i[     ]   XSAVE support: no
00000000000i[     ]   AES support: no
00000000000i[     ]   VMX support: no
00000000000i[     ] Optimization configuration
00000000000i[     ]   RepeatSpeedups support: no
00000000000i[     ]   Trace cache support: no
00000000000i[     ]   Fast function calls: no
00000000000i[     ] Devices configuration
00000000000i[     ]   ACPI support: no
00000000000i[     ]   NE2000 support: no
00000000000i[     ]   PCI support: no
00000000000i[     ]   SB16 support: no
00000000000i[     ]   USB support: no
00000000000i[     ]   VGA extension support: vbe 
00000000000i[MEM0 ] allocated memory at 0xb2b31008. after alignment, vector=0xb2b32000
00000000000i[MEM0 ] 64.00MB
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/local/share/bochs/BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/40448 ('/usr/local/share/bochs/VGABIOS-lgpl-latest')
00000000000e[DEV  ] Bochs is not compiled with PCI support
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Tue Jun  2 22:56:06 2009 (time0=1243997766)
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[FDD  ] fd0: '/home/elias/eliax/eliax' ro=0, h=2,t=80,spt=18
00000000000i[VGA  ] interval=300000
00000000000i[MEM0 ] Register memory access handlers: 0x000a0000 - 0x000bffff
00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried
00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24
00000000000i[MEM0 ] Register memory access handlers: 0xe0000000 - 0xe0ffffff
00000000000i[VGA  ] VBE Bochs Display Extension Enabled
00000000000i[     ] init_dev of 'unmapped' plugin device by virtual method
00000000000i[     ] init_dev of 'biosdev' plugin device by virtual method
00000000000i[     ] init_dev of 'speaker' plugin device by virtual method
00000000000i[SPEAK] Failed to open /dev/console: Resource temporarily unavailable
00000000000i[SPEAK] Deactivating beep on console
00000000000i[     ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[     ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] Using boot sequence floppy, none, none
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[     ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[     ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x0378 irq 7
00000000000i[     ] register state of 'unmapped' plugin device by virtual method
00000000000i[     ] register state of 'biosdev' plugin device by virtual method
00000000000i[     ] register state of 'speaker' plugin device by virtual method
00000000000i[     ] register state of 'extfpuirq' plugin device by virtual method
00000000000i[     ] register state of 'keyboard' plugin device by virtual method
00000000000i[     ] register state of 'harddrv' plugin device by virtual method
00000000000i[     ] register state of 'serial' plugin device by virtual method
00000000000i[     ] register state of 'parallel' plugin device by virtual method
00000000000i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[     ] reset of 'unmapped' plugin device by virtual method
00000000000i[     ] reset of 'biosdev' plugin device by virtual method
00000000000i[     ] reset of 'speaker' plugin device by virtual method
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'keyboard' plugin device by virtual method
00000000000i[     ] reset of 'harddrv' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[XGUI ] [x] Mouse off
00000000000i[     ] set SIGINT handler to bx_debug_ctrlc_handler
00000003305i[BIOS ] $Revision: 1.231 $ $Date: 2009/04/26 17:17:07 $
00000337554i[KBD  ] reset-disable command received
00000487302i[VBIOS] VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $

00000487373i[VGA  ] VBE known Display Interface b0c0
00000487405i[VGA  ] VBE known Display Interface b0c5
00000490330i[VBIOS] VBE Bios $Id: vbe.c,v 1.62 2009/01/25 15:46:25 vruppert Exp $
00000796891i[BIOS ] Starting rombios32
00000797388i[BIOS ] Shutdown flag 0
00000798069i[BIOS ] ram_size=0x04000000
00000798547i[BIOS ] ram_end=64MB
00000799065i[BIOS ] Found 1 cpu(s)
00000818100i[BIOS ] bios_table_addr: 0x000fb9a8 end=0x000fcc00
00000833468i[BIOS ] MP table addr=0x000fba80 MPC table addr=0x000fb9b0 size=0xd0
00000835312i[BIOS ] SMBIOS table addr=0x000fba90
00000836195i[BIOS ] bios_table_cur_addr: 0x000fbb94
00015000000i[XGUI ] charmap update. Font Height is 16
00153228420i[BIOS ] Booting from 0000:7c00
00167138962i[CPU0 ] CPU is in protected mode (active)
00167138962i[CPU0 ] CS.d_b = 32 bit
00167138962i[CPU0 ] SS.d_b = 32 bit
00167138962i[CPU0 ] | EAX=e0000011  EBX=00000010  ECX=00000400  EDX=00000000
00167138962i[CPU0 ] | ESP=0000ffff  EBP=00000000  ESI=000e7c3e  EDI=0000ffac
00167138962i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af PF cf
00167138962i[CPU0 ] | SEG selector     base    limit G D
00167138962i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00167138962i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 ffffffff 1 1
00167138962i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00167138962i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00167138962i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00167138962i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00167138962i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00167138962i[CPU0 ] | EIP=001000a9 (001000a9)
00167138962i[CPU0 ] | CR0=0xe0000011 CR2=0x00000040
00167138962i[CPU0 ] | CR3=0x00101000 CR4=0x00000000
00167138962e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
00167138962i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00167138962i[CPU0 ] cpu hardware reset
00167138962i[     ] reset of 'unmapped' plugin device by virtual method
00167138962i[     ] reset of 'biosdev' plugin device by virtual method
00167138962i[     ] reset of 'speaker' plugin device by virtual method
00167138962i[     ] reset of 'extfpuirq' plugin device by virtual method
00167138962i[     ] reset of 'keyboard' plugin device by virtual method
00167138962i[     ] reset of 'harddrv' plugin device by virtual method
00167138962i[     ] reset of 'serial' plugin device by virtual method
00167138962i[     ] reset of 'parallel' plugin device by virtual method
00167138963i[     ] dbg: Quit
00167138963i[CPU0 ] CPU is in real mode (active)
00167138963i[CPU0 ] CS.d_b = 16 bit
00167138963i[CPU0 ] SS.d_b = 16 bit
00167138963i[CPU0 ] | EAX=00000000  EBX=00000000  ECX=00000000  EDX=00000543
00167138963i[CPU0 ] | ESP=00000000  EBP=00000000  ESI=00000000  EDI=00000000
00167138963i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00167138963i[CPU0 ] | SEG selector     base    limit G D
00167138963i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00167138963i[CPU0 ] |  CS:f000( 1e00| 0|  0) ffff0000 0000ffff 0 0
00167138963i[CPU0 ] |  DS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00167138963i[CPU0 ] |  SS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00167138963i[CPU0 ] |  ES:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00167138963i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00167138963i[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00167138963i[CPU0 ] | EIP=0000fff0 (0000fff0)
00167138963i[CPU0 ] | CR0=0x60000010 CR2=0x00000000
00167138963i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00167138963i[CMOS ] Last time is 1243997769 (Tue Jun  2 22:56:09 2009)
00167138963i[XGUI ] Exit
00167138963i[CTRL ] quit_sim called with exit code 0
before it fails, cr0 and cr3 seem to be set as they should be, and from calculating the pages by hand, the pde and pte seem to be setup correctly. Ive compared them with the pde and pte setup by JamesM's code, and the status bits and addresses seem to be setup the same way.

Here is the directory set up by the tutorial code:

Code: Select all

[bochs]:
0x00302000 <bogus+       0>:	0x00305000 0x00307000 0x00309000 0x00000000
0x00302010 <bogus+      16>:	0x00000000 0x00000000 0x00000000 0x00000000
0x00302020 <bogus+      32>:	0x00000000	 0x00000000
And here is the page table set up by the tutorial code:

Code: Select all

[bochs]:
0x00305000 <bogus+       0>:	0x00000005	 0x00001005 0x00002005 0x00003005
0x00305010 <bogus+      16>:	0x00004005	 0x00005005 0x00006005 0x00007005
0x00305020 <bogus+      32>:	0x00008005 0x00009005
The only difference in the table is the last digit is a 5 instead of a 3, indicating that frame has been accessed. Am I just going crazy here? I cant see why its not working
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Re: help with initialising paging

Post by hailstorm »

Your pagedirectory entries need their present bit to be set... I don't see that happening...
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: help with initialising paging

Post by yemista »

that was it! thank you so much!
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: help with initialising paging

Post by yemista »

Love4Boobies wrote:The IVT isn't the real concern, nor is the BDA. However, the EBDA gets used even if you aren't aware of it - since the BIOS works in SMM mode.
So where do you think a good place o put the stack is? Right now mine starts at 0x000ffff0, but could this mess things up if it spills into something?
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Re: help with initialising paging

Post by Ready4Dis »

Put it anywhere you want, but I would mark the page previous your stack as not available so it will throw a page fault, and have a stand-by kernel stack available to catch it, this way, if the stack overflows, you can either a.) shut down the offending program, or allocate more memory, copy the stack, and move the stack pointer.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: help with initialising paging

Post by jal »

Ready4Dis wrote:copy the stack, and move the stack pointer.
That doesn't work, as the program may use local variables referenced by a BP that's pointing to the original stack (OK, if you leaver the original stack as-is, which is a waste of memory, it may work, but just don't).


JAL
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: help with initialising paging

Post by egos »

yemista wrote:So where do you think a good place o put the stack is? Right now mine starts at 0x000ffff0, but could this mess things up if it spills into something?
My initial stack is placed directly below the loaded kernel file at 0x8000. When paging starts, it uses the identity mapping for first 640 kb. Then initialization code allocates memory, maps it to stable position of the kernel at higher part of virt. addr. space and physically copies the symbols (general) section image to its new position. The 1st thread of the primary task then is created (with own kernel stack) and when it takes control the base memory is unmapped manually and so initial stack is detached.
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
kop99
Member
Member
Posts: 120
Joined: Fri May 15, 2009 2:58 am

Re: help with initialising paging

Post by kop99 »

I think it's maybe depends on your kernel size...
Post Reply