Page 1 of 1

Grub2 - address out of range

Posted: Tue Jul 30, 2013 11:10 am
by Vanzef
Hello, everybody! I'm trying to boot my custom kernel in bochs, but when I invoke "call" instruction bochs crushes. Bochs says that I must set up IDT. OK, I use this code to do all routine:
boot.s file:

Code: Select all

    .section .boot
    .global entry
    .global load_addr

    .set    stackSize, 0x4000
entry:
/*
    movl    $(stack + stackSize), %esp

    pushl   $0
    popf

    pushl   %ebx
    pushl   %eax
*/
    
//leave protected mode
    movl    %cr0, %eax
    and     0xfffe, %eax
    movl    %eax, %cr0

//load gdt and idtt
    lgdt    gdtr
    lidt    idtr

//stop interrupts (all!)    
    cli
    inb     $0x70, %al
    or      $0x80, %al
    outb    %al, $0x70

//enter protected mode

    movl    %cr0, %eax
    or      0x1, %eax
    movl    %eax, %cr0
 
    call    main
    .comm   stack, stackSize
(This code is under construction, but it doesn't matter)
mbhdr.s - multiboot2 header file

Code: Select all

    .section .mbhdr

    .set    magic, 0xe85250d6
    .set    street_magic, 0x36d76289
    .set    architecture, 0x0
    .set    length, (MBEnd-MBStart)
    .set    checksum, -(magic + length + architecture)
    
MBStart:
    .align  8
    .long   magic
    .long   architecture
    .long   length
    .long   checksum
    
tags:

//The adress tag of Multiboot header
at_s:
    .short  2
    .short  1
    .long   at_e-at_s
    .long   MBStart
//    .long   load_addr           
    .long   entry
    .long   load_end_addr
    .long   bss_end_addr
at_e:

//The entry address tag of Multiboot header
ea_s:
    .short  3
    .short  1
    .long   ea_e-ea_s
    .long   entry
ea_e:

//Flags tag
//no size? (in spec)
/*    .word   4
    .word   0
    .long   12
    .long   0
*/
//end of tags
    .align  8
    .short  0
    .short  0
    .long   8
MBEnd:
Also I have gdt.s and idt.s:
gdt.s:

Code: Select all

    .global gdt, gdtr
    .section .gdt_sect

gdt:
null:
    .quad   0

kernel_code:
    .byte   0x0
    .byte   0b11010000

    .byte   0b10011010
    .byte   0x0

    .word   0x0

    .word   0x800

kernel_data:
    .byte   0x0
    .byte   0b11010000

    .byte   0b10010010
    .byte   0x0

    .word   0x0

    .word   0x800

user_code:
    .byte   0x0
    .byte   0b11010000

    .byte   0b11111110
    .byte   0x0

    .word   0x800

    .word   0x800

user_data:
    .byte   0x0
    .byte   0b11010000

    .byte   0b11110010
    .byte   0x0

    .word   0x800

    .word   0x800

gdtr:
    .long   gdt
    .word   5*8-1
idt.s:

Code: Select all

    .global idt, idtr
    .section idt_sect

idt:
null:
    .quad   0x0

idtr:
    .long   idt
    .word   8*1-1
Last but not least:
linker.ld:

Code: Select all

ENTRY   (entry)
LMA = 0x00100000;

SECTIONS{
    . = LMA;
    .multiboot                 :    {   *(.mbhdr)
                                        *(.gdt_sect)
                                        *(.idt_sect)        
                                        *(.boot)            }
    .text       ALIGN (0x1000) :    {   *(.text)            }
    .rodata     ALIGN (0x1000) :    {   *(.rodata*)         }
    .data       ALIGN (0x1000) :    {   *(.data)            }
    load_end_addr = .;
    .bss                       :    {   *(COMMON) *(.bss)   }
    bss_end_addr = .;
    KERNEL_END = .;
    /DISCARD/                  :    {   *(.comment)         }
}
So, when I'm trying to boot it, Grub2 says:" address out of range... load kernel first..."
Which "address" is out of range and why it is there?

P.S. Sorry for my bad english.

Re: Grub2 - address out of range

Posted: Wed Jul 31, 2013 5:37 am
by Combuster
Vanzef wrote:Which "address" is out of range and why it is there?
Ask objdump to (initially) give you a list of sections to check if they're all in the correct place, use the mbchk tool for more verbose messages, and try disassembling the multiboot header for sanity.

Re: Grub2 - address out of range

Posted: Wed Jul 31, 2013 7:34 am
by Vanzef
So, I check sections with "objdump -ph" and I found one strange thing: there was idt_sect, but the wasn't gdt_sect.
I tried to create new section called "descriptors" in linker.ld, but the result was the same. As I undestand, mistake in "linker.ld" file, but I don't know where it is there?
P.S. More information by "objdump" you can find in attached file.