Page 1 of 1

Linking & higher half

Posted: Wed Oct 05, 2005 2:39 pm
by yukito
Hi,

I'm trying to link my kernel to higher half, but grub keeps complaining about "loading below 1MB is not supported". What am I doing wrong?

here's the ld script:

Code: Select all

ENTRY (_loader)

SECTIONS
{
    . = 0xF0100000;

    .text : AT(ADDR(.text) - 0xF0000000)
    {
        *(.text)
    }

    .rodata ALIGN (0x1000) : AT(ADDR(.rodata) - 0xF0000000)
    {
        *(.rodata)
    }

    .data ALIGN (0x1000) : AT(ADDR(.data) - 0xF0000000)
    {
        *(.data)
    }

    .bss :  AT(ADDR(.bss) - 0xF0000000)
    {
        _sbss = .;
        *(COMMON)
        *(.bss)
        _ebss = .;
    }
    
    _endofkernel = . ;
}

Re:Linking & higher half

Posted: Wed Oct 05, 2005 4:24 pm
by Kemp
Does your multiboot header tell grub to load the kernel below the 1MB mark?

Re:Linking & higher half

Posted: Wed Oct 05, 2005 5:56 pm
by Crazed123
And why exactly do you want to load your kernel in the last 256 MB of address space?

Re:Linking & higher half

Posted: Wed Oct 05, 2005 11:07 pm
by AR
Try objdump-ing, make sure the kernel is linked correctly and all the sections have the appropriate virtual and physical addresses (you may also want to generate a link map as it can be quite handy in the future as well)

Re:Linking & higher half

Posted: Thu Oct 06, 2005 4:05 am
by yukito

Code: Select all

KERNEL_VIRTUAL_BASE equ 0xF0000000   ; last 256MB of address space will be the virtual address for our kernel's code
KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22)
Is the part in the multiboot header about using a higher half kernel?

And why not load it in the last 256mb? I don't need more than 256MB for the kernel, now do I? this way I have lots and lots of address space to play around with later :)

Re:Linking & higher half

Posted: Thu Oct 06, 2005 2:04 pm
by Crazed123
Most people load it at 0xC0000000 and give the kernel 1 GB of address space to use so that if their kernel needs to take up more space later it can.

Re:Linking & higher half

Posted: Thu Oct 06, 2005 2:25 pm
by yukito
Yes I know, and I assume it is better than my 256MB, but I intend to keep my kernel light & small, so it should never need more then 256MB of address space for anything...

Re:Linking & higher half

Posted: Thu Oct 06, 2005 2:31 pm
by bluecode
Crazed123 wrote: Most people load it at 0xC0000000 and give the kernel 1 GB of address space to use so that if their kernel needs to take up more space later it can.
Which kernel really needs 1GiB? And if some kernel does, wtf is that kernel doing? Does it include speech recognition ;D ?

Re:Linking & higher half

Posted: Thu Oct 06, 2005 3:30 pm
by yukito
My point exactly ;) Maybe it's an AI OS with 1Gig of rules or something.

Anyway, as we're not getting any closer to a solution and I would like my code to boot again so I can bug you people with other questions ;), maybe the assembly entry code can help:

Code: Select all

; Entry code for zerOS, by Wim Vander Schelden, based on many tutorials found at www.osdever.net and www.mega-tokyo.com/osfaq2
; Many thanks to bluecoder

global _loader           ; making entry point visible to linker
extern _main             ; _main is defined elsewhere

; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ  1<<0                   ; align loaded modules on page boundaries
MEMINFO     equ  1<<1                   ; provide memory map
FLAGS       equ  MODULEALIGN | MEMINFO  ; this is the Multiboot 'flag' field
MAGIC       equ    0x1BADB002           ; 'magic number' lets bootloader find the header
CHECKSUM    equ -(MAGIC + FLAGS)        ; checksum required
KERNEL_VIRTUAL_BASE equ 0xC0000000   ; last 256MB of address space will be the virtual address for our kernel's code
KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22)

section .data
; The following part contains the kernels page directory
kernelpagingdir:
   dd 0x00000083   ; First page: identity map the first 4MB - will be erased later
         ; bits set:
         ;   0 - page is present
         ;   1 - page is writable
         ;   7 - page is 4MB large
   times(KERNEL_PAGE_NUMBER-1) dd 0 ; All other pages, before the 0xF0000000 mark, are not present
   dd 0x00000083   ; Same as the first page, but now mapping 0xF0000000 to 0x00000000
   times(1024-KERNEL_PAGE_NUMBER-1) dd 0   ; All pages after the kernel are not present

