Trying to get into protected mode, getting relocation error?

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
mango
Posts: 8
Joined: Sun May 25, 2014 6:36 pm

Trying to get into protected mode, getting relocation error?

Post by mango »

I can't use GRUB to make a disk image as I'm developing on OSX, so I've been creating binary kernel images and booting via QEMU. I've wrote an entry asm file that contains a multi boot header and an entry routine that sets up protected mode and a stack before calling into c code. However, while linking everything together I get the following error:

Code: Select all

lib/entry.o: In function `seta20p2':
(.text+0x2c): relocation truncated to fit: R_386_16 against `.text'
lib/entry.o: In function `seta20p2':
(.text+0x39): relocation truncated to fit: R_386_16 against `.text'
collect2: error: ld returned 1 exit status
My code is as follows:

Code: Select all

#include "mmu.h"

.align 4
.text
.global multiboot_header
multiboot_header:
    #define magic 0x1badb002
    #define flags 0
    .long magic
    .long flags
    .long -(magic+flags)

.global _start
_start:
    # start in Real Mode
    .code16
    # Disable interrupts for obvious reasons
    cli
    # Zero out the data segment and stack segment in preparation
    # for a new GDT that will redefine those segments for protected
    # mode
    xorw %ax, %ax
    movw %ax, %ds
    movw %ax, %es
    movw %ax, %ss
    # Set address line 20 high so we can access 1MB and above
    seta20p1:
    inb     $0x64,%al               # Wait for not busy
    testb   $0x2,%al
    jnz     seta20p1

    movb    $0xd1,%al               # 0xd1 -> port 0x64
    outb    %al,$0x64

    seta20p2:
    inb     $0x64,%al               # Wait for not busy
    testb   $0x2,%al
    jnz     seta20p2

    movb    $0xdf,%al               # 0xdf -> port 0x60
    outb    %al,$0x60
    # Switch from real to protected mode, using a GDT that
    # does an identity mapping
    lgdt    gdtdesc
    movl    %cr0, %eax
    orl     $CR0_PE, %eax
    movl    %eax, %cr0
    # Enter protected mode with a long jump,
    # which will reset cs and eip
    ljmp    $KERNEL_CS, $start32
.code32
start32:
    movw $KERNEL_DS, %ax
    movw %ax, %ds
    movw %ax, %es
    movw %ax, %ss
    xorw %ax, %ax

    # set up stack 
    movl $(stack + 4096), %esp

    call main
#The above should never return, but in case it does
spin:
    jmp spin

.align 4
# bootstrap gdt that overlaps code and data and identity maps
gdt:
    SEGMENT_NULL                        # GDT must begin with null descriptor
    SEGMENT(SEG_X|SEG_R, 0, 0xffffffff) # code segment
    SEGMENT(SEG_W, 0, 0xffffffff)       # data segment

# GDT descriptor that is loaded onto gdtr
gdtdesc:
    .word (gdtdesc-gdt-1) #sideof(gdt) - 1
    .long gdt             # pointer to gdt

.comm stack, 4096
I understand most everything above, and I borrowed heavily from xv6, but I don't get what's wrong. Does anyone know what's up?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Trying to get into protected mode, getting relocation er

Post by Combuster »

You can use multiboot images directly with QEMU, which means you should not use 16-bit code. You can also roll your entire boot loader, which means you have to write a dedicated bootsector with the relevant boot signature that contains the loading code for a different binary, and no multiboot header.

At the very least, your visible problems are coming from the fact that you told gcc that the bootsector should go in a different place than where it would actually go on a real system. But since your design is fundamentally flawed in the first place, I recommend that you drop this code, decide what you actually want, and then follow the appropriate Tutorials first
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
mango
Posts: 8
Joined: Sun May 25, 2014 6:36 pm

Re: Trying to get into protected mode, getting relocation er

Post by mango »

I began writing this OS to get a better understanding of the boot process, so I'm a little lost here. I've never had problems booting from QEMU, I just specify --kernel and boot from the .bin image. I googled around to find more info about the QEMU loader, but I can't seem to find anything useable. I know that GRUB gaurantees protected mode and line A20 up after entering the kernel, but I don't know this about QEMU. What about this is wrong specifically?
Octocontrabass
Member
Member
Posts: 5604
Joined: Mon Mar 25, 2013 7:01 pm

Re: Trying to get into protected mode, getting relocation er

Post by Octocontrabass »

mango wrote:I borrowed heavily from xv6
mango wrote:What about this is wrong specifically?
Xv6 boots directly from the BIOS. The BIOS is not Multiboot. Compare this to this.
mango
Posts: 8
Joined: Sun May 25, 2014 6:36 pm

Re: Trying to get into protected mode, getting relocation er

Post by mango »

Ah, thank you! I changed the code to:

Code: Select all

#include "mmu.h"

