Page 1 of 2
Switching to virtual memory management
Posted: Sat Nov 08, 2014 5:52 am
by psychobeagle12
Hello all! I have been working on a small system for a few weeks now (I have worked on a few little hobby systems and I am pretty good with C and x86 assembly.) I am loosely following Brokenthorn's OS Development Series and most of the OSDev Wiki pages when needed. Anyway, here is the issue. I am starting to migrate from pure physical memory management to virtual memory management. I am using GRUB to load the system, GCC and NASM to build. I built a small assembler stub that sets up basic paging tables and then jumps to my higher half kernel. For some reason, when I jump to the higher half (which is still in the stub part) I am getting a page fault, gp fault, then finally triple fault (obviously caused by the invalid idt.) Here is the assembler stub and the linker script:
Code: Select all
;-----------------------------------------------------------------------------------------;
; kboot.asm: Version two of the kernel bootstrap (forms jump point for GRUB) ;
; Written by Ben Melikant 11/2014 ;
; This bootstrap sets up a basic paging directory table for the kernel so that our ;
; jump to the kernel does not result in triple-fault. ;
;-----------------------------------------------------------------------------------------;
bits 32
; paging identification info
%define PAGE_DIRECTORY_ADDR 0x9C000
%define PAGE_TABLE_0_ADDR 0x9D000
%define PAGE_TABLE_768_ADDR 0x9E000
%define PAGE_TABLE_ENTRIES 1024
%define FIRST_MEG_ENTRIES 256
%define PAGE_PRIVILEGE 3
; multiboot information definitions
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS)
; place the multiboot header in it's own section
[section .multiboot]
align 4
multiboot_hdr:
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
; switch to the .startup section
[section .startup]
[global start]
; memory location to preserve the multiboot pointer
multiboot_ptr dd 0x00000000
; global descriptor table (to override GRUB's table)
gdt_start:
dd 0,0
db 0xff,0xff,0x00,0x00,0x00,10011010b,11001111b,0x00
db 0xff,0xff,0x00,0x00,0x00,10010010b,11001111b,0x00
gdt_table:
dw gdt_table-gdt_start-1
dd gdt_start
;------------------------------------------------------------------------------------------;
; start: Load into the operating system proper by setting up a page directory table ;
; and enabling paging. The OS is loaded at 0x10000 physical, 0xC0000000 virtual. ;
; If the OS ever returns, we have an issue. ;
;------------------------------------------------------------------------------------------;
start:
; load a new global descriptor table (override GRUB's table)
lgdt [gdt_table]
jmp 0x08:next
next:
; fix our segments
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
; jump to the actual start code, below the paging install routine
mov dword [multiboot_ptr],ebx
jmp start_system
;---------------------------------------------------------;
; setup_paging: Enable paging before executing OS ;
; Inputs: None, Returns: None ;
;---------------------------------------------------------;
setup_paging:
; save the registers
pusha
; identity-map addresses 0x00000000 - 0x00400000
mov eax,PAGE_TABLE_0_ADDR
mov ebx,0 | PAGE_PRIVILEGE
mov ecx,PAGE_TABLE_ENTRIES
.identity_loop:
mov dword [eax],ebx ; put the address entry into the table
add eax,4 ; queue next page entry
add ebx,4096 ; each entry is 4Kb
loop .identity_loop ; set up next entry
; next set up the address for the kernel page table
mov eax,PAGE_TABLE_768_ADDR
mov ebx,0x10000 | PAGE_PRIVILEGE
mov ecx,PAGE_TABLE_ENTRIES
.kernel_loop:
mov dword [eax],ebx ; same as above
add eax,4 ; same as above
add ebx,4096 ; same as above
loop .kernel_loop ; same as above
.already_mapped:
; install the tables into the directory
mov eax,PAGE_TABLE_0_ADDR | PAGE_PRIVILEGE
mov dword [PAGE_DIRECTORY_ADDR],eax
mov eax,PAGE_TABLE_768_ADDR | PAGE_PRIVILEGE
mov dword [PAGE_DIRECTORY_ADDR+(768*4)],eax
; install the page directory into cr3 (pdbr)
mov eax,PAGE_DIRECTORY_ADDR
mov cr3,eax
popa
ret
start_system:
; first set up the page directory table and page tables
call setup_paging
push dword [multiboot_ptr]
mov ebx,0xb8000
mov byte [ebx],'H'
; now enable the paging mechanism
mov eax,cr0
or eax,0x80000000
mov cr0,eax
mov byte [0xc0000000],'i' ; this memory access works...
jmp 0x08:paging_code
; paging is enabled. All addresses must now be translated as virtual
; switch to the .text section (regular system code, 0xC0000000 virtual)
[section .text]
[extern kmain]
paging_code:
; mov ebx,0xb8002
; mov byte [ebx],'i'
; restore the multiboot ptr
; pop ebx
; now all we need to do is call the kernel loadpoint
; mov esp,system_stack
; push ebx
; call kmain
; a safeguard. The code should never reach this point
jmp $
[section .bss]
resb 0x1000
system_stack:
; our kernel stack begins here
and the link script:
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
SECTIONS {
. = 0x10000;
.startup :
{
*(.multiboot)
*(.startup)
}
. += 0xC0000000;
.text : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
}
.data ALIGN(4096) : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
*(.rodata*)
}
.bss ALIGN(4096) : AT(ADDR(.bss) - 0xC0000000)
{
*(COMMON*)
*(.bss*)
}
kernel_end=.;
}
Do I have a logical approach to getting into paging mode, or am I completely on the wrong track here? I appreciate any help, and again I apologize if this is a duplicate question at all. Thanks everyone!
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 8:02 am
by Combuster
Without actually reading the question:
Code: Select all
%define PAGE_DIRECTORY_ADDR 0x9C000
%define PAGE_TABLE_0_ADDR 0x9D000
%define PAGE_TABLE_768_ADDR 0x9E000
That's likely to be reserved addresses.
That maps to the addresses 64K up to 4M+64K, which is probably not what you want.
Stackpointer undefined.
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 8:32 am
by psychobeagle12
That maps to the addresses 64K up to 4M+64K, which is probably not what you want.
Yes, that code is a mistake that I never changed back after trying a few experimental changes. I had forgotten about that. I want to map 0x00100000 - 0x00400000 for my OS code. As for the stack pointer, I believe I am setting it up in the startup code here:
Code: Select all
;------------------------------------------------------------------------------------------;
; start: Load into the operating system proper by setting up a page directory table ;
; and enabling paging. The OS is loaded at 0x10000 physical, 0xC0000000 virtual. ;
; If the OS ever returns, we have an issue. ;
;------------------------------------------------------------------------------------------;
start:
; load a new global descriptor table (override GRUB's table)
lgdt [gdt_table]
jmp 0x08:next
next:
; fix our segments
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
; jump to the actual start code, below the paging install routine
mov dword [multiboot_ptr],ebx
jmp start_system ; this just skips the following enable_paging routine
As for the other addresses, to be honest I took most of the basic page mapping code from Brokenthorn's virtual memory management tutorial, so I used the same memory values found on that tutorial for my code. I can move them around if necessary no problem. I will try to change the addresses around and also make sure I change my linker script and mapping routine for 0x100000 instead of 0x10000. Anything else that jumps out to anybody? I'm very open to suggestions
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 10:00 am
by eryjus
Check for setting esp again. I see you cleaning up ss after jumping to next to set your cs register. After setting the ss, you should be executing mov esp,<you-stack-pointer>.
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 10:23 am
by psychobeagle12
Yes, I see the mistake with the stack now. Sorry, I'm not too crazy... I seem to have mixed up the words "pointer" and "segment." My mistake.
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 10:44 am
by psychobeagle12
Well, I made the following changes:
Code: Select all
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x90000 ; fixed stack pointer, again location taken from Brokenthorn
; jump to the actual start code, below the paging install routine
mov dword [multiboot_ptr],ebx
jmp start_system
and also:
Code: Select all
mov eax,PAGE_TABLE_768_ADDR
mov ebx,0x100000 | PAGE_PRIVILEGE
mov ecx,PAGE_TABLE_ENTRIES
and lastly:
Code: Select all
%define PAGE_DIRECTORY_ADDR 0x7E00
%define PAGE_TABLE_0_ADDR 0x7F00
%define PAGE_TABLE_768_ADDR 0x8000
I also changed the start address in my linker script to 0x100000. None of these seemed to fix my issue. The bochs log shows exactly the same pattern with the revised code. Page fault (no vector available), GP Fault (no vector available), triple fault - reset.
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 11:17 am
by Combuster
You forgot a zero (page structures must be page aligned)
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 11:57 am
by psychobeagle12
Oops, another typo. I'm writing the code on my laptop, posting from my desktop. I in fact used
Code: Select all
%define PAGE_DIRECTORY_ADDR 0x7E000
%define PAGE_TABLE_0_ADDR 0x7F000
%define PAGE_TABLE_768_ADDR 0x80000
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 12:10 pm
by eryjus
psychobeagle12 wrote:Code: Select all
; next set up the address for the kernel page table
mov eax,PAGE_TABLE_768_ADDR
mov ebx,0x10000 | PAGE_PRIVILEGE
mov ecx,PAGE_TABLE_ENTRIES
.kernel_loop:
mov dword [eax],ebx ; same as above
add eax,4 ; same as above
add ebx,4096 ; same as above
loop .kernel_loop ; same as above
Correct me if I am wrong, but you really want virtual address 0xc0000000 to map to physical address 0x00000000 (and more to the point, virtual address 0xc0100000 to map to physical address 0x00100000)?
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 12:19 pm
by psychobeagle12
eryjus wrote:psychobeagle12 wrote:Code: Select all
; next set up the address for the kernel page table
mov eax,PAGE_TABLE_768_ADDR
mov ebx,0x10000 | PAGE_PRIVILEGE
mov ecx,PAGE_TABLE_ENTRIES
.kernel_loop:
mov dword [eax],ebx ; same as above
add eax,4 ; same as above
add ebx,4096 ; same as above
loop .kernel_loop ; same as above
Correct me if I am wrong, but you really want virtual address 0xc0000000 to map to physical address 0x00000000 (and more to the point, virtual address 0xc0100000 to map to physical address 0x00100000)?
As far as I know, given the knowledge base I have on paging (I am honestly still very new to paging) the code I have written (or rather followed) will map the first page table to 0x00000000 (identity-mapping the first 4mb), and then will map address 0x100000 to 0xC0000000. Perhaps I am wrong in my understanding of the code I followed. And that raises a question for me as well. To my knowledge, bits 11 - 31 in a page table entry point to the physical address of the mapping, correct? So why, in the example read from Brokenthorn, would we not shift the entry left (0x100000 << 11) to set the entry correctly? I think I am still confused on this. Rather than ask anybody to fix this for me, I think I will reread the paging tutorial, unless I am on the right track? I appreciate the responses though, know that you guys are helping me very much!
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 6:55 pm
by eryjus
OK, I am by no means an expert in paging and virtual memory. However, I have just completed a similar fight myself so the topic is still fresh in my mind. I'm sure if I get some of the details wrong, there are many people willing to set both of us straight.
First a few tool I use:
readelf will show you the sections of your file and where they will be loaded. In particular, the Program Headers ans Section to Segment mapping will show you where your binary is expected to live. In the Program Headers, look for "VirtAddr" and "PhysAddr" for each section. Take note that your .startup section is expected to load at physical address 0x00100000 and at virtual address 0x00100000. Thus, you need the identity map once you enable paging to get to the next instruction to execute.
Now, your .text section will likely be at a physical address (for the sake of argument since I cannot see your file) 0x00100e00. This will correspond to a virtual address of 0xc0100e00 based on your linker script. Notice you stated in your script:
This line changes your virtual offset for the program you are linking, but does not impact where your elf binary will really be loaded in physical memory. You want this offset because you want to be able to have your low memory stub and high memory kernel to coexist nicely, which they cannot do if they are in the same physical memory. By the way, you might want to page-align the .text segment so you have the option to reclaim that stub code memory space at a later time.
This all really means you want virtual address 0xc0000000 to map to physical address 0x00000000 and virtual address 0xc0100000 to map to 0x00100000. This is not how your paging tables are setup.
Now for the paging tables. I highly recommend taking a look at the Intel software development manuals. In short, the physical address is "assembled" from the different entries in the paging tables. The Intel System Programming Guide, Part 1, Chapter 4 contains a good discussion on paging, and a number of tables that lay out the page table entries. In particular, section 4.3 is specific to 32-bit paging. Find the manuals
here.
psychobeagle12 wrote:To my knowledge, bits 11 - 31 in a page table entry point to the physical address of the mapping
Bits 31:12 of the physical address are assembled from the virtual address and the entries found in the tables at each level. That is: bits 31:22 of the virtual address identify a page directory entry, where bits 31:12 of the resulting PDE identify a (4K aligned) page Table. Bits 21:12 of the virtual address identify a page table entry, where bits 31:12 of the resulting PTE identify a 4k page of physical memory. Bits 11:0 of your virtual address indicate the offset (bits 11:0) into your 4K aligned page of physical memory.
I hope this helps. Good luck!
EDIT: fixed URL link
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 7:28 pm
by psychobeagle12
I poured over the tutorials some more (and believe it or not the Intel 80386 developer's manual) and my understanding is now much more complete. For the life of me though I cannot understand how my page tables are set up incorrectly. Yes, I realize that the address of my start code will not be 0xc0100000, but some offset into that area. However, from what I can tell my page tables still should be mapping the address of my paging_code symbol (which, according to bochs, is 0xc0101c00). My page tables are mapping this area to the correct non-virtual address, are they not? My table sets up mapping from 0xC0000000 to 0x100000 which should work correctly from what I can tell. Gives me more to think about though, I'll keep digging until I hit the nail...
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 7:49 pm
by psychobeagle12
The more I work the more frustrated I become, and the more convinced I am that this should be working! I changed my linker script:
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
SECTIONS {
. = 0x7E000;
.startup :
{
*(.multiboot)
*(.startup)
}
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
}
.data ALIGN(4096) : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
*(.rodata*)
}
.bss ALIGN(4096) : AT(ADDR(.bss) - 0xC0000000)
{
*(COMMON*)
*(.bss*)
}
kernel_end=.;
}
So now I am loading the stub code to the memory at 0x7e000, and the kernel gets loaded to physical 0x100000, virtual 0xc0100000. My page should be mapped (unless my mapping routine is really messed up, which I nearly refuse to believe barring more evidence) and I changed my directory pointers to:
Code: Select all
%define PAGE_DIRECTORY_ADDR 0x7F000
%define PAGE_TABLE_0_ADDR 0x80000
%define PAGE_TABLE_768_ADDR 0x81000
so that I wouldn't overwrite my stub with page data (my stub is smaller than 4Kb). I am quickly running out of ideas. Is it possible that I am going about this whole thing the wrong way? I feel like this is a fairly basic task of most systems and that I shouldn't bother continuing if I can't figure this part out!
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 7:55 pm
by eryjus
please post the results of readelf.
Re: Switching to virtual memory management
Posted: Sat Nov 08, 2014 8:02 pm
by psychobeagle12
readelf missy.elf -l -s:
Code: Select all
Elf file type is EXEC (Executable file)
Entry point 0x7e02e
There are 3 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x0007e000 0x0007e000 0x006f4 0x006f4 R 0x1000
LOAD 0x002000 0xc0100000 0x00100000 0x01cce 0x01cce R E 0x1000
LOAD 0x004000 0xc0102000 0x00102000 0x002a9 0x028a0 RW 0x1000
Section to Segment mapping:
Segment Sections...
00 .startup .eh_frame
01 .text
02 .data .bss
Symbol table '.symtab' contains 189 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 0007e000 0 SECTION LOCAL DEFAULT 1
2: 0007e0d4 0 SECTION LOCAL DEFAULT 2
3: c0100000 0 SECTION LOCAL DEFAULT 3
4: c0102000 0 SECTION LOCAL DEFAULT 4
5: c0103000 0 SECTION LOCAL DEFAULT 5
6: 00000000 0 SECTION LOCAL DEFAULT 6
7: 00000000 0 FILE LOCAL DEFAULT ABS src/asm/kboot.asm
8: 00000001 0 NOTYPE LOCAL DEFAULT ABS MULTIBOOT_PAGE_ALIGN
9: 00000002 0 NOTYPE LOCAL DEFAULT ABS MULTIBOOT_MEMORY_INFO
10: 1badb002 0 NOTYPE LOCAL DEFAULT ABS MULTIBOOT_HEADER_MAGIC
11: 00000003 0 NOTYPE LOCAL DEFAULT ABS MULTIBOOT_HEADER_FLAGS
12: e4524ffb 0 NOTYPE LOCAL DEFAULT ABS MULTIBOOT_CHECKSUM
13: 0007e000 0 NOTYPE LOCAL DEFAULT 1 multiboot_hdr
14: 0007e00c 0 NOTYPE LOCAL DEFAULT 1 multiboot_ptr
15: 0007e010 0 NOTYPE LOCAL DEFAULT 1 gdt_start
16: 0007e028 0 NOTYPE LOCAL DEFAULT 1 gdt_table
17: 0007e03c 0 NOTYPE LOCAL DEFAULT 1 next
18: 0007e057 0 NOTYPE LOCAL DEFAULT 1 setup_paging
19: 0007e067 0 NOTYPE LOCAL DEFAULT 1 setup_paging.identity_loo
20: 0007e083 0 NOTYPE LOCAL DEFAULT 1 setup_paging.kernel_loop
21: 0007e090 0 NOTYPE LOCAL DEFAULT 1 setup_paging.already_mapp
22: 0007e0ae 0 NOTYPE LOCAL DEFAULT 1 start_system
23: c0101500 0 NOTYPE LOCAL DEFAULT 3 paging_code
24: c01048a0 0 NOTYPE LOCAL DEFAULT 5 system_stack
25: 00000000 0 FILE LOCAL DEFAULT ABS x86_display.c
26: 00000000 0 FILE LOCAL DEFAULT ABS x86_idt.c
27: 00000000 0 FILE LOCAL DEFAULT ABS x86_pic.c
28: c0100302 29 FUNC LOCAL DEFAULT 3 x86_inportb
29: c010031f 30 FUNC LOCAL DEFAULT 3 x86_outportb
30: 00000000 0 FILE LOCAL DEFAULT ABS x86_gdt.c
31: c0100625 51 FUNC LOCAL DEFAULT 3 x86_gdt_install
32: 00000000 0 FILE LOCAL DEFAULT ABS x86_pit.c
33: c01008fc 29 FUNC LOCAL DEFAULT 3 x86_inportb
34: c0100919 30 FUNC LOCAL DEFAULT 3 x86_outportb
35: 00000000 0 FILE LOCAL DEFAULT ABS hal.c
36: 00000000 0 FILE LOCAL DEFAULT ABS kernel.c
37: 00000000 0 FILE LOCAL DEFAULT ABS mmngr_physical.c
38: c0103888 4 OBJECT LOCAL DEFAULT 5 _memory_bmp
39: c010388c 2 OBJECT LOCAL DEFAULT 5 _bmp_sz
40: c0103890 4 OBJECT LOCAL DEFAULT 5 _memory_size
41: c0103894 4 OBJECT LOCAL DEFAULT 5 _free_blocks
42: c0103898 4 OBJECT LOCAL DEFAULT 5 _used_blocks
43: c010389c 4 OBJECT LOCAL DEFAULT 5 _total_blocks
44: c0101108 136 FUNC LOCAL DEFAULT 3 _pmmngr_init_region
45: c0101082 134 FUNC LOCAL DEFAULT 3 _pmmngr_find_first_free
46: c0101190 138 FUNC LOCAL DEFAULT 3 _pmmngr_deinit_region
47: 00000000 0 FILE LOCAL DEFAULT ABS stdio.c
48: 00000000 0 FILE LOCAL DEFAULT ABS string.c
49: 00000000 0 FILE LOCAL DEFAULT ABS stdlib.c
50: 00000000 0 FILE LOCAL DEFAULT ABS x86_cpu.c
51: 00000000 0 FILE LOCAL DEFAULT ABS x86_keyboard.c
52: 00000000 0 FILE LOCAL DEFAULT ABS x86_apic.c
53: 00000000 0 FILE LOCAL DEFAULT ABS mmngr_virtual.c
54: 00000000 0 FILE LOCAL DEFAULT ABS src/asm/x86_handler_irq0.
55: c0101522 0 NOTYPE LOCAL DEFAULT 3 x86_int20_handler_pit.ela
56: c010152f 0 NOTYPE LOCAL DEFAULT 3 x86_int20_handler_pit.don
57: c0101535 0 NOTYPE LOCAL DEFAULT 3 internal_counter
58: 00000000 0 FILE LOCAL DEFAULT ABS src/asm/exceptions.asm
59: c0101558 0 NOTYPE LOCAL DEFAULT 3 msgDefaultHandler
60: c01015ae 0 NOTYPE LOCAL DEFAULT 3 msgDivideByZero
61: c01015f0 0 NOTYPE LOCAL DEFAULT 3 msgDebugTrap
62: c0101627 0 NOTYPE LOCAL DEFAULT 3 msgNonMaskable
63: c010165f 0 NOTYPE LOCAL DEFAULT 3 msgBreakPoint
64: c0101695 0 NOTYPE LOCAL DEFAULT 3 msgOverflow
65: c01016cb 0 NOTYPE LOCAL DEFAULT 3 msgBoundFault
66: c0101703 0 NOTYPE LOCAL DEFAULT 3 msgInvalidOpcode
67: c010173a 0 NOTYPE LOCAL DEFAULT 3 msgDeviceError
68: c0101773 0 NOTYPE LOCAL DEFAULT 3 msgDoubleFault
69: c01017ac 0 NOTYPE LOCAL DEFAULT 3 msgInvalidTss
70: c01017e4 0 NOTYPE LOCAL DEFAULT 3 msgSegmentNotPresent
71: c010181f 0 NOTYPE LOCAL DEFAULT 3 msgStackSegmentFault
72: c010186a 0 NOTYPE LOCAL DEFAULT 3 x86_genprotectfault.gdt_d
73: c0101879 0 NOTYPE LOCAL DEFAULT 3 x86_genprotectfault.idt_d
74: c0101886 0 NOTYPE LOCAL DEFAULT 3 x86_genprotectfault.print
75: c0101888 0 NOTYPE LOCAL DEFAULT 3 _gpf_error
76: c010188c 0 NOTYPE LOCAL DEFAULT 3 msgGeneralProtectionFault
77: c01018c8 0 NOTYPE LOCAL DEFAULT 3 msgGdtDescriptor
78: c01018f1 0 NOTYPE LOCAL DEFAULT 3 msgIdtDescriptor
79: c010192c 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.pf_notprese
80: c0101945 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.pf_protecti
81: c010196b 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.from_user_m
82: c0101978 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.check_readw
83: c0101991 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.on_write
84: c010199e 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.stop
85: c01019a1 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.page_nonexi
86: c01019b1 0 NOTYPE LOCAL DEFAULT 3 x86_pagefault.fault_done
87: c01019b3 0 NOTYPE LOCAL DEFAULT 3 msgPageFault
88: c01019e9 0 NOTYPE LOCAL DEFAULT 3 msgPageProtectError
89: c0101a13 0 NOTYPE LOCAL DEFAULT 3 msgPageNonexistant
90: c0101a37 0 NOTYPE LOCAL DEFAULT 3 msgPageAccessRead
91: c0101a68 0 NOTYPE LOCAL DEFAULT 3 msgPageAccessWrite
92: c0101a9a 0 NOTYPE LOCAL DEFAULT 3 msgPagePrivilegeUser
93: c0101ac0 0 NOTYPE LOCAL DEFAULT 3 msgPagePrivilegeKernel
94: c0101ae8 0 NOTYPE LOCAL DEFAULT 3 _pf_err_code
95: c0101afa 0 NOTYPE LOCAL DEFAULT 3 msgFPUException
96: c0101b34 0 NOTYPE LOCAL DEFAULT 3 msgAlignmentCheck
97: c0101b6c 0 NOTYPE LOCAL DEFAULT 3 msgMachineCheck
98: c0101ba6 0 NOTYPE LOCAL DEFAULT 3 msgSimdException
99: c0101be1 0 NOTYPE LOCAL DEFAULT 3 msgVirtualizeException
100: c0101c22 0 NOTYPE LOCAL DEFAULT 3 msgSecurityException
101: c0101c61 0 NOTYPE LOCAL DEFAULT 3 msgTestCode
102: 00000000 0 FILE LOCAL DEFAULT ABS src/asm/x86_handler_irq7.
103: c0101ca0 0 NOTYPE LOCAL DEFAULT 3 x86_handler_irq7.spurious
104: c0101ca6 0 NOTYPE LOCAL DEFAULT 3 x86_handler_irq7.interrup
105: 00000000 0 FILE LOCAL DEFAULT ABS src/asm/x86_handler_irq15
106: c0101cc2 0 NOTYPE LOCAL DEFAULT 3 x86_handler_irq15.spuriou
107: c0101ccc 0 NOTYPE LOCAL DEFAULT 3 x86_handler_irq15.interru
108: 00000000 0 FILE LOCAL DEFAULT ABS
109: c01002f6 12 FUNC GLOBAL DEFAULT 3 x86_idt_install
110: c0101aec 0 NOTYPE GLOBAL DEFAULT 3 x86_fpuexception
111: c0101c14 0 NOTYPE GLOBAL DEFAULT 3 x86_securityexception
112: c0100000 101 FUNC GLOBAL DEFAULT 3 x86_clearscreen
113: c0100fce 94 FUNC GLOBAL DEFAULT 3 pmmngr_alloc_block
114: c0103000 2040 OBJECT GLOBAL DEFAULT 5 _idt
115: c0103800 80 OBJECT GLOBAL DEFAULT 5 _gdt
116: c0101619 0 NOTYPE GLOBAL DEFAULT 3 x86_nonmaskable
117: 00000000 0 NOTYPE GLOBAL DEFAULT UND x86_pit_update_count
118: c0100a71 15 FUNC GLOBAL DEFAULT 3 x86_pit_resetticks
119: c0101652 0 NOTYPE GLOBAL DEFAULT 3 x86_breakpoint
120: c010102c 86 FUNC GLOBAL DEFAULT 3 pmmngr_free_block
121: c010191b 0 NOTYPE GLOBAL DEFAULT 3 x86_pagefault
122: c0101811 0 NOTYPE GLOBAL DEFAULT 3 x86_stacksegfault
123: c01006c3 569 FUNC GLOBAL DEFAULT 3 x86_gdt_add_descriptor
124: c0101b5e 0 NOTYPE GLOBAL DEFAULT 3 x86_machinecheck
125: c0100ac7 13 FUNC GLOBAL DEFAULT 3 tickcount
126: c0101b26 0 NOTYPE GLOBAL DEFAULT 3 x86_aligncheck
127: c0102298 17 OBJECT GLOBAL DEFAULT 4 lettermap
128: c01005ce 87 FUNC GLOBAL DEFAULT 3 x86_pic_get_irqreg
129: c01016f5 0 NOTYPE GLOBAL DEFAULT 3 x86_badopcode
130: c0103850 6 OBJECT GLOBAL DEFAULT 5 _gdt_table
131: c0103881 1 OBJECT GLOBAL DEFAULT 5 _curY
132: c0100af9 70 FUNC GLOBAL DEFAULT 3 sound
133: c01015e2 0 NOTYPE GLOBAL DEFAULT 3 x86_debugtrap
134: c01009bc 132 FUNC GLOBAL DEFAULT 3 x86_pit_makesound
135: c0102004 4 OBJECT GLOBAL DEFAULT 4 video_memory
136: c0101bd3 0 NOTYPE GLOBAL DEFAULT 3 x86_virtualizeexception
137: c0101765 0 NOTYPE GLOBAL DEFAULT 3 x86_doublefault
138: c0101536 0 NOTYPE GLOBAL DEFAULT 3 x86_int20_pit_counter
139: c01013fc 191 FUNC GLOBAL DEFAULT 3 itoa_s
140: c0101c90 0 NOTYPE GLOBAL DEFAULT 3 x86_handler_irq7
141: c010172c 0 NOTYPE GLOBAL DEFAULT 3 x86_deviceerror
142: c010184c 0 NOTYPE GLOBAL DEFAULT 3 x86_genprotectfault
143: c01001e4 38 FUNC GLOBAL DEFAULT 3 x86_setpos
144: c0100513 38 FUNC GLOBAL DEFAULT 3 x86_pic_disable
145: c01048a0 0 NOTYPE GLOBAL DEFAULT 5 kernel_end
146: c0100273 131 FUNC GLOBAL DEFAULT 3 x86_idt_setvector
147: c0103860 32 OBJECT GLOBAL DEFAULT 5 buffer
148: c0100a40 39 FUNC GLOBAL DEFAULT 3 x86_pit_killsound
149: c0101238 47 FUNC GLOBAL DEFAULT 3 debug_puts
150: c0100a67 10 FUNC GLOBAL DEFAULT 3 x86_pit_getticks
151: c0101687 0 NOTYPE GLOBAL DEFAULT 3 x86_overflow
152: c0100a80 61 FUNC GLOBAL DEFAULT 3 hal_initialize
153: c0101cb0 0 NOTYPE GLOBAL DEFAULT 3 x86_handler_irq15
154: c010020a 105 FUNC GLOBAL DEFAULT 3 x86_idt_initialize
155: c0103880 1 OBJECT GLOBAL DEFAULT 5 _curX
156: c010033d 247 FUNC GLOBAL DEFAULT 3 x86_pic_initialize
157: c0100ad4 37 FUNC GLOBAL DEFAULT 3 setvector
158: c0100492 97 FUNC GLOBAL DEFAULT 3 x86_pic_unmask_irq
159: c01014bb 56 FUNC GLOBAL DEFAULT 3 memset
160: c0100539 139 FUNC GLOBAL DEFAULT 3 x86_pic_send_eoi
161: c01037f8 6 OBJECT GLOBAL DEFAULT 5 _idtr
162: c0100e57 375 FUNC GLOBAL DEFAULT 3 pmmngr_initialize
163: c0100abd 10 FUNC GLOBAL DEFAULT 3 hal_shutdown
164: c01016bd 0 NOTYPE GLOBAL DEFAULT 3 x86_bounderror
165: c010179e 0 NOTYPE GLOBAL DEFAULT 3 x86_invalidtss
166: c0102000 1 OBJECT GLOBAL DEFAULT 4 color_attrib
167: c010008a 116 FUNC GLOBAL DEFAULT 3 x86_scroll
168: c01004f3 32 FUNC GLOBAL DEFAULT 3 x86_pic_enable
169: c010159e 0 NOTYPE GLOBAL DEFAULT 3 x86_dividebyzero
170: c01000fe 230 FUNC GLOBAL DEFAULT 3 x86_putchar
171: c0100937 40 FUNC GLOBAL DEFAULT 3 x86_pit_initialize
172: c01017d6 0 NOTYPE GLOBAL DEFAULT 3 x86_segnotpresent
173: c0100065 37 FUNC GLOBAL DEFAULT 3 x86_color
174: c0101540 0 NOTYPE GLOBAL DEFAULT 3 x86_default_interrupt
175: c0100658 107 FUNC GLOBAL DEFAULT 3 x86_gdt_initialize
176: 0007e02e 0 NOTYPE GLOBAL DEFAULT 1 start
177: c010121a 30 FUNC GLOBAL DEFAULT 3 debug_putc
178: c0100ba7 688 FUNC GLOBAL DEFAULT 3 kmain
179: 00000000 0 NOTYPE GLOBAL DEFAULT UND _x86_swap_page
180: c0101267 405 FUNC GLOBAL DEFAULT 3 debug_printf
181: c0101510 0 NOTYPE GLOBAL DEFAULT 3 x86_int20_handler_pit
182: c0100b3f 104 FUNC GLOBAL DEFAULT 3 print_splash
183: c010095f 93 FUNC GLOBAL DEFAULT 3 x86_pit_startcount
184: c0101b98 0 NOTYPE GLOBAL DEFAULT 3 x86_simdexception
185: c0103884 4 OBJECT GLOBAL DEFAULT 5 spurious
186: c0101c53 0 NOTYPE GLOBAL DEFAULT 3 x86_testcode
187: c01005c4 10 FUNC GLOBAL DEFAULT 3 x86_pic_spurious_count
188: c0100434 94 FUNC GLOBAL DEFAULT 3 x86_pic_mask_irq
None of the C stuff is involved. It is only there because it is linked into the final executable so (I think) it can be safely ignored. Also, the relevant part of the bochs log:
Code: Select all
00017844368i[BIOS ] Booting from 0000:7c00
00060242922e[CPU0 ] interrupt(): vector must be within IDT table limits, IDT.limit = 0x0
00060242922e[CPU0 ] interrupt(): vector must be within IDT table limits, IDT.limit = 0x0
00060242922i[CPU0 ] CPU is in protected mode (active)
00060242922i[CPU0 ] CS.mode = 32 bit
00060242922i[CPU0 ] SS.mode = 32 bit
00060242922i[CPU0 ] EFER = 0x00000000
00060242922i[CPU0 ] | EAX=e0000011 EBX=000b8000 ECX=00000000 EDX=00000000
00060242922i[CPU0 ] | ESP=0008fffc EBP=00000000 ESI=00000000 EDI=00000000
00060242922i[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt of df if tf SF zf af PF cf
00060242922i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00060242922i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00060242922i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00060242922i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00060242922i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00060242922i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00060242922i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00060242922i[CPU0 ] | EIP=c0101500 (c0101500)
00060242922i[CPU0 ] | CR0=0xe0000011 CR2=0xe0000011
00060242922i[CPU0 ] | CR3=0x0007f000 CR4=0x00000000
00060242922e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00060242922i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00060242922i[CPU0 ] cpu hardware reset
Any help to anybody? :/
Edit: I should have mentioned from the beginning that this code triple-faults on real hardware as well, just to throw that into the mix...