GCC cross-compiler mcmodel=large?

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
eryjus
Member
Member
Posts: 286
Joined: Fri Oct 21, 2011 9:47 pm
Libera.chat IRC: eryjus
Location: Tustin, CA USA

Re: GCC cross-compiler mcmodel=large?

Post by eryjus »

XenOS wrote:
Brendan wrote:Of course then you'd split up each area into specific pieces (text, data, bss; shared library area, whatever).
I'm quite curious how exactly you would split these things up. Do you have any particular locations for user mode libraries? Or page tables, PL0-stacks, other kernel relevant stuff?
I'm by no means an expert. However, I will speak to my personal experience. I started with the above advice as a starting point as a result of being challenged with the 32-bit immediate issues with 64-bit code. Ultimately, when I started working on my paging tables and trying to figure out recursive mapping, I made the critical decision to keep my recursive mappings at the highest memory locations.

Therefore, I have so far developed the following memory map. Disclaimer: I am only so far working on the kernel, so large portions of this map is currently unused. I might also get a few months down the road and change everything again as I learn more.

0x0000 0000 0000 0000 to 0x0000 7fff ffff ffff -- User memory space (not defined at this point)
0xffff 8000 0000 0000 to 0xffff 8fff ffff ffff -- Kernel Code (.text & .rodata)
0xffff 9000 0000 0000 to 0xffff 9fff ffff ffff -- Kernel Data (.data & .text)
0xffff a000 0000 0000 to 0xffff afff ffff ffff -- Kernel Heap
0xffff b000 0000 0000 to 0xffff bfff ffff ffff -- Driver/Daemon Code [future development]
0xffff c000 0000 0000 to 0xffff cfff ffff ffff -- Driver/Daemon Data [future development]
0xffff d000 0000 0000 to 0xffff dfff ffff ffff -- Driver/Daemon Heap [future development]
0xffff e000 0000 0000 to 0xffff efff ffff ffff -- Future Use -- Unknown at this time
0xffff f000 0000 0000 to 0xffff f001 ffff ffff -- Physical Memory Manager Bitmap -- enough room to manage 256TB
0xffff f002 0000 0000 to 0xffff f003 ffff ffff -- Stacks (not sure if kernel-only at this point); enough room for 512K X 16KB stacks
0xffff f004 0000 0000 to 0xffff ff7f ffdf ffff -- System reserved memory
0xffff ff7f ffe0 0000 to 0xffff ff7f ffef ffff -- Reserved for pointer initialization space (where dereferencing a pointer will cause page-fault)
0xffff ff7f fff0 0000 to 0xffff ff7f ffff efff -- TSSs (at 1 per CPU, this will be far more space than I will ever use; but I have space to do something different is I so choose)
0xffff ff7f ffff f000 to 0xffff ff7f ffff ffff -- Specific location for initializing page table internal structures before inserting them into their proper right location
0xffff ff80 0000 0000 to 0xffff ffff bfff ffff -- Page Tables recursive mapping
0xffff ffff c000 0000 to 0xffff ffff ffdf ffff -- Page Directories recursive mapping
0xffff ffff c000 0000 to 0xffff ffff ffdf ffff -- Page Directory Pointer Tables recursive mapping
0xffff ffff ffff f000 to 0xffff ffff ffff ffff -- PML4 recursive mapping
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: GCC cross-compiler mcmodel=large?

Post by Brendan »

Hi,
eryjus wrote:
XenOS wrote:
Brendan wrote:Of course then you'd split up each area into specific pieces (text, data, bss; shared library area, whatever).
I'm quite curious how exactly you would split these things up. Do you have any particular locations for user mode libraries? Or page tables, PL0-stacks, other kernel relevant stuff?
I'm by no means an expert. However, I will speak to my personal experience. I started with the above advice as a starting point as a result of being challenged with the 32-bit immediate issues with 64-bit code. Ultimately, when I started working on my paging tables and trying to figure out recursive mapping, I made the critical decision to keep my recursive mappings at the highest memory locations.
That doesn't sound right to me. The kernel's text, data, bss need to be in the highest 2 GiB (so you can use sign extended 32-bit immediate addressing); while the recursive mappings takes up 512 GiB of space. If you have the recursive mappings in the highest addresses, then it's impossible for the kernel to use sign extended 32-bit immediates.

