Triple fault on setting CR0 in with 64-bit

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.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Triple fault on setting CR0 in with 64-bit

Post by zhiayang »

Problems. It seems every time I try anything even mildly paging-related, I get problems. All kinds of dumb problems.

Firstly: I'm following this tutorial on getting to long mode.

However, (As the title says), I get a triple fault (or at least I think, because none of my fault handlers get called) when I enable paging by setting CR0.

I understand that this question might have been asked several times, but none have resolved my problem, or given details about resolving the problem.

Here is the code I use to set up the paging structures:

Code: Select all

uint64_t PageDirectoryPointerTable[4] __attribute__ ((aligned(0x1000)));
uint64_t PageDirectory[512] __attribute__ ((aligned(0x1000)));

uint64_t PageTable[512] __attribute__ ((aligned(0x1000)));
uint64_t PageTable1[512] __attribute__ ((aligned(0x1000)));

PageDirectoryPointerTable[0] = (uint64_t)&PageDirectory | 3;	// Present
PageDirectory[0] = (uint64_t)&PageTable | 3;					// Present, R/W

unsigned int i = 0;
unsigned int Address = 0;

for(i = 0; i < 512; i++)
{
	PageTable[i] = Address | 3;	// Present, R/W
	Address += 0x1000;
}
asm volatile ("movl %cr4, %eax; bts $5, %eax; movl %eax, %cr4");			// set bit5 in CR4 to enable PAE
asm volatile ("movl %%eax, %%cr3" :: "a" (&PageDirectoryPointerTable));		// load PDPT into CR3

Do64();
I map 2MB of memory, from 0x0 to 0x00200000.
It's all fine until there, but I use the following to enable long mode and paging:

Code: Select all

Do64:
	mov ecx, 0xC0000080		; Target the EFER MSR (Model-Specific Register)
	rdmsr					; Read the MSR into EAX
	or eax, 1 << 8				; Set the Long Mode Bit (Bit 8)
	wrmsr					; Update the MSR

	; Enable Paging
	mov eax, cr0				; Get CR0
	or eax, 1 << 31			; Set bit 31, the paging bit.
	mov cr0, eax				; Update CR0
	ret
(I use 'ret' as this ASM is called from C)

Help? Below is my bochs.log.















Code: Select all

00000000000i[     ] Bochs x86 Emulator 2.6
00000000000i[     ]   Built from SVN snapshot on September 2nd, 2012
00000000000i[     ] Compiled on Nov 21 2012 at 16:48:12
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1 (cores=1, HT threads=1)
00000000000i[     ]   A20 line support: yes
00000000000i[     ] IPS is set to 4000000
00000000000i[     ] CPU configuration
00000000000i[     ]   level: 6
00000000000i[     ]   SMP support: no
00000000000i[     ]   Using pre-defined CPU configuration: corei5_arrandale_m520
00000000000i[     ] Optimization configuration
00000000000i[     ]   RepeatSpeedups support: yes
00000000000i[     ]   Fast function calls: yes
00000000000i[     ]   Handlers Chaining speedups: no
00000000000i[     ] Devices configuration
00000000000i[     ]   NE2000 support: yes
00000000000i[     ]   PCI support: yes, enabled=yes
00000000000i[     ]   SB16 support: yes
00000000000i[     ]   USB support: yes
00000000000i[     ]   VGA extension support: vbe cirrus
00000000000i[MEM0 ] allocated memory at 0x10a37e000. after alignment, vector=0x10a37e000
00000000000i[MEM0 ] 32.00MB
00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/local/Cellar/bochs/2.6/share/bochs/BIOS-bochs-latest')
00000000000i[     ] lt_dlhandle is 0x7ff59c0aa080
00000000000i[PLGIN] loaded plugin libbx_hdimage.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0aa5e0
00000000000i[PLGIN] loaded plugin libbx_pci.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0aae40
00000000000i[PLGIN] loaded plugin libbx_pci2isa.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0ab560
00000000000i[PLGIN] loaded plugin libbx_acpi.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0abc40
00000000000i[PLGIN] loaded plugin libbx_cmos.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0ac250
00000000000i[PLGIN] loaded plugin libbx_dma.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0ac9c0
00000000000i[PLGIN] loaded plugin libbx_pic.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0ad090
00000000000i[PLGIN] loaded plugin libbx_pit.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0ad760
00000000000i[PLGIN] loaded plugin libbx_floppy.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0ae010
00000000000i[PLGIN] loaded plugin libbx_vga.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0ae540
00000000000i[PLGIN] loaded plugin libbx_ioapic.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0aeb80
00000000000i[PLGIN] loaded plugin libbx_keyboard.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0af220
00000000000i[PLGIN] loaded plugin libbx_harddrv.so
00000000000i[     ] lt_dlhandle is 0x7ff59c0af750
00000000000i[PLGIN] loaded plugin libbx_pci_ide.so
00000000000i[PLGIN] init_dev of 'pci' plugin device by virtual method
00000000000i[PCI  ] 440FX Host bridge present at device 0, function 0
00000000000i[PLGIN] init_dev of 'pci2isa' plugin device by virtual method
00000000000i[PCI  ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
00000000000i[PLGIN] init_dev of 'cmos' plugin device by virtual method
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Wed Nov 21 17:38:23 2012 (time0=1353490703)
00000000000i[PLGIN] init_dev of 'dma' plugin device by virtual method
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[PLGIN] init_dev of 'pic' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'pit' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'floppy' plugin device by virtual method
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[PLGIN] init_dev of 'vga' plugin device by virtual method
00000000000i[MEM0 ] Register memory access handlers: 0x00000000000a0000 - 0x00000000000bffff
00000000000i[VGA  ] interval=200000
00000000000i[MEM0 ] Register memory access handlers: 0x00000000e0000000 - 0x00000000e0ffffff
00000000000i[BXVGA] VBE Bochs Display Extension Enabled
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 ] rom at 0xc0000/41472 ('/usr/local/Cellar/bochs/2.6/share/bochs/VGABIOS-lgpl-latest')
00000000000i[PLGIN] init_dev of 'acpi' plugin device by virtual method
00000000000i[PCI  ] ACPI Controller present at device 1, function 3
00000000000i[PLGIN] init_dev of 'ioapic' plugin device by virtual method
00000000000i[IOAP ] initializing I/O APIC
00000000000i[MEM0 ] Register memory access handlers: 0x00000000fec00000 - 0x00000000fec00fff
00000000000i[PLGIN] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[PLGIN] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] CD on ata0-0: 'disk.iso'
00000000000i[CD1  ] load cdrom with path=disk.iso
00000000000i[CD1  ] Opening image file as a cd.
00000000000i[HD   ] Media present in CD-ROM drive
00000000000i[HD   ] Capacity is 267 sectors (0.52 MB)
00000000000i[HD   ] Using boot sequence floppy, cdrom, none
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[PLGIN] init_dev of 'pci_ide' plugin device by virtual method
00000000000i[PCI  ] PIIX3 PCI IDE controller present at device 1, function 1
00000000000i[PLGIN] init_dev of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'speaker' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x0378 irq 7
00000000000i[PLGIN] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[PLGIN] init_dev of 'gameport' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'iodebug' plugin device by virtual method
00000000000i[PLGIN] register state of 'pci' plugin device by virtual method
00000000000i[PLGIN] register state of 'pci2isa' plugin device by virtual method
00000000000i[PLGIN] register state of 'cmos' plugin device by virtual method
00000000000i[PLGIN] register state of 'dma' plugin device by virtual method
00000000000i[PLGIN] register state of 'pic' plugin device by virtual method
00000000000i[PLGIN] register state of 'pit' plugin device by virtual method
00000000000i[PLGIN] register state of 'floppy' plugin device by virtual method
00000000000i[PLGIN] register state of 'vga' plugin device by virtual method
00000000000i[PLGIN] register state of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] register state of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] register state of 'speaker' plugin device by virtual method
00000000000i[PLGIN] register state of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] register state of 'parallel' plugin device by virtual method
00000000000i[PLGIN] register state of 'serial' plugin device by virtual method
00000000000i[PLGIN] register state of 'gameport' plugin device by virtual method
00000000000i[PLGIN] register state of 'iodebug' plugin device by virtual method
00000000000i[PLGIN] register state of 'acpi' plugin device by virtual method
00000000000i[PLGIN] register state of 'ioapic' plugin device by virtual method
00000000000i[PLGIN] register state of 'keyboard' plugin device by virtual method
00000000000i[PLGIN] register state of 'harddrv' plugin device by virtual method
00000000000i[PLGIN] register state of 'pci_ide' plugin device by virtual method
00000000000i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x00000000fee00000
00000000000i[CPU0 ] CPUID[0x00000000]: 0000000b 756e6547 6c65746e 49656e69
00000000000i[CPU0 ] CPUID[0x00000001]: 00020652 00010800 0298e3df bfebfbff
00000000000i[CPU0 ] CPUID[0x00000002]: 55035a01 00f0b2dd 00000000 09ca212c
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000004]: 1c004121 01c0003f 0000003f 00000000
00000000000i[CPU0 ] CPUID[0x00000005]: 00000040 00000040 00000003 00001120
00000000000i[CPU0 ] CPUID[0x00000006]: 00000007 00000002 00000001 00000000
00000000000i[CPU0 ] CPUID[0x00000007]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000008]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000009]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] WARNING: Architectural Performance Monitoring is not implemented
00000000000i[CPU0 ] CPUID[0x0000000a]: 07300403 00000004 00000000 00000603
00000000000i[CPU0 ] CPUID[0x0000000b]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000001 28100000
00000000000i[CPU0 ] CPUID[0x80000002]: 65746e49 2952286c 726f4320 4d542865
00000000000i[CPU0 ] CPUID[0x80000003]: 35692029 55504320 20202020 4d202020
00000000000i[CPU0 ] CPUID[0x80000004]: 30323520 20402020 30342e32 007a4847
00000000000i[CPU0 ] CPUID[0x80000005]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 00000000 01006040 00000000
00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000100
00000000000i[CPU0 ] CPUID[0x80000008]: 00003028 00000000 00000000 00000000
00000000000i[PLGIN] reset of 'pci' plugin device by virtual method
00000000000i[PLGIN] reset of 'pci2isa' plugin device by virtual method
00000000000i[PLGIN] reset of 'cmos' plugin device by virtual method
00000000000i[PLGIN] reset of 'dma' plugin device by virtual method
00000000000i[PLGIN] reset of 'pic' plugin device by virtual method
00000000000i[PLGIN] reset of 'pit' plugin device by virtual method
00000000000i[PLGIN] reset of 'floppy' plugin device by virtual method
00000000000i[PLGIN] reset of 'vga' plugin device by virtual method
00000000000i[PLGIN] reset of 'acpi' plugin device by virtual method
00000000000i[PLGIN] reset of 'ioapic' plugin device by virtual method
00000000000i[PLGIN] reset of 'keyboard' plugin device by virtual method
00000000000i[PLGIN] reset of 'harddrv' plugin device by virtual method
00000000000i[PLGIN] reset of 'pci_ide' plugin device by virtual method
00000000000i[PLGIN] reset of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] reset of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] reset of 'speaker' plugin device by virtual method
00000000000i[PLGIN] reset of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] reset of 'parallel' plugin device by virtual method
00000000000i[PLGIN] reset of 'serial' plugin device by virtual method
00000000000i[PLGIN] reset of 'gameport' plugin device by virtual method
00000000000i[PLGIN] reset of 'iodebug' plugin device by virtual method
00000000000i[XGUI ] Mouse capture off
00000000000i[     ] Using debugger log file bochsdebug.log
00000000000i[     ] set SIGINT handler to bx_debug_ctrlc_handler
00000000000i[XGUI ] Mouse capture off
00000000025i[MEM0 ] allocate_block: block=0x0 used 0x1 of 0x20
00000004661i[BIOS ] $Revision: 11318 $ $Date: 2012-08-06 19:59:54 +0200 (Mo, 06. Aug 2012) $
00000321072i[KBD  ] reset-disable command received
00000323806i[BIOS ] Starting rombios32
00000324240i[BIOS ] Shutdown flag 0
00000324835i[BIOS ] ram_size=0x02000000
00000325256i[BIOS ] ram_end=32MB
00000365767i[BIOS ] Found 1 cpu(s)
00000379949i[BIOS ] bios_table_addr: 0x000fa438 end=0x000fcc00
00000707742i[PCI  ] 440FX PMC write to PAM register 59 (TLB Flush)
00001035670i[P2I  ] PCI IRQ routing: PIRQA# set to 0x0b
00001035689i[P2I  ] PCI IRQ routing: PIRQB# set to 0x09
00001035708i[P2I  ] PCI IRQ routing: PIRQC# set to 0x0b
00001035727i[P2I  ] PCI IRQ routing: PIRQD# set to 0x09
00001035737i[P2I  ] write: ELCR2 = 0x0a
00001036503i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a
00001044168i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600
00001046438i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601
00001048547i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101
00001048778i[PIDE ] new BM-DMA address: 0xc000
00001049395i[BIOS ] region 4: 0x0000c000
00001051420i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680
00001051653i[ACPI ] new irq line = 11
00001051665i[ACPI ] new irq line = 9
00001051694i[ACPI ] new PM base address: 0xb000
00001051708i[ACPI ] new SM base address: 0xb100
00001051736i[PCI  ] setting SMRAM control register to 0x4a
00001215827i[CPU0 ] Enter to System Management Mode
00001215837i[CPU0 ] RSM: Resuming from System Management Mode
00001379855i[PCI  ] setting SMRAM control register to 0x0a
00001394748i[BIOS ] MP table addr=0x000fa510 MPC table addr=0x000fa440 size=0xc8
00001396504i[BIOS ] SMBIOS table addr=0x000fa520
00001396562i[MEM0 ] allocate_block: block=0x1f used 0x2 of 0x20
00001398699i[BIOS ] ACPI tables: RSDP addr=0x000fa640 ACPI DATA addr=0x01ff0000 size=0x992
00001401896i[BIOS ] Firmware waking vector 0x1ff00cc
00001403317i[PCI  ] 440FX PMC write to PAM register 59 (TLB Flush)
00001404045i[BIOS ] bios_table_cur_addr: 0x000fa664
00001531662i[VBIOS] VGABios $Id: vgabios.c,v 1.75 2011/10/15 14:07:21 vruppert Exp $
00001531733i[BXVGA] VBE known Display Interface b0c0
00001531765i[BXVGA] VBE known Display Interface b0c5
00001534690i[VBIOS] VBE Bios $Id: vbe.c,v 1.64 2011/07/19 18:25:05 vruppert Exp $
00001600003i[XGUI ] charmap update. Font Height is 16
00005741743i[BIOS ] IDE time out
00017896668i[BIOS ] Booting from 07c0:0000
00018037493i[BIOS ] int13_harddisk: function 41, unmapped device for ELDL=80
00018041173i[BIOS ] int13_harddisk: function 08, unmapped device for ELDL=80
00018044836i[BIOS ] *** int 15h function AX=00c0, BX=0000 not yet supported!
00019833877i[MEM0 ] allocate_block: block=0x1 used 0x3 of 0x20
00020266511i[SER  ] com1: FIFO enabled
00021004624i[MEM0 ] allocate_block: block=0x2 used 0x4 of 0x20
00022372885i[CPU0 ] CPU is in compatibility mode (active)
00022372885i[CPU0 ] CS.mode = 32 bit
00022372885i[CPU0 ] SS.mode = 32 bit
00022372885i[CPU0 ] EFER   = 0x00000500
00022372885i[CPU0 ] | RAX=00000000e0000011  RBX=0000000000000000
00022372885i[CPU0 ] | RCX=00000000c0000080  RDX=0000000000000000
00022372885i[CPU0 ] | RSP=0000000000102fec  RBP=0000000000107ff0
00022372885i[CPU0 ] | RSI=0000000000000000  RDI=0000000000035a65
00022372885i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00022372885i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00022372885i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00022372885i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00022372885i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af PF cf
00022372885i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00022372885i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 ffffffff 1 1
00022372885i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00022372885i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00022372885i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00022372885i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00022372885i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00022372885i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00022372885i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00022372885i[CPU0 ] | RIP=00000000001002b8 (00000000001002b8)
00022372885i[CPU0 ] | CR0=0xe0000011 CR2=0x00000000001090e0
00022372885i[CPU0 ] | CR3=0x00106000 CR4=0x00000020
00022372885p[CPU0 ] >>PANIC<< exception(): 3rd (14) exception with no resolution
00022372885e[CPU0 ] WARNING: Any simulation after this point is completely bogus !
00022372885p[CPU0 ] >>PANIC<< Entering to shutdown state still not implemented
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Triple fault on setting CR0 in with 64-bit

Post by bluemoon »

Code: Select all

uint64_t PageDirectoryPointerTable[4] __attribute__ ((aligned(0x1000)));
[Error:] Long mode do not use PDPT[4], it use PML4 instead.
[Break] The rest of code is not read due to error found.

PS. I recommend reading X86-64 and Entering_Long_Mode_Directly too.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Triple fault on setting CR0 in with 64-bit

Post by Combuster »

The difference between long mode paging and legacy PAE is that long mode has 4 levels of tables, and not the 2-and-a-half you're using right now.
Last edited by Combuster on Wed Nov 21, 2012 4:01 am, edited 1 time in total.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Triple fault on setting CR0 in with 64-bit

Post by gerryg400 »

You're missing one level of paging table.
If a trainstation is where trains stop, what is a workstation ?
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Triple fault on setting CR0 in with 64-bit

Post by zhiayang »

Thanks for all the quick replies. It would appear that it was a large oversight on my part. However, the problem persists;

Code: Select all

uint64_t PML4T[512] __attribute__ ((aligned(0x1000)));
uint64_t PageDirectoryPointerTable[512] __attribute__ ((aligned(0x1000)));
uint64_t PageDirectory[512] __attribute__ ((aligned(0x1000)));

uint64_t PageTable[512] __attribute__ ((aligned(0x1000)));

