Page 2 of 2

Re: GCC cross-compiler mcmodel=large?

Posted: Sat Dec 13, 2014 5:34 pm
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

Re: GCC cross-compiler mcmodel=large?

Posted: Sat Dec 13, 2014 9:12 pm
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

Re: GCC cross-compiler mcmodel=large?

Posted: Sun Dec 14, 2014 2:14 am
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.

Re: GCC cross-compiler mcmodel=large?

Posted: Sun Dec 14, 2014 6:17 am
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.

Re: GCC cross-compiler mcmodel=large?

Posted: Sun Dec 14, 2014 6:42 am
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.

Re: GCC cross-compiler mcmodel=large?

Posted: Sun Dec 14, 2014 6:51 am
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.

Re: GCC cross-compiler mcmodel=large?

Posted: Sun Dec 14, 2014 10:22 am
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.

Re: GCC cross-compiler mcmodel=large?

Posted: Sun Dec 14, 2014 11:11 am
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