For kernel space, I'd start with this:
  • 0xFFFF800000000000 to 0x00007FFFFFFFFFFF = area for dynamically allocated memory (heap, stack, etc)
    0xFFFFFFFF80000000 to 0xFFFFFFFFFFFFFFFF = area for "2 GiB or smaller" kernel text, rodata, data, bss
For a micro-kernel, I'd assume the kernel doesn't need 128 TiB of space and start splitting it up like this:
  • 0xFFFF800000000000 to 0xFFFFFEFFFFFFFFFF = unused
    0xFFFFFF0000000000 to 0xFFFFFF7FFFFFFFFF = 512 GiB recursive paging structure mapping
    0xFFFFFF8000000000 to 0xFFFFFFFF7FFFFFFF = 510 GiB area for dynamically allocated memory (heap, stacks, etc)
    0xFFFFFFFF80000000 to 0xFFFFFFFFFFFFFFFF = 2 GiB area for kernel text, rodata, data, bss
For a monolithic kernel; I'd probably do the same, except I'd split up that "unused" area up; starting with space for VFS cache and memory mapped IO devices, so maybe:
  • 0xFFFF800000000000 to 0xFFFF9FFFFFFFFFFF = 32 TiB area for memory mapped IO
    0xFFFFA00000000000 to 0xFFFFBFFFFFFFFFFF = 32 TiB area for virtual file system caches
    0xFFFFC00000000000 to 0xFFFFEFFFFFFFFFFF = device drivers or something?
    0xFFFFFF0000000000 to 0xFFFFFF7FFFFFFFFF = 512 GiB recursive paging structure mapping
    0xFFFFFF8000000000 to 0xFFFFFFFF7FFFFFFF = 510 GiB area for dynamically allocated memory (heap, stacks, etc)
    0xFFFFFFFF80000000 to 0xFFFFFFFFFFFFFFFF = 2 GiB area for kernel text, rodata, data, bss

Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: GCC cross-compiler mcmodel=large?

Post by xenos »

Thanks Brendan, that looks exactly like the layout I'm implementing at the moment :)

eryjus, my former layout is quite similar to yours, but now I'm switching from mcmodel=large to mcmodel=kernel.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: GCC cross-compiler mcmodel=large?

Post by mariuszp »

mariuszp wrote:OK, I tried moving my kernel to higher memory (0xFFFF800000000000+) and I have a very strange TSS problem. The structure of the TSS segment (in the GDT) is:

Code: Select all

	; The TSS
	.TSS_limitLow: dw 0
	.TSS_baseLow: dw 0
	.TSS_baseMiddle: db 0
	.TSS_Access: db 11101001b
	.TSS_limitHigh: dw 0
	.TSS_baseMiddleHigh: db 0
	.TSS_baseHigh: dd 0
	dd 0
Which I got from the Intel manuals. The base and limit fields are filled in later by some assembly code, and after loading the GDT once the TSS segment was filled in, I use a Bochs magic breakpoint, then I type "info gdt" and it says:

Code: Select all

GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0x00000000, Execute-Only, Non-Conforming, Accessed, 64-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0x00000000, Read-Only, Accessed
GDT[0x03]=Code segment, base=0x0f000000, limit=0x0000ffff, Execute-Only, Non-Conforming, 64-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0x00000000, Read/Write
GDT[0x05]=32-Bit TSS (Available) at 0x001001b0, length 0x000c0
GDT[0x06]=??? descriptor hi=0x000000ff, lo=0xff800000
You can list individual entries with 'info gdt [NUM]' or groups with 'info gdt [NUM] [NUM]'
I don't understand why it thinks the TSS segment is 32-bit... according to the Intel manuals, the type which I use (1001) is automatically considered 64-bit in 64-bit mode. However, Bochs is showing me that the TSS segment is 32-bit, and the high 32 bits of my TSS address become part of segment 6, which is undefined, and therefore the TSS base becomes invalid, and then it says the TSS base is non-canonical! What am I doing wrong here?
Sorry for re-posting this but I think it got unnoticed as it was the last thing on the previous page.
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: GCC cross-compiler mcmodel=large?

Post by Combuster »

I have a lot of hunches, including the use of an outdated Bochs and not using the GDT structure as specified by the intel manuals.
"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 ]
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: GCC cross-compiler mcmodel=large?

Post by mariuszp »

Combuster wrote:I have a lot of hunches, including the use of an outdated Bochs and not using the GDT structure as specified by the intel manuals.
My full GDT structure is as follows, I believe it is correct:

Code: Select all

GDT64:                               ; Global Descriptor Table (64-bit).
	.Null: equ $ - GDT64         ; The null descriptor.
	dw 0                         ; Limit (low).
	dw 0                         ; Base (low).
	db 0                         ; Base (middle)
	db 0                         ; Access.
	db 0                         ; Granularity.
	db 0                         ; Base (high).
	.Code: equ $ - GDT64         ; The code descriptor.
	dw 0                         ; Limit (low).
	dw 0                         ; Base (low).
	db 0                         ; Base (middle)
	db 10011000b                 ; Access.
	db 00100000b                 ; Granularity.
	db 0                         ; Base (high).
	.Data: equ $ - GDT64         ; The data descriptor.
	dw 0                         ; Limit (low).
	dw 0                         ; Base (low).
	db 0                         ; Base (middle)
	db 10010000b                 ; Access.
	db 00000000b                 ; Granularity.
	db 0                         ; Base (high).
	.UserCode: equ $ - GDT64
	dw 0
	dw 0
	db 0
	db 11111000b                 ; Access.
	db 00100000b                 ; Granularity.
	db 0                         ; Base (high).
	.UserData: equ $ - GDT64
	dw 0                         ; Limit (low).
	dw 0                         ; Base (low).
	db 0                         ; Base (middle)
	db 11110010b                 ; Access.
	db 00000000b                 ; Granularity.
	db 0                         ; Base (high).
	; The TSS
	.TSS: equ $ - GDT64
	.TSS_limitLow: dw 0
	.TSS_baseLow: dw 0
	.TSS_baseMiddle: db 0
	.TSS_Access: db 11101001b
	.TSS_limitHigh: dw 0
	.TSS_baseMiddleHigh: db 0
	.TSS_baseHigh: dd 0
	dd 0
	.Pointer:                    ; The GDT-pointer.
	dw $ - GDT64 - 1             ; Limit.
	.Addr64: dq (GDT64 - 0xFFFF800000100000 + 0x100000)                     ; Base.
Im using Bochs 2.6.1, in it's source code I see references to "64-bit TSS".

EDIT: On real hardware it just triple faults and resets. Strange.
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: GCC cross-compiler mcmodel=large?

Post by Combuster »

I believe
OS development is not a religious exercise. I'll let you get away with not checking as the intel website 500s on me.

Instead, read the AMD manual volume 2, page 91.
"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 ]
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: GCC cross-compiler mcmodel=large?

Post by mariuszp »

Combuster wrote:
I believe
OS development is not a religious exercise. I'll let you get away with not checking as the intel website 500s on me.

Instead, read the AMD manual volume 2, page 91.
After looking at this billions of times, I've finally noticed the error - I set one of the field to 16 bits when it should be 8 bits. Eh... Well, thanks for help :D
Post Reply