简体   繁体   English

装配麻烦:创建一个Bootloader

[英]Trouble with Assembly: Creating a Bootloader

I just started an Operating Systems class and have run into a wall on the infamous bootloader lab. 我刚刚启动了一个操作系统类,并在臭名昭着的bootloader实验室中遇到了障碍。 One part of the assignment is to create a 512-byte bootloader in Assembly capable of loading a given kernel, more or less from scratch. 分配的一部分是在Assembly中创建一个512字节的引导加载程序,能够从头开始或多或少地加载给定的内核。 Here's the code I've worked on so far: 这是我到目前为止所做的代码:

# bootblock.s

# .equ symbol, expression
# These directives set the value of the symbol to the expression

.equ    BOOT_SEGMENT,0x07c0

.equ    DISPLAY_SEGMENT,0xb800

.text               # Code segment

.globl    _start    # The entry point must be global

.code16             # Real mode


# Start

_start:

    jmp over


# OS Size

os_size:
    # Area reserved for createimage to write the OS size

    .word   0

    .word   0


# Routines to print a zero terminated string pointed to by esi
# Overwrites:   AX, DS, BX

print:

    movw  $BOOT_SEGMENT,%ax
    movw  %ax,%ds

print_loop:

    lodsb
    cmpb  $0,%al
    je  print_done
    movb  $14,%ah
    movl  $0x0002,%ebx
    int  $0x10
    jmp  print_loop

print_done:

    retw


# Over is where the magic happens

over:


    movl $messagetest, %esi
    call print
    movl $hellostring, %esi
    call print

    # Allocating the stack
    movw $0x0, %ax
    movw %ax, %ss
    movw $0xffff, %sp

    # Booting up at 0x07c0
    movw $BOOT_SEGMENT, %ax
    movw %ax, %ds
    movl $messageboot, %esi
    call print

    # Resetting the disk drive, setting %dl and calling int 0x13
    movb $0x0, %ah
    movb $0x80, %dl
    int $0x13

    # Make says my .os_size = 9 sectors. Setting %al = 9
    movb $0x09, %al

    # %cl controls which sector to read from. Setting %cl = 2
    movb $0x02, %cl 

    # %dh/%ch control head numbers. I'm not sure how they work; setting them to zero
    movb $0x0, %dh
    movb $0x0, %ch

    # Setting the drive number to 0x80 (Hard drive)
    movb $0x80, %dl

    # Time to set es:bx to read from the correct place (0:1000)
    movw $0x0, %bx
    movw %bx, %es
    movw $0x1000, %bx

    # Setting %ah = 2 and calling int 0x13 again (Read Sectors)
    movb $0x02, %ah
    int $0x13

    # Setting %ds = 0. I don't think it can be done directly.
    movw $0x0, %ax
    movw %ax, %ds

    # Kernel jump
    movl $messageready, %esi
    call print
    ljmp $0x1000, $0x0

    # Displaying error message, if any
    movl $messageerror, %esi
    call print


# Rebooting the OS

reboot:

    movl $messagereboot, %esi
    call print
    movb $0, %ah
    int $0x16
    movb $0, %ah
    int $0x19


# Infinite loop 

forever:

    hlt
    jmp forever


# Error handling

error:

    movl $messageerror, %esi
    call print


# Test messages

hellostring:

    .asciz  "Hi Professor.\n\n\r"

messagetest:

    .asciz "\nTesting Bootblock!\n\r"

messageboot:

    .asciz "Booting up... \n\r "

messageready:

    .asciz "\b>> Jumping into the Kernel... \n\r"

messagereboot:

    .asciz "Press any key to reboot the OS!\n\r"

messageerror:

    .asciz "Unknown error!\n\r"

Now, my code prints all of the messages it is supposed to, but when it is time to jump into the kernel, it's clearly just not doing it properly (the kernel doesn't display a confirmation message). 现在,我的代码打印了它应该的所有消息,但是当它是时候跳进内核时,它显然没有正确地执行它(内核不显示确认消息)。

My code compiles, but I feel there must be an error somewhere either in: 我的代码编译,但我觉得必须在某处出现错误:

  1. How I allocate stack space, or 我如何分配堆栈空间,或
  2. How I set registers before calling INT 0x13 如何在调用INT 0x13之前设置寄存器

Can anyone help me out by telling me what's wrong? 谁能告诉我什么是错的,可以帮助我吗?

You are apparently loading the code at address 0:0x1000 ( es=0 , bx=0x1000 ) but jumping to 0x1000:0 ( ljmp $0x1000, $0x0 ). 您显然在地址0:0x1000处加载代码0:0x1000es=0bx=0x1000 )但跳转到0x1000:0ljmp $0x1000, $0x0 )。 That won't work since the first is physical address 0x1000 but the second is 0x10000 (because in real mode you have to multiply segment by 16). 这不起作用,因为第一个是物理地址0x1000但第二个是0x10000(因为在实模式中你必须将段乘以16)。 Make them match. 让它们匹配。

There may be other errors, learn to use a debugger or you'll be asking for help every minute. 可能存在其他错误,学习使用调试器或者您每分钟都会寻求帮助。

Also, please keep the formatting such that we can easily copy-paste the whole code for testing ourselves (or provide a pastebin link too). 另外,请保留格式,以便我们可以轻松地复制粘贴整个代码以进行自我测试(或者也提供一个pastebin链接)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM