Page 1 of 1

HigherHalfWithGdt and Grub Error 28

Posted: Tue Jul 11, 2006 4:14 am
by yegor
Hello, All.

I'm trying to build a higher-half kernel with gcc 2.95.2 and gnu ld version 2.9.1. Method is one described in HigherHalfWithGdt article.

I used linker script from FAQ with no changes, assembler part has been rewritten to GAS.

The problem is when I try to launch new kernel, Grub 0.97 says: "Selected item cannot fit into memory."

Code: Select all

$ objdump -x kernel

kernel:     file format elf32-i386
kernel
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0xc010002c

Program Header:
    LOAD off    0x00000000 vaddr 0xc00ff000 paddr 0x000ff000 align 2**12
         filesz 0x000038ea memsz 0x000038ea flags r-x
    LOAD off    0x00004000 vaddr 0xc0103000 paddr 0x00103000 align 2**12
         filesz 0x00000e88 memsz 0x0000d924 flags rw-

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .setup        0000001e  00100000  00100000  00005000  2**0
                  CONTENTS, READONLY
  1 .text         000028ca  c0100020  00100020  00001020  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .data         00000e88  c0103000  00103000  00004000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  3 .bss          0000c924  c0104000  00104000  00005000  2**5
                  ALLOC
  4 .note         00000104  c0110924  c0110924  0000501e  2**0
                  CONTENTS, READONLY
  5 .comment      000001ee  c0110a28  c0110a28  00005122  2**0
                  CONTENTS, READONLY
Even if I delete suspicious .note and .comment sections with strip, Grub reports the same error.

Any ideas?

Re:HigherHalfWithGdt and Grub Error 28

Posted: Tue Jul 11, 2006 4:47 am
by Solar
Without looking too close at the objdump, any specific reason for using a 1998 linker and a 2001 compiler? Just curious, because my first reflex would have been updating my toolchain to the latest public release...

Re:HigherHalfWithGdt and Grub Error 28

Posted: Tue Jul 11, 2006 5:04 am
by yegor
It's very simple. :-) I just don't know root password on that machine.

Re:HigherHalfWithGdt and Grub Error 28

Posted: Tue Jul 11, 2006 5:28 am
by Solar
You can use that 2.9x GCC to compile an up-to-date version of tools and install that to /home/yegor/bin or whereever you want. I would honestly recommend going through the GCC Cross-Compiler tutorial using TARGET=i386-elf and PREFIX={wherever-you-have-access} to rule out some long-fixed bugs in your tools as the cause for your problems.

And now I step back to leave room for those who can help you with your other problem (the GRUB error). ;)

Re:HigherHalfWithGdt and Grub Error 28

Posted: Tue Jul 11, 2006 8:40 am
by yegor
Well, it's not a bad idea to build newer gcc, but it was not the point here. :-)

Of course, I did must specify "ax" attributes for .setup section in head.S. :-)

Re:HigherHalfWithGdt and Grub Error 28

Posted: Thu Jul 13, 2006 1:13 am
by Pype.Clicker
i'm suspicious about your "paddr 0x000ff000" part (presumably, the linker said the whole chunk had to be loaded at 0xff000 so that after the section info (one page), the code actually stands at 0x100000: quite weird).

Grub may not like to require something loaded below 1MB. Earlier versions of GRUB didn't liked physical addresses to differ from logical addresses. Checking you have a recent GRUB may help.

Re:HigherHalfWithGdt and Grub Error 28

Posted: Thu Jul 13, 2006 1:26 am
by Solar
His GRUB is 0.97, that's recent.

Re:HigherHalfWithGdt and Grub Error 28

Posted: Mon Jul 24, 2006 8:00 am
by quok
I had a similar problem when porting the HigherHalfWithGDT code to GAS, and I was using a recent toolchain (binutils 2.17 and gcc 4.1.1).

I did eventually get it to work, I'm attaching my loader.S code for review. :)

Code: Select all

# loader.S

.global _loader # make 'start' function global
.extern _main # our C kernel main

# Multiboot constants
.set MULTIBOOT_PAGE_ALIGN,    1<<0
.set MULTIBOOT_MEMORY_INFO,   1<<1
.set MULTIBOOT_HEADER_MAGIC,  0x1BADB002
.set MULTIBOOT_HEADER_FLAGS,  MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
.set MULTIBOOT_CHECKSUM,       -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

# Multiboot header (needed to boot from GRUB)
.align 4
multiboot_header:
        .long MULTIBOOT_HEADER_MAGIC
        .long MULTIBOOT_HEADER_FLAGS
        .long MULTIBOOT_CHECKSUM

.set STACKSIZE, 0x4000

# the kernel entry point
_loader:
        # here's the trick: we load a GDT with a base address
        # of 0x40000000 for the code (0x08) and data (0x10) segments
        lgdt trickgdt
      mov $0x10, %ax
      mov %ax, %ds
      mov %ax, %es
      mov %ax, %fs
      mov %ax, %gs
      mov %ax, %ss


        # jump to the higher half kernel
        jmp $0x08, $higherhalf

higherhalf:
        # from now the CPU will translate automatically every address
        # by adding the base 0x40000000

      mov $kernel_stack, %esp # set up a new stack for our kernel

        call _main # jump to our C kernel

        # just a simple protection...
        jmp .

.global gdt_flush # make 'gdt_flush' accessible from C code
.extern gp        # tells the assembler to look at C code for 'gp'

# this function does the same thing of the 'start' one, this time with
# the real GDT
gdt_flush:
        lgdt gp
      mov $0x10, %ax
      mov %ax, %ds
      mov %ax, %es
      mov %ax, %fs
      mov %ax, %gs
      mov %ax, %ss
        jmp $0x08, $flush2

flush2:
        ret

.section .setup, "a" # tells the assembler to include this data in the '.setup' section

trickgdt:
        .word gdt_end - gdt - 1 # size of the GDT
        .long gdt # linear address of GDT

gdt:
       # null gate
        .long 0, 0
        # code selector 0x08: base 0x40000000, limit 0xFFFFFFFF, type 0x9A, granularity 0xCF
      .byte 0xFF, 0xFF, 0, 0, 0, 0B10011010, 0B11001111, 0x40
        # data selector 0x10: base 0x40000000, limit 0xFFFFFFFF, type 0x92, granularity 0xCF
      .byte 0xFF, 0xFF, 0, 0, 0, 0B10010010, 0B11001111, 0x40

gdt_end:

.section .bss
.align 32
.skip 0x4000 # 16K stack space, 32-bit aligned
kernel_stack:
        # our kernel stack