Thread: [EXPERTS] Wired linker problem

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    2

    Unhappy [EXPERTS] Wired linker problem

    I'm coding a little kernel in C and ASM and I use only GCC + NASM for coding. GRUB loads my little kernel.
    Everything goes well, but there is one really wired problem with ld, which I use for linking the stuff...

    My kernel is about 8kb big and loads well with GRUB. But when I exceed a specific amount of code the size of my kernel goes up from 8kb to 1 MB and GRUB won't load it anymore.
    It says, it won't recognize the file format anymore. So I think it doesn't finds the GRUB boot sigmature ( in entry.asm ) anymore.

    I use following command for linking:
    Code:
    ld -T link.ld -o kernel.bin entry.o main.o display.o memory.o string.o io.o gdt.o gdt_helper.o
    The linker script link.ld:
    Code:
    OUTPUT_FORMAT("binary")
    ENTRY(start)
    phys = 0x00100000;
    SECTIONS
    {
      .text phys : AT(phys) {
        code = .;
        *(.text)
        . = ALIGN(4096);
      }
      .data : AT(phys + (data - code))
      {
        data = .;
        *(.data)
        . = ALIGN(4096);
      }
      .bss : AT(phys + (bss - code))
      {
        bss = .;
        *(.bss)
        . = ALIGN(4096);
      }
      end = .;
    }
    My start code in entry.asm:
    Code:
    [BITS 32]
    global start
    
    start:
    	mov esp, _sys_stack     ; This points the stack to our new stack area
    	jmp stublet
    
    ; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4'
    ALIGN 4
    mboot:
        ; Multiboot macros to make a few lines later more readable
        MULTIBOOT_PAGE_ALIGN	equ 1<<0
        MULTIBOOT_MEMORY_INFO	equ 1<<1
        MULTIBOOT_AOUT_KLUDGE	equ 1<<16
        MULTIBOOT_HEADER_MAGIC	equ 0x1BADB002
        MULTIBOOT_HEADER_FLAGS	equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
        MULTIBOOT_CHECKSUM	equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
        EXTERN code, bss, end
    
        ; This is the GRUB Multiboot header. A boot signature
        dd MULTIBOOT_HEADER_MAGIC
        dd MULTIBOOT_HEADER_FLAGS
        dd MULTIBOOT_CHECKSUM
        
        ; AOUT kludge - must be physical addresses. Make a note of these:
        ; The linker script fills in the data for these ones!
        dd mboot
        dd code
        dd bss
        dd end
        dd start
    
    stublet:
    	extern k_main
    	call k_main
    	jmp $
    
    ; Here is the definition of our BSS section. Right now, we'll use
    ; it just to store the stack. Remember that a stack actually grows
    ; downwards, so we declare the size of the data before declaring
    ; the identifier '_sys_stack'
    SECTION .bss
        resb 8192               ; This reserves 8KBytes of memory here
    _sys_stack
    I think the problem lies in the liker script, but I'm unable to find it myself... *sniff*
    Last edited by mrsuicide; 08-14-2005 at 04:18 AM.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Posts
    1
    i think the problem lies in your "AT" statements. you're telling ld to place .data at (phys+data-code) but data's address is based on .data's place. same applies for the following sections. you don't have to put these AT statement except for the first one, sections in your lists will be adjacent without them and it's less confusing this way.

  3. #3
    Registered User
    Join Date
    Aug 2005
    Posts
    2

    Cool

    I found a soloution for myself.

    I sent the linker script and my asm startup file to hell.
    Now I'm linking with:
    Code:
    ld --oformat elf32-i386 --entry 0x100000 -Ttext 0x100000 -Map kernel.map -O 1 -o kernel.bin [*.o files]
    And my new startup code is:
    Code:
    [includes]
    
    void start(); //Entry point
    void k_main(const struct multiboot_info *mbi); //Kernel main
    
    void start() { // Before header
    __asm__ __volatile__("pushl %ebx"); //Push multiboot information
    __asm__ __volatile__("call k_main");
    while(1);
    }
    
    const unsigned MultibootHeader[12] __attribute__ ((section(".text"))) = { //........ u grub!
      MULTIBOOT_HEADER_MAGIC, // der magische Wert
      MULTIBOOT_HEADER_FLAGS, // die Flags
      -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS), //-MULTIBOOT_HEADER_MAGIC - FLAGS = CHECKSUM
      (unsigned) MultibootHeader, // Offset des Headers
      (unsigned) start, // Offset von main() als Beginn des Code Segments
      0x00000000, // Data Segment, da scheißen wir drauf
      0x00000000, // BSS Segment, wer braucht`n sowas?
      (unsigned) start, // nochmal main(), diesmal als Entry Point
      0x00000000, // Grafik? Nein, danke! 
      0x00000050, // 80 Spalten
      0x00000019, // 25 Zeilen
      0x00000000 // 0 BPP, wir sind im Text-Modus
    }; 
    
    void k_main(const struct multiboot_info *mbi) {
    k_set_color(D_COLOR_WHITE,D_COLOR_BLUE);
    k_cls();
    k_printf(welcomeMsg);
    gdt_install();
    idt_install();
    init_mm(mbi);
    irq_install();
    init_timer();
    init_keyboard();
    (...)
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mysterious Linker Error
    By Night_Blade in forum Windows Programming
    Replies: 0
    Last Post: 04-30-2006, 01:50 PM
  2. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  3. vc++ linker options problem
    By fnoyan in forum C++ Programming
    Replies: 2
    Last Post: 12-08-2005, 11:22 AM
  4. Replies: 5
    Last Post: 11-07-2005, 11:34 PM
  5. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM