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:
Axel Dörfler 2003-01-20 15:17:19 +00:00
parent d499baecf3
commit 6fa8ddedd0
1 changed files with 164 additions and 0 deletions

164
src/apps/bin/writembr/mbr.S Normal file
View File

@ -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