putting my kernel at 0xC0000000

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.
Poseidon

putting my kernel at 0xC0000000

Post 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.
Poseidon

Re:putting my kernel at 0xC0000000

Post 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
Pestilence

Re:putting my kernel at 0xC0000000

Post 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
Silverhawk

Re:putting my kernel at 0xC0000000

Post by Silverhawk »

this is one of my post, titled "OS memory structure" on the first page.
Silverhawk

Re:putting my kernel at 0xC0000000

Post 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 ?
Poseidon

Re:putting my kernel at 0xC0000000

Post 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 :(
Poseidon

Re:putting my kernel at 0xC0000000

Post 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
Poseidon

Re:putting my kernel at 0xC0000000

Post 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
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:putting my kernel at 0xC0000000

Post by Candy »

the first is at 0x000, which grub can't do. Place it elsewhere.
Poseidon

Re:putting my kernel at 0xC0000000

Post 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 :)
Poseidon

Re:putting my kernel at 0xC0000000

Post 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.
Silverhawk

Re:putting my kernel at 0xC0000000

Post 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 ?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:putting my kernel at 0xC0000000

Post 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.
Poseidon

Re:putting my kernel at 0xC0000000

Post 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.
Silverhawk

Re:putting my kernel at 0xC0000000

Post 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 ?
Post Reply