PML4T[0] = (uint64_t)&PageDirectoryPointerTable | 3;			// Present, R/W
PageDirectoryPointerTable[0] = (uint64_t)&PageDirectory | 3;	// Present, R/W
PageDirectory[0] = (uint64_t)&PageTable | 3;					// Present, R/W

asm volatile ("movl %%eax, %%cr3" :: "a" (&PML4T));
This is my updated code, including the PML4T and putting the address of that into CR3 instead of the PDPT.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Triple fault on setting CR0 in with 64-bit

Post by bluemoon »

Code: Select all

PML4T[0] = (uint64_t)&PageDirectoryPointerTable | 3;         // Present, R/W
PageDirectoryPointerTable[0] = (uint64_t)&PageDirectory | 3;   // Present, R/W
PageDirectory[0] = (uint64_t)&PageTable | 3;               // Present, R/W
Hint #1: &PageDirectoryPointerTable
Hint #2: This whole thing will not work if logical(as view by linker) address(PageDirectoryPointerTable) != physical address
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Triple fault on setting CR0 in with 64-bit

Post by zhiayang »

bluemoon wrote:

Code: Select all

PML4T[0] = (uint64_t)&PageDirectoryPointerTable | 3;         // Present, R/W
PageDirectoryPointerTable[0] = (uint64_t)&PageDirectory | 3;   // Present, R/W
PageDirectory[0] = (uint64_t)&PageTable | 3;               // Present, R/W
Hint #1: &PageDirectoryPointerTable
Hint #2: This whole thing will not work if logical(as view by linker) address(PageDirectoryPointerTable) != physical address