.align 4
.text
.global multiboot_header
multiboot_header:
    #define magic 0x1badb002
    #define flags 0
    .long magic
    .long flags
    .long -(magic+flags)

.global _start
_start:
    # Disable interrupts for obvious reasons
    cli
    # does an identity mapping
    lgdt    gdtdesc
    # Enter protected mode with a long jump,
    # which will reset cs and eip
    ljmp    $KERNEL_CS, $gdt_loaded
gdt_loaded:
    movw $KERNEL_DS, %bx
    movw %bx, %ds
    movw %bx, %es
    movw %bx, %ss
    xorw %bx, %ax

    # set up stack 
    movl $(stack + 4096), %esp

    pushl %eax
    call main
#The above should never return, but in case it does
spin:
    jmp spin

.align 4
# bootstrap gdt that overlaps code and data and identity maps
gdt:
    SEGMENT_NULL                        # GDT must begin with null descriptor
    SEGMENT(SEG_X|SEG_R, 0, 0xffffffff) # code segment
    SEGMENT(SEG_W, 0, 0xffffffff)       # data segment

# GDT descriptor that is loaded onto gdtr
gdtdesc:
    .word (gdtdesc-gdt-1) #sideof(gdt) - 1
    .long gdt             # pointer to gdt

.comm stack, 4096
and it boots again, but when I examine the argument to main in the c code, it is != 0x2badb002. What else is wrong? The QEMU docs say that the -kernel flag requires a multi boot kernel, so I assume boot would break, but it doesn't
User avatar
ScropTheOSAdventurer
Member
Member
Posts: 86
Joined: Sun Aug 25, 2013 5:47 pm
Location: Nebraska, USA

Re: Trying to get into protected mode, getting relocation er

Post by ScropTheOSAdventurer »

You do that XOR with bx and ax. That messes it up.

EDIT: Why are you doing that xor anyways? Curious.
"Procrastination is the art of keeping up with yesterday."
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: Trying to get into protected mode, getting relocation er

Post by Bender »

ScropTheOSAdventurer wrote:You do that XOR with bx and ax. That messes it up.

EDIT: Why are you doing that xor anyways? Curious.
If I'm correct he's probably trying to zero out BX. It's a "shorter" operation (as in size), XOR R32, R32 is only 2-bytes whereas MOV R32, IMM takes 5 bytes. However XOR uses 4 (? idk) NAND gates and it's a complicated operation while AND uses 2. AND R32, 0 can also be used to zero a register. Please note that both XOR and AND thrash (E/R)FLAGS.
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Trying to get into protected mode, getting relocation er

Post by Combuster »

The propagation delay of one gate of AND or the three of XOR reduced to the three primary ones, is totally irrelevant compared to all the other administration the processor has to perform. The correct answer is that XOR reg, reg (or SUB reg, reg) takes the least possible bytes to encode. AND can't do that, MOV can't do that.
idk
Better not to post in such a situation.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: Trying to get into protected mode, getting relocation er

Post by Bender »

*Embarrassment*
Yes, Combuster is right. AND R32, IMM takes 4 bytes (x86-32) while XOR R32, R32 takes only 2 bytes which makes XOR a better choice. Heck, even GCC uses XOR R, R with -O2. (Confused AND R32, IMM with AND R32, R32). Though I'd still say on a "hypothetical" machine where instructions are of the same length AND will be faster than XOR. (Even though negligible)
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
Octocontrabass
Member
Member
Posts: 5604
Joined: Mon Mar 25, 2013 7:01 pm

Re: Trying to get into protected mode, getting relocation er

Post by Octocontrabass »

Bender wrote:Though I'd still say on a "hypothetical" machine where instructions are of the same length AND will be faster than XOR. (Even though negligible)
Every CPU I know of can do AND, XOR, ADD, and SUB in one cycle each. Your hypothetical CPU's clock speed would have to be very high for the propagation delay of a few transistors to warrant an extra cycle for one ALU operation over another. I'd really like to see your CPU in action!

On a side note, Sandy Bridge skips the ALU entirely if you're using SUB or XOR to zero a register. It's such a small optimization, I have to wonder if it makes a difference anywhere outside of benchmarks.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Trying to get into protected mode, getting relocation er

Post by Owen »

Octocontrabass wrote:
Bender wrote:Though I'd still say on a "hypothetical" machine where instructions are of the same length AND will be faster than XOR. (Even though negligible)
Every CPU I know of can do AND, XOR, ADD, and SUB in one cycle each. Your hypothetical CPU's clock speed would have to be very high for the propagation delay of a few transistors to warrant an extra cycle for one ALU operation over another. I'd really like to see your CPU in action!

On a side note, Sandy Bridge skips the ALU entirely if you're using SUB or XOR to zero a register. It's such a small optimization, I have to wonder if it makes a difference anywhere outside of benchmarks.
It renames out the register to the special zero rename-register and breaks the dependency chain. It's a pretty important one. They've been doing it for years.
Post Reply