cannot make binary kernel work with GRUB

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

cannot make binary kernel work with GRUB

Post by songziming »

Hi, i use grub to boot my kernel. Instead of cross compiling the kernel, I use objcopy to produce binary image to get rid of every host-specific information. mbchk indicates that the binary kernel is valid, however GRUB reports Error 13.

This is my kernel source (currently only one file)

Code: Select all

extern  kernel_load_addr
extern  kernel_data_end
extern  kernel_bss_end

MB_MAGIC    equ 0x1badb002
MB_FLAGS    equ 1<<0|1<<1|1<<16
MB_CHECK    equ -(MB_MAGIC+MB_FLAGS)

[SECTION    .boot]
[BITS       32]

    jmp     multiboot_entry
ALIGN   4
multiboot_header:
    dd      MB_MAGIC
    dd      MB_FLAGS
    dd      MB_CHECK
    dd      multiboot_header
    dd      kernel_load_addr
    dd      kernel_data_end
    dd      kernel_bss_end
    dd      multiboot_entry

multiboot_entry:
    cli

    mov     al, 'H'
    mov     ah, 0x0f
    mov     [0xb8000], ax

    jmp     $
And this is my link script

Code: Select all

OUTPUT_FORMAT(elf32-i386)
SECTIONS {
    . = 1M;
    kernel_load_addr = .;
    .text BLOCK(4K) : ALIGN(4K) {
        kernel_text_start = .;
        *(.boot)
        *(.text)
        kernel_text_end = .;
    } = 0x90
    .data BLOCK(4K) : ALIGN(4K) {
        kernel_data_start = .;
        *(.rodata)
        *(.data)
        kernel_data_end = .;
    } = 0x90
    .bss BLOCK(4K) : ALIGN(4K) {
        kernel_bss_start = .;
        *(COMMON)
        *(.bss)
        kernel_bss_end = .;
    } = 0x90
}
and the command for compile and linking is

Code: Select all

yasm -f elf multiboot.asm -o multiboot.o
ld -m elf_i386 -T link.lds multiboot.o -o kernel.elf
objcopy -O binary kernel.elf kernel.bin
Besides, I'm producing 32-bit code on a 64-bit Linux, does it matter?
Reinventing the Wheel, code: https://github.com/songziming/wheel
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Re: cannot make binary kernel work with GRUB

Post by max »

songziming wrote:Instead of cross compiling the kernel
Use a cross toolchain.

I'm sorry but we can't try to find a solution for all kinds of grotesque ways that people try to build their kernels. Using your systems linker will cause problems.
Last edited by max on Wed Mar 11, 2015 11:50 am, edited 1 time in total.
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

Re: cannot make binary kernel work with GRUB

Post by songziming »

I did try using cross compiler and change the output format in the link.lds to binary. But I still get the Error 13 from GRUB.
Reinventing the Wheel, code: https://github.com/songziming/wheel
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Re: cannot make binary kernel work with GRUB

Post by max »

songziming wrote:I did try using cross compiler and change the output format in the link.lds to binary. But I still get the Error 13 from GRUB.
If you're using a cross compiler, it shouldn't be necessary to specify the output format. I think you should not have that "jmp" instruction right before your multiboot header.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: cannot make binary kernel work with GRUB

Post by kzinti »

You haven't defined an entry point in your linker script. Usually you want to use '_start'. Add a "_start" label before the jump over the multiboot header. Then add "ENTRY(_start)" to your linker script.
no92
Member
Member
Posts: 307
Joined: Wed Oct 30, 2013 1:57 pm
Libera.chat IRC: no92
Location: Germany
Contact:

Re: cannot make binary kernel work with GRUB

Post by no92 »

songziming wrote:I did try using cross compiler and change the output format in the link.lds to binary. But I still get the Error 13 from GRUB.
Wait, wait, wait!
OSDev.org Wiki wrote:[...] making a cross-compiler is required, so as not to link in the development system's runtime files.
If it's written there, do it, for the love of programming. There's a reason for it. Just do it, even if you don't understand it yet.

While not having worked with linker scripts, I noticed two things: kzinti already pointed the first one, while I don't know what this is supposed to do:

Code: Select all

} = 0x90
Icee
Member
Member
Posts: 100
Joined: Wed Jan 08, 2014 8:41 am
Location: Moscow, Russia

Re: cannot make binary kernel work with GRUB

Post by Icee »

Because you have no actual data in the .data section, it is not copied to the output file. However, the symbol kernel_data_end still has the address 0x101000 associated with it because of the enforced alignment in linker script. GRUB tries to load 0x1000 and cannot because the resulting file is smaller. You have two options: either remove the alignment directives (by the way, the ALIGN directive after the colon should not be there in the first place), or add something to the data section, like this:

Code: Select all

[SECTION .data]
DD 0
You should also not pad the .data and .bss sections with NOPs (=0x90), this is meaningless for .data and, in fact, erroneous for .bss because the latter must be zero-initialized.
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

Re: cannot make binary kernel work with GRUB

Post by songziming »

Icee's method works!

To be clear, my purpose is to make a BINARY kernel, not ELF kernel. Because I think all the machine-dependencies have something to do with elf meta data.
Reinventing the Wheel, code: https://github.com/songziming/wheel
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: cannot make binary kernel work with GRUB

Post by Roman »

songziming wrote:I think all the machine-dependencies have something to do with elf meta data.
What? The code is machine-dependent because every ISA (instruction set architecture) has its own encoding.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
Post Reply