1. What am I supposed to use then?
2. ...? How then, would I ensure that the physical address matches the logical address?

Also: for some reason, using uint64_t types corrupt random things in my kernel; specifically the ISR routines. Is it something I should take note of (I'm sure it is, but what's the problem?)? I've changed it to unsigned long for now, and the problem doesn't occur.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Triple fault on setting CR0 in with 64-bit

Post by gerryg400 »

I guess you know that a 64bit IDT is different from a 32bit IDT....
If a trainstation is where trains stop, what is a workstation ?
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Triple fault on setting CR0 in with 64-bit

Post by zhiayang »

gerryg400 wrote:I guess you know that a 64bit IDT is different from a 32bit IDT....
I know, but I don't even far jump to 64-bit mode yet. I do set the LME bit in one of those registers (can't remember offhand), and I haven't set a 64-bit GDT yet, which means I should be executing in compatibility mode, right?

Also: by 'corrupt random things' I mean causing random interrupts, like invalid opcode, breakpoint, etc. it happens just by *including* the paging code in the program; it isn't actually excuted when the fault occurs.

All this is so very weird and unpredictable...
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Triple fault on setting CR0 in with 64-bit

Post by bluemoon »

requimrar wrote:I know, but I don't even far jump to 64-bit mode yet. I do set the LME bit in one of those registers (can't remember offhand), and I haven't set a 64-bit GDT yet, which means I should be executing in compatibility mode, right?
No. if LME is enabled, even in compatibility mode require 64-bit GDT (which may contain 32-bit compatibility segment), 64-bit IDT and 64-bit TSS.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Triple fault on setting CR0 in with 64-bit

