Added a gcc compilable MBR code - borrowed from FreeBSD. For later use with
the writembr utility (I was just too lazy to make it build right now). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2522 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 1999 Robert Nordier
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms are freely
|
||||||
|
** permitted provided that the above copyright notice and this
|
||||||
|
** paragraph and the following disclaimer are duplicated in all
|
||||||
|
** such forms.
|
||||||
|
**
|
||||||
|
** This software is provided "AS IS" and without any express or
|
||||||
|
** implied warranties, including, without limitation, the implied
|
||||||
|
** warranties of merchantability and fitness for a particular
|
||||||
|
** purpose.
|
||||||
|
/*
|
||||||
|
|
||||||
|
/* A 512 byte MBR boot manager that simply boots the active partition. */
|
||||||
|
|
||||||
|
.set LOAD, 0x7c00 // Load address
|
||||||
|
.set EXEC, 0x600 // Execution address
|
||||||
|
.set PT_OFF, 0x1be // Partition table
|
||||||
|
.set MAGIC, 0xaa55 // Magic: bootable
|
||||||
|
|
||||||
|
.set NUM_HARD_DRIVES, 0x475 // Number of hard drives
|
||||||
|
|
||||||
|
.globl start // Entry point
|
||||||
|
.code16
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the segment registers for flat addressing and setup the stack.
|
||||||
|
*/
|
||||||
|
start: cld // String ops inc
|
||||||
|
xorw %ax, %ax // Zero
|
||||||
|
movw %ax, %es // Address
|
||||||
|
movw %ax, %ds // data
|
||||||
|
movw %ax, %ss // Set up stack
|
||||||
|
movw $LOAD, %sp //
|
||||||
|
/*
|
||||||
|
* Relocate ourself to a lower address so that we are out of the way when
|
||||||
|
* we load in the bootstrap from the partition to boot.
|
||||||
|
*/
|
||||||
|
movw $main-EXEC+LOAD, %si // Source
|
||||||
|
movw $main, %di // Destination
|
||||||
|
movw $0x200-(main-start), %cx // Byte count
|
||||||
|
rep // Relocate code
|
||||||
|
movsb //
|
||||||
|
/*
|
||||||
|
* Jump to the relocated code.
|
||||||
|
*/
|
||||||
|
jmp main-LOAD+EXEC // Jump to relocated code
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan the partition table looking for an active entry. Note that %ch is
|
||||||
|
* zero from the repeated string instruction above. We save the offset of
|
||||||
|
* the active partition in %si and scan the entire table to ensure that only
|
||||||
|
* one partition is marked active.
|
||||||
|
*/
|
||||||
|
|
||||||
|
main: xorw %si, %si // No active partition
|
||||||
|
movw $partition_table, %bx // Partition table
|
||||||
|
movb $0x4, %cl // Number of entries
|
||||||
|
main.1: cmpb %ch, (%bx) // Null entry?
|
||||||
|
je main.2 // Yes
|
||||||
|
jg err_partition_table // If 0x1..0x7f
|
||||||
|
testw %si, %si // Active already found?
|
||||||
|
jnz err_partition_table // Yes
|
||||||
|
movw %bx, %si // Point to active
|
||||||
|
main.2: addb $0x10, %bl // Till
|
||||||
|
loop main.1 // done
|
||||||
|
testw %si, %si // Active found?
|
||||||
|
jnz main.3 // Yes
|
||||||
|
int $0x18 // BIOS: Diskless boot
|
||||||
|
/*
|
||||||
|
* Ok, we've found a possible active partition. Check to see that the drive
|
||||||
|
* is a valid hard drive number.
|
||||||
|
*/
|
||||||
|
main.3: cmpb $0x80, %dl // Drive valid?
|
||||||
|
jb main.4 // No
|
||||||
|
movb NUM_HARD_DRIVES, %dh // Calculate the highest
|
||||||
|
addb $0x80, %dh // drive number available
|
||||||
|
cmpb %dh, %dl // Within range?
|
||||||
|
jb main.5 // Yes
|
||||||
|
main.4: movb (%si), %dl // Load drive
|
||||||
|
/*
|
||||||
|
* Ok, now that we have a valid drive and partition entry, load the CHS from
|
||||||
|
* the partition entry and read the sector from the disk.
|
||||||
|
*/
|
||||||
|
main.5: movw %sp, %di // Save stack pointer
|
||||||
|
movb 0x1(%si), %dh // Load head
|
||||||
|
movw 0x2(%si), %cx // Load cylinder:sector
|
||||||
|
movw $LOAD, %bx // Transfer buffer
|
||||||
|
cmpb $0xff, %dh // Might we need to use LBA?
|
||||||
|
jnz main.7 // No.
|
||||||
|
cmpw $0xffff, %cx // Do we need to use LBA?
|
||||||
|
jnz main.7 // No.
|
||||||
|
pushw %cx // Save %cx
|
||||||
|
pushw %bx // Save %bx
|
||||||
|
movw $MAGIC, %bx // Magic
|
||||||
|
movb $0x41, %ah // BIOS: EDD extensions present?
|
||||||
|
int $0x13 //
|
||||||
|
jc main.6 // No.
|
||||||
|
cmpw $MAGIC, %bx // Magic ok?
|
||||||
|
jne main.6 // No.
|
||||||
|
testb $0x1, %cl // Packet mode present?
|
||||||
|
jz main.6 // No.
|
||||||
|
popw %bx // Restore %bx
|
||||||
|
pushl $0x0 // Set the LBA
|
||||||
|
pushl 0x8(%si) // address
|
||||||
|
pushw %es // Set the address of
|
||||||
|
pushw %bx // the transfer buffer
|
||||||
|
pushw $0x1 // Read 1 sector
|
||||||
|
pushw $0x10 // Packet length
|
||||||
|
movw %sp, %si // Packer pointer
|
||||||
|
movw $0x4200, %ax // BIOS: LBA Read from disk
|
||||||
|
jmp main.8 // Skip the CHS setup
|
||||||
|
main.6: popw %bx // Restore %bx
|
||||||
|
popw %cx // Restore %cx
|
||||||
|
main.7: movw $0x201, %ax // BIOS: Read from disk
|
||||||
|
main.8: int $0x13 // Call the BIOS
|
||||||
|
movw %di,%sp // Restore stack
|
||||||
|
jc err_loading_os // If error
|
||||||
|
/*
|
||||||
|
* Now that we've loaded the bootstrap, check for the magic 0xaa55 signature. If it
|
||||||
|
* is present, execute the bootstrap we just loaded.
|
||||||
|
*/
|
||||||
|
cmpw $MAGIC, 0x1fe(%bx) // Bootable?
|
||||||
|
jne err_missing_os // No
|
||||||
|
jmp *%bx // Invoke bootstrap
|
||||||
|
/*
|
||||||
|
* Various error message entry points.
|
||||||
|
*/
|
||||||
|
err_partition_table:
|
||||||
|
movw $msg_partition_table, %si // "Invalid partition table"
|
||||||
|
jmp putString //
|
||||||
|
|
||||||
|
err_loading_os:
|
||||||
|
movw $msg_loading_os, %si // "Error loading operating system"
|
||||||
|
jmp putString //
|
||||||
|
|
||||||
|
err_missing_os:
|
||||||
|
movw $msg_missing_os, %si // "Missing operating system"
|
||||||
|
jmp putString //
|
||||||
|
/*
|
||||||
|
* Output an ASCIZ string to the console via the BIOS.
|
||||||
|
*/
|
||||||
|
putString.0:
|
||||||
|
movw $0x7, %bx // Page:attribute
|
||||||
|
movb $0xe, %ah // BIOS: Display character
|
||||||
|
int $0x10 //
|
||||||
|
putString:
|
||||||
|
lodsb // Get character
|
||||||
|
testb %al,%al // End of string?
|
||||||
|
jnz putString.0 // No
|
||||||
|
putString.1:
|
||||||
|
jmp putString.1 // Await reset
|
||||||
|
|
||||||
|
msg_partition_table: .asciz "Invalid partition table"
|
||||||
|
msg_loading_os: .asciz "Error loading operating system"
|
||||||
|
msg_missing_os: .asciz "Missing operating system"
|
||||||
|
|
||||||
|
.org PT_OFF
|
||||||
|
|
||||||
|
partition_table:
|
||||||
|
.fill 0x10,0x4,0x0 // Partition table
|
||||||
|
.word MAGIC // Magic number
|
||||||
Reference in New Issue
Block a user