[SOLVED] Far jump in Bochs

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
Vanzef
Posts: 9
Joined: Mon Jul 29, 2013 11:45 am

[SOLVED] Far jump in Bochs

Post by Vanzef »

Hello, everybody!

I lost the fight with Grub2 http://forum.osdev.org/viewtopic.php?f=1&t=26967 :D So, I decided to roll my own bootloader for my custom kernel. As base I chose Linux kernel v0.01.

Here is a code of my bootloader:

Code: Select all

 
    .set    BOOTSEG, 0x7c0
    .set    LOADSEG, 0x9000
    .set    SYSSEG, 0x1000

start:
//copy the WHOLE bootloader to new location
    movw    BOOTSEG, %ax
    movw    %ax, %ds
    xor     %si, %si
    movw    LOADSEG, %ax
    movw    %ax, %es
    xor     %di, %di
    movw    256, %cx
    rep     movsw

//jump to new location
//enable A20
//    in      $0x70, %al
//    or      $0x2, %al
//    out     %al, $0x70

    movw    LOADSEG, %ax
    movw    %ax, %es
    ljmp      %es:loaded
//    pushw   LOADSEG
//    pushw   loaded
//    ret

loaded:
    jmp .
//set up data and stack
    movw    %cs, %ax        /*save new location*/
    movw    %ax, %ds        /*data segment starts here (cs)*/
    movw    %ax, %es
    movw    %ax, %ss        /*stack also starts there (cs)*/
    movw    $513, %sp       /*stack size > 512, not to clear our program)*/

//clear screen
    movw    $0x3, %ax
    int     $0x10

//print message
    pushw   msg
    pushw   $0xa
    call    print_msg

//load kernel to 0x10000
load_kernel:
    xor     %dx, %dx
    xor     %ah, %ah
    int     $0x13
    jc      reboot

    movw    SYSSEG, %ax
    movw    %ax, %es
    movb    $0x2, %ah
    movb    $1, %al
    movw    $0x1, %cx
    xor     %dx, %dx
    movw    $0x0, %bx
    int     $0x13
    jc      reboot

move_kernel:
    cli
    xor     %ax, %ax
    movw    %ax, %ds
    movl    $0x9000, %esi
    movw    %ax, %es
    movl    $0x0, %edi
    movl    (move_kernel_end-move_kernel), %ecx
    rep movsb
    sti
    jmp     $0x0
move_kernel_end:

print_msg:
//print message
    popw    %ax
    popw    %cx
    popw    %bp
    pushw   %ax
    movb    $0x04, %bl
    movb    $0x13, %ah
    movb    $0x1, %al
    int     $0x10
    ret

msg:
    .string "Booting..."

gdt_unreal:
    .quad   0x0

    .byte   0x0
    .byte   0b11001111
    .byte   0b10011010
    .byte   0x0
    .word   0x0
    .word   0xffff

    .byte   0x0
    .byte   0b11001111
    .byte   0b10010010
    .byte   0x0
    .word   0x0
    .word   0xffff
gdtr_unreal:
    .long   gdt_unreal
    .word   23

reboot:
    pushw   $0xdead
    pushw   $0x8
    call    print_msg

    .fill   510-(. - start), 1, 0
    .byte   0x55
    .byte   0xaa
I am using Bochs 2.6 with GDB-stub to run this code. So, it crashes while I wnat to jump to new location (%es:loaded).

Code: Select all

    movw    LOADSEG, %ax
    movw    %ax, %es
    ljmp      %es:loaded
Bochs output:

Code: Select all

[MEM0 ]   allocted_block: block=0x1 used 0x3 of of 0x200
[CPU0 ]   prefetch: EIP [00010000] > CS.limit [0000ffff]
[GDBST]   stopped with ac0
As I understood, Bochs says to me that I want jump to memory, which is higher than 1MiB. But 0x9000 is lower than 0xffff, isn't it? As I asid, the base was the Linux kernel v 0.01, Linus use `jmpi go, INITSEG` instruction to jump. Yasm doesn't undestand that instuction, so I use `ljmp` instead of it.

Question:
1) Is using `ljmp` instead of `jmpi` correct or not?
2) Why Bochs said that destination address is higher than 1MiB?

Thanks!
Last edited by Vanzef on Thu Aug 15, 2013 1:24 am, edited 1 time in total.
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Far jump in Bochs

Post by HugeCode »

Problem seems to be in your jump. I think that something like segreg:offset isn't actually allowed.
There are only two forms of far jump: absolute and absolute indirect. For direct jump, absolute immediate address (segment, offset) must be specified. Indirect jump gets new EIP value from address encoded with instruction. In think that your compiler uses indirect jump.

To solve your problem, you should try to use

Code: Select all

ljmp LOADSEG, $loaded
I'm not very familiar with AT&T.

About your error message, I can't see lgdt or switching to pmode anywhere, so it's difficult to explain why is your checked.
Vanzef
Posts: 9
Joined: Mon Jul 29, 2013 11:45 am

Re: Far jump in Bochs

Post by Vanzef »

Thanks, HugeCode!
I tryied

Code: Select all

ljmp $LOADSEG, $loaded
And it works!
Post Reply