OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Mar 29, 2024 1:04 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Error: Entry point isn't in a segment
PostPosted: Sun Nov 30, 2014 2:25 pm 
Offline
Member
Member
User avatar

Joined: Mon Jun 16, 2014 5:33 pm
Posts: 213
Location: Costa Rica
Hi!

I was trying to follow the wiki's Higher-Half tutorial. It looked too easy... Simple arithmetic and that's it. But when I compile and run all the stuff, GRUB 2.00 revenges again :x . A little message appears, saying:
GRUB 2.00 wrote:
error: entry point isn't in a segment.
error: you need to load the kernel first.

Press any key to continue...


What am I doing wrong? I saw that in the tutorial, the .text section wasn't page-aligned. I did it, and the same error apperars. Then I saw the tutorial puts the Multiboot header in the .text section, but that's just awful and dangerous. I changed my code, just for test, and obviously a "multiboot not found" error appeared; undoed that. Here's the relevant code (in file /arch/x86/init/bootstrap.S):
Code:
.set ALIGN,    1<<0             # align loaded modules on page boundaries
.set MEMINFO,  1<<1             # provide memory map
.set FLAGS,    ALIGN | MEMINFO  # this is the Multiboot 'flag' field
.set MAGIC,    0x1BADB002       # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot

.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.align 0x1000

.section .stack, "aw", @nobits
stackBottom:
   .skip 16384
stackTop:

.set KVIRT_BASE, 0xC0000000
.set KPAGE_NUM,   (KVIRT_BASE >> 22)

.section .data
pageDirectory:
   .long 0x00000083
   .fill (KPAGE_NUM - 1), 4, 0x00000000
   .long 0x00000083
   .fill (1024 - KPAGE_NUM - 1), 4, 0x00000000

.section .text
.global __start__
.set __start__, (setup - 0xC0000000)
setup:
   movl (pageDirectory - KVIRT_BASE), %eax
   movl %ecx, %cr3
   
   movl %cr4, %ecx
   orl $0x00000010, %ecx
   movl %ecx, %cr4
   
   movl %cr0, %ecx
   orl $0x80000000, %ecx
   movl %ecx, %cr0
   
   lea (realstart), %ecx
   jmp *%ecx
   
realstart:
   movl $0x00000000, (pageDirectory)
   invlpg (0)
   
   movl $stackTop, %esp
   movl %esp, %ebp
   
   push %ebx
   push %eax
   call KernelInit
   
   cli
   hlt
.hang:
   jmp .hang


And here's the relevant linker script:
Code:
ENTRY(__start__)
OUTPUT_FORMAT(elf32-i386)

SECTIONS {
   . = 0xC0100000;

   .text : ALIGN(0x1000) : AT(ADDR(.text) - 0xC0000000) {
       *(.multiboot)
       *(.text)
   }
   
   .rodata ALIGN(0x1000) : AT(ADDR(.rodata) - 0xC0000000) {
       *(.rodata*)
   }
   
   .data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) {
       *(.data)
   }

   .bss : AT(ADDR(.bss) - 0xC0000000) {
       *(COMMON)
       *(.bss)
       *(.stack)
   }
   
   __KEND__ = .;
}


The wiki says I shouldn't calculate the physical address of __start__ myself, or I'll get the mentioned error. But I'm not doing it :-k

_________________
Happy New Code!
Hello World in Brainfuck :D:
Code:
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.


Top
 Profile  
 
 Post subject: Re: Error: Entry point isn't in a segment
PostPosted: Sun Nov 30, 2014 4:13 pm 
Offline
Member
Member
User avatar

Joined: Wed Mar 21, 2012 3:01 pm
Posts: 930
May I suggest you don't mix multiboot and higher half? It's not pretty when code has to relocate itself. I recommend you use a bootloader (perhaps a custom one) that enables paging when loading your kernel and maps it already to virtual locations. You pass the locations of where the paging tables are mapped and the memory map to the kernel, it can then bootstrap itself and take control of paging. You then simply link the kernel at somewhere location you want it.

I blew some nukes on the wiki and got rid of some of the duplicated and ill-advised higher half tutorials, just leaving not-entirely-bad ones. We need a good rewrite, I'll get around to that eventually, but I believe it's bad design for code to relocate itself and that paging-enabling is a bootloader responsibility; therefore multiboot is a broken design in my opinion.

Another approach could be to have two kernels, with one as a normal multiboot kernel at 1 MiB, and another as the real kernel that as is passed as an initrd to the wrapper kernel, the wrapper kernel enables paging and loads the real kernel according to its ELF headers and passes control to it. This has the advantage of not being a full custom bootloader.


Top
 Profile  
 
 Post subject: Re: Error: Entry point isn't in a segment
PostPosted: Sun Nov 30, 2014 9:18 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 21, 2011 9:47 pm
Posts: 286
Location: Tustin, CA USA
I'm successfully using multiboot and 64 bit higher half. The biggest problems are the elf page size and the structure alignments.

I'm on my phone now, but you can check out my make file and loader from the link below.

EDIT: Now that I have the benefit of a larger screen, I see I had the same problem. The way I overcame this in my code was to skip the tricky stuff and simply set the entry point. In other words, set your entry point to be setup.

Finally, I would pull your multiboot and initial 32-bit setup code into its own elf section and put that first in the linker script. I put my entry point in a .boot section and told the linker to put it right behind my multiboot data structures. Then, I set my .text section in the higher virtual address.

_________________
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber


Top
 Profile  
 
 Post subject: Re: Error: Entry point isn't in a segment
PostPosted: Mon Dec 01, 2014 11:12 am 
Offline

Joined: Thu Oct 09, 2014 5:09 pm
Posts: 12
Try consolidating your "__start__" and "setup" address. Don't subtract 0xC0000000 from setup.

I learned this the hard way a few week ago. Grub's multiboot will expect the start symbol to be located above 0xC0000000.

You can see my (very similar) linker.ld and start.s script for comparison.


Top
 Profile  
 
 Post subject: Re: Error: Entry point isn't in a segment
PostPosted: Mon Dec 01, 2014 3:08 pm 
Offline
Member
Member
User avatar

Joined: Mon Jun 16, 2014 5:33 pm
Posts: 213
Location: Costa Rica
naegelejd wrote:
Try consolidating your "__start__" and "setup" address. Don't subtract 0xC0000000 from setup.

I learned this the hard way a few week ago. Grub's multiboot will expect the start symbol to be located above 0xC0000000.

You can see my (very similar) linker.ld and start.s script for comparison.


Thanks, that solved it! I'll edit the wiki with this information :wink: . Now I have another (minor) problem. How can I debug the __start__ function (there's no setup now) with GDB? It triple faults inmediately. Probably I did a bad conversion between NASM and GAS code #-o . I'll try several combinations until GDB breaks at realstart.

Edit: I've finally managed to debug with GDB, even in this situation (command break *something - 0xC0000000), then lots of stepi and info reg ecx. Thanks to all of your for your help! I'll take in account sortie's suggestion BTW.

_________________
Happy New Code!
Hello World in Brainfuck :D:
Code:
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 151 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group