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 ?