Page 1 of 2

putting my kernel at 0xC0000000

Posted: Wed Mar 16, 2005 9:21 am
by Poseidon
I'm currently trying to let my kernel think it is at 3 gig high in the memory, but GRUB gives an error that I have not enough memory. How can I let GRUB load it at physical 0x100000 and stop it from giving an error I don't have 3 gig of memory?

Thanks.

Re:putting my kernel at 0xC0000000

Posted: Wed Mar 16, 2005 2:09 pm
by Poseidon
I tried the following linker script, which would let GRUB let it load at 0x100000, and still changes the addresses... when I use it I get an error that it doesn't fit into the memory???

Code: Select all


OUTPUT_FORMAT("elf32-i386")
ENTRY(_loader)
virt = 0xC0100000; /* 3 gig */
phys = 0x100000; /* 1 meg */
SECTIONS
{ .text virt : AT(phys)
{ code = .;
*(.text)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{ data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{ bss = .;
*(.bss)
*(COMMON)
. = ALIGN(4096);
}
end = .;
}
Is there something in my code wrong, something in the linkerscript or is my floppy dead?

Thanks

Re:putting my kernel at 0xC0000000

Posted: Wed Mar 16, 2005 2:26 pm
by Pestilence
Poseidon wrote: I'm currently trying to let my kernel think it is at 3 gig high in the memory
That would be a virtual memory thing. References to 0xC0000000 need to translate to 0x00100000 (where your kernel actually is).

You need to tell GRUB to load the kernel to 0x00100000, and then before you use any code that makes reference to 0xC0000000, you need to set up the translation (e.g.: paging, Tim's segmentation trick).

Read this thread: http://www.mega-tokyo.com/forum/index.p ... eadid=7438

Re:putting my kernel at 0xC0000000

Posted: Wed Mar 16, 2005 2:28 pm
by Silverhawk
this is one of my post, titled "OS memory structure" on the first page.

Re:putting my kernel at 0xC0000000

Posted: Wed Mar 16, 2005 2:33 pm
by Silverhawk
your linker script seems to be correct...
I've tried one similar, and it works fine !

what your entry point "_loader" looks like ?

Re:putting my kernel at 0xC0000000

Posted: Thu Mar 17, 2005 1:05 am
by Poseidon
my _loader thing:

1. it clears all the space from physical mem addr 0x9C000 to 0xA0000 for the page directory
2. i create a pagetable for my kernel, first page in the table starts at 0x100000
3. put some extra pages like vga mem in the table
4. i put the pagetable at 0 to 4 mb and at 3 gig in the pagedirectory and enables paging


but this doesn't have anything to do with the size of my kernel, i suppose :(

Re:putting my kernel at 0xC0000000

Posted: Thu Mar 17, 2005 8:30 am
by Poseidon
by the way, this is the message I get:

Code: Select all

root (fd0)
 Filesystem type is fat, using whole disk
kernel /boot/kernel.elf
   [Multiboot-elf, <0x0:0xeb6:0x0>

Error 28: Selected item cannot fit into memory

Re:putting my kernel at 0xC0000000

Posted: Thu Mar 17, 2005 12:29 pm
by Poseidon

Code: Select all

Program Header:
    LOAD off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
         filesz 0x00000eb6 memsz 0x00000eb6 flags r--
    LOAD off    0x00001000 vaddr 0xc0100000 paddr 0x00100000 align 2**12
         filesz 0x00003000 memsz 0x00003000 flags r-x
    LOAD off    0x00004000 vaddr 0xc0103000 paddr 0x00103000 align 2**12
         filesz 0x00001000 memsz 0x00002000 flags rw-
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rwx
still not fixed... here is a objdump. does this say anything to any1?

still waiting for help :)
thanks

Re:putting my kernel at 0xC0000000

Posted: Thu Mar 17, 2005 1:29 pm
by Candy
the first is at 0x000, which grub can't do. Place it elsewhere.

Re:putting my kernel at 0xC0000000

Posted: Thu Mar 17, 2005 2:56 pm
by Poseidon

Code: Select all

fixed it... have converted my entry point from at&t to intel syntax and placed 'section .entry' at the top, put it in my linker script to make the addresses OK, and where everything has been set up i put a 'section .text'. the only problem is that bochs 'reboots' here:

mov eax, cr0
or eax, 0x80000000
mov cr0, eaxmov eax, cr0
or eax, 0x80000000
mov cr0, eax

jmp continue

section .text

continue:
add esp, 0xC0000000
unpage_first: ;unpage the first table
; . . .

Code: Select all


it looks ok with an objdump -S, but still bochs crashes on it. I didn't test it on a real machine yet. can anybody find what's wrong?

thanks.
   
   jmp continue                   ; i suppose it crashes here
   
section .text

continue:
   add esp, 0xC0000000
unpage_first: ;unpage the first table
; . . .
it looks ok with an objdump -S, but still bochs crashes on it. I didn't test it on a real machine yet. can anybody find what's wrong?

thanks.

EDIT: i think i get why the kernel crashes... continue is at 0xC0100000, which is in the table 0x100000. forgot to change it while changing everything with sections. gonna try it now :)

Re:putting my kernel at 0xC0000000

Posted: Thu Mar 17, 2005 3:17 pm
by Poseidon
first, see edit last post.

It still doesn't work, here is a bit info:

Code: Select all

Idx Name          Size      VMA       LMA       File off  Algn
  0 .entry        000000c0  00100000  00100000  00001000  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .text         00002ff6  c01000c0  001000c0  000010c0  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .data         00000194  c01030c0  001030c0  000040c0  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  3 .bss          00000a30  c0103260  00103260  00004260  2**5
                  ALLOC
and a bit disassembled code :)

Code: Select all

1000b0:   0f 20 c0                mov    %cr0,%eax
  1000b3:   0d 00 00 00 80          or     $0x80000000,%eax
  1000b8:   0f 22 c0                mov    %eax,%cr0
  1000bb:   e9 00 00 00 c0          jmp    c01000c0 <code>
Disassembly of section .text:

c01000c0 <code>:
c01000c0:   81 c4 00 00 00 c0       add    $0xc0000000,%esp
thanks.

Re:putting my kernel at 0xC0000000

Posted: Thu Mar 17, 2005 4:19 pm
by Silverhawk
If bochs reboots when once paging is enabled, it's that you've done wrong paging maping (or bad entries in page dir / page table with bad privileges)...
Is this a CPU 14 exception you have ?

Re:putting my kernel at 0xC0000000

Posted: Fri Mar 18, 2005 1:20 am
by Candy
I believe it was explicitly required to make a long jump after enabling protected mode, IE, a 0xEA long jump. You currently use a 0xE9 jump.

Re:putting my kernel at 0xC0000000

Posted: Fri Mar 18, 2005 1:43 pm
by Poseidon
I've fixed it... well, actually, I already had fixed it but didn't realise it, just 5 lines further there was another bug:
the first page was already unpaged and the address of the multiboot header was still there, so I moved the unpage function to somewhat later. I decided to create a table next to the first (so i put the address of it at 0x9c004) containing the whole 0 to 4 mb (i also use the memory map from grub), then I add 0x400000 to the original address of the multiboot info struct but I can't get the values... what can I have done wrong?
Here are a few pieces of my code:

entry.s

Code: Select all

infoheader:   dd 0 ; space for saving the info struct
_loader:
   mov dword [infoheader], ebx ; save the address in ebx in infoheader

;somewhat later in the code...
; fill in the table with 0mb to 4mb
        mov eax, 0xa0000
   mov ebx, 0x0
page_first4mb:
   mov ecx, ebx
   or ecx, 0x3
   mov dword [eax], ecx
   add eax, 0x4
   add ebx, 0x1000
   cmp eax, 0xa1000
   jne page_first4mb

; again somewhat later in the code
mov dword [0x9c004], 0xa0003       ; put address of table at the second entry

; again somewhat later in the code
        mov ebx, [infoheader]             ; put infostruct back
   push ebx                                ; push it on the stack
   
   call _main            ;call the 'real' kernel
and a few pieces of init.c:

Code: Select all

void _main (multiboot_info_t* mbi) {
   multiboot_info_t *new_mbi = (int) 0x400000 + (int) mbi; // create a new pointer to the multiboot info struct, but then the physical address
   unpage_0(); // not needed anymore, delete it
     
   video_init(); // init video
// just some debugging info
   printf("Old MBI: %i - 0x%x\n", mbi, mbi);
   printf("New MBI: %i - 0x%x\n", new_mbi, new_mbi);
   
   printf("Memory: %i\n", (int) new_mbi->mem_lower);
   printf("Memory: %i\n", (int) new_mbi->mem_upper);
   printf("Memory: %i\n", (int) new_mbi->mmap_addr);
   cli();
   hlt(); // because of debugging reasons, halt the kernel
can anyone see what's wrong?
thanks.

Re:putting my kernel at 0xC0000000

Posted: Fri Mar 18, 2005 2:45 pm
by Silverhawk
I don't understand what you've written...
0xa0000 is the address of a page table ? You've put it in the video reserved range of memory ?