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:
parent
d499baecf3
commit
6fa8ddedd0
|
@ -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
|
Loading…
Reference in New Issue