Post by zhiayang »

bluemoon wrote:
requimrar wrote:I know, but I don't even far jump to 64-bit mode yet. I do set the LME bit in one of those registers (can't remember offhand), and I haven't set a 64-bit GDT yet, which means I should be executing in compatibility mode, right?
No. if LME is enabled, even in compatibility mode require 64-bit GDT (which may contain 32-bit compatibility segment), 64-bit IDT and 64-bit TSS.

Bah. But for now I just need a GDT, right? Interrupts are off and I don't do multitasking yet.
Also: assuming I solve this paging problem, (help?), I am faced with a theoretical problem ( which may not exist at all, I don't know)

I assume that I should load the GDT before I enable LME; however,
1. Do I far jump to activate the GDT before or after activating paging? (I think after)

But first, all those faults. I get the feeling that something at the core is broken, but I have no idea what...
User avatar
SparrowOS
Member
Member
Posts: 72
Joined: Wed Nov 14, 2012 5:22 pm
Location: Vegas
Contact:

Re: Triple fault on setting CR0 in with 64-bit

Post by SparrowOS »

Did you set-up paging? You need 64-bit page tables. Long mode requires paging.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Triple fault on setting CR0 in with 64-bit

Post by zhiayang »

This thread was created because I couldn't get paging to work.
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Triple fault on setting CR0 in with 64-bit

Post by iansjack »

requimrar wrote:Bah. But for now I just need a GDT, right? Interrupts are off and I don't do multitasking yet.
if you don't have an IDT, what will happen when you get a Page Fault or a GPF? It'll end up as a triple fault. So perhaps it's something very simple that is masked by the fact that any fault will lead to a triple fault.

I would recommend that you set up a minimal IDT and then run the code under a debugger (something like Bochs or AMD's SimNow). Step through the code until it faults; then examine the registers, memory, and your page table. The problem should be fairly easy to track down.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Triple fault on setting CR0 in with 64-bit

Post by bluemoon »

requimrar wrote:Bah. But for now I just need a GDT, right? Interrupts are off and I don't do multitasking yet.
As I said above you also need a dummy TSS, which consist of mostly zero - this is accordingly to intel manual.
For reality, you may skip that TSS part and it might as well work on most machine, but I personally would stick to the manual as it's just easy step.
the software initialization code must load a minimum number of protected mode data structures and code
Vol. 3A 9-11
PROCESSOR MANAGEMENT AND INITIALIZATION
modules into memory to support reliable operation of the processor in protected mode. These data structures include the following:
• AIDT.
• AGDT.
• ATSS.
• (Optional) An LDT.
• If paging is to be used, at least one page directory and one page table.
• A code segment that contains the code to be executed when the processor switches to protected mode.
• One or more code modules that contain the necessary interrupt and exception handlers.
Software initialization code must also initialize the following system registers before the processor can be switched to protected mode:
• The GDTR.
• (Optional.) The IDTR. This register can also be initialized immediately after
switching to protected mode, prior to enabling interrupts.
• Control registers CR1 through CR4.
• (Pentium 4, Intel Xeon, and P6 family processors only.) The memory type range registers (MTRRs)
requimrar wrote:1. Do I far jump to activate the GDT before or after activating paging? (I think after)
If you do Real->Protected->IA32e
1. You need to setup 32-bit GDTR before switch to protected mode
2. Enter protected mode (CR0.PE=1)
3. Reload CS, DS, ES, SS to flush the descriptor caches
4. Setup 64-bit GDTR
5. Enter long mode (compatibility mode)
6. Reload CS, DS, ES, SS to flush the descriptor caches, I would reload CS with 32-bit selector here, but you may try to do a direct 64-bit selector.
*) If the logical address for GDTR changed due to paging, you need to reload GDTR and refresh selector registers with IRET(can be done with RETF in some situation)
**) Refer to the manual for all the required steps.

If you do Real->IA32e directly
1. You need to setup 64-bit GDTR before switch to compatible mode
2. Enter long mode (compatibility mode)
3. Reload CS, DS, ES, SS to flush the descriptor caches
*) If the logical address for GDTR changed due to paging, you need to reload GDTR and refresh selector registers with IRET(can be done with RETF in some situation)
**) Refer to the manual for all the required steps.


EDIT: OMG This is a thousand...
Post Reply