; Note that the lines below are used for flat segmentation, every segment starts at 0 and ends at 
; the end of the systems memory. The lots of labels are just so that I would know what does what two weeks from now
GDTLIMIT    dw 40         ; The limit of the GDT: 5 entries * 8 bytes per entry -1 = 40
GDTBASE     dd NULLENTRYLIMITL   ; Start of the table

NULLENTRYLIMITL   dw 0         ; Null entry in the GDT
NULLENTRYBASEL   dw 0
NULLENTRYBASEM   db 0
NULLENTRYACCESS db 0
NULLENTRYGRANUL   db 0
NULLENTRYBASEH   db 0

KERNELCSLIMITL   dw 0xFFFF      ; Kernel code segment
KERNELCSBASEL   dw 0x0000
KERNELCSBASEM   db 0x00
KERNELCSACCESS   db 0x9A
KERNELCSGRANUL   db 0xCF
KERNELCSBASEH   db 0

KERNELDSLIMITL   dw 0xFFFF      ; Kernel data segment
KERNELDSBASEL   dw 0x0000
KERNELDSBASEM   db 0x00
KERNELDSACCESS   db 0x92
KERNELDSGRANUL   db 0xCF
KERNELDSBASEH   db 0

USERCSLIMITL   dw 0xFFFF      ; User code segment
USERCSBASEL   dw 0x0000
USERCSBASEM   db 0x00
USERCSACCESS   db 0xFA
USERCSGRANUL   db 0xCF
USERCSBASEH   db 0

USERDSLIMITL   dw 0xFFFF      ; User data segment
USERDSBASEL   dw 0x0000
USERDSBASEM   db 0x00
USERDSACCESS   db 0xF2
USERDSGRANUL   db 0xCF
USERDSBASEH   db 0

; End of segmentation code

section .text
align 4
MultiBootHeader:
   dd MAGIC
   dd FLAGS
   dd CHECKSUM

; reserve initial kernel stack space
STACKSIZE equ 0x4000          ; that's 16k.

_loader:
   mov esp, stack+STACKSIZE-KERNEL_VIRTUAL_BASE   ; set up the stack
   lgdt [GDTLIMIT-KERNEL_VIRTUAL_BASE]      ; set up the GDT
   mov cx, 0x10               ; The kernel data segment (16 byte offset into the GDT)
   mov ds, cx               ; copy it to the data segment registers
   mov es, cx
   mov fs, cx
   mov gs, cx
   mov ss, cx               ; and stack segment
   jmp 0x08:continue-KERNEL_VIRTUAL_BASE      ; Far jump into the code segment, on the next line
   continue:
   push eax               ; pass Multiboot magic number
   push ebx               ; pass Multiboot info structure
   call _main               ; call kernel
      hlt               ; halt machine should kernel return (which never should happen)

set_paging:
   

section .bss
align 32
stack:
   resb STACKSIZE      ; reserve 16k stack on a quadword boundary
Note that paging is not yet enabled, but grub complains before even loading the kernel...

Re:Linking & higher half

Posted: Fri Oct 07, 2005 10:42 pm
by proxy
you know the kernel code itsaelf will likely be WAY smaller than a gig, but keep in mind that each thread usually will have a kernel stack (which could be allocated through a kernel heap). So the max size of the heap and/or kernel stacks can put a practical limitation on the number of threads you can run. So using more than 256 isn't THAT insane (though it does seem like a bit much, my OS has yet to use over 8 meg)

proxy

Re:Linking & higher half

Posted: Sat Oct 08, 2005 9:07 am
by JoeKayzA
It also depends on whether you use a microkernel or not. But even a microkernel can need tons of heap memory, as proxy stated, for kernel heaps, mapping & thread/process structures, message queues....

When you use recursive page directory mappings, for e.g., every address space you get access to needs 4MB of virtual memory (1024 page tables).

If you are really keen on keeping kernel space as small as possible, you'd need to fiddle with paging when your kernel heap gets larger. Map data pages in and out on demand, don't use recursive pdir mappings. But IMVHO, 3GB for userspace should really be enough, otherwise you should consider refitting userspace code to be less space consuming.

cheers Joe

Re:Linking & higher half

Posted: Sat Oct 08, 2005 8:05 pm
by Crazed123
There are SOME specialized applications (very large databases, supercomputing, etc) that would require more than 3GB of userspace, but for most of us hobbyists writing a system that has to run that stuff is a pipe dream.