mbr.s revision 62146
1239324Simp#
2239324Simp# Copyright (c) 1999 Robert Nordier
3239324Simp# All rights reserved.
4239324Simp#
5239324Simp# Redistribution and use in source and binary forms are freely
6239324Simp# permitted provided that the above copyright notice and this
7239324Simp# paragraph and the following disclaimer are duplicated in all
8239324Simp# such forms.
9239324Simp#
10239324Simp# This software is provided "AS IS" and without any express or
11239324Simp# implied warranties, including, without limitation, the implied
12239324Simp# warranties of merchantability and fitness for a particular
13239324Simp# purpose.
14239324Simp#
15239324Simp
16239324Simp# $FreeBSD: head/sys/boot/i386/mbr/mbr.s 62146 2000-06-26 23:58:04Z jhb $
17239324Simp
18239324Simp# A 512 byte MBR boot manager that simply boots the active partition.
19239324Simp
20239324Simp		.set LOAD,0x7c00		# Load address
21239324Simp		.set EXEC,0x600 		# Execution address
22239324Simp		.set PT_OFF,0x1be		# Partition table
23266328Sian		.set MAGIC,0xaa55		# Magic: bootable
24239324Simp
25239324Simp		.set NDRIVE,0x8 		# Drives to support
26239324Simp
27266328Sian		.globl start			# Entry point
28266328Sian		.code16
29266328Sian
30266328Sian#
31266328Sian# Setup the segment registers for flat addressing and setup the stack.
32266328Sian#
33266328Sianstart:		cld				# String ops inc
34266328Sian		xorw %ax,%ax			# Zero
35239324Simp		movw %ax,%es			# Address
36239324Simp		movw %ax,%ds			#  data
37266328Sian		cli				# Disable interrupts
38266328Sian		movw %ax,%ss			# Set up
39266328Sian		movw $LOAD,%sp			#  stack
40266328Sian		sti				# Enable interrupts
41239324Simp#
42239324Simp# Relocate ourself to a lower address so that we are out of the way when
43239324Simp# we load in the bootstrap from the partition to boot.
44266328Sian#
45266328Sian		movw $main-EXEC+LOAD,%si	# Source
46266328Sian		movw $main,%di			# Destination
47266328Sian		movw $0x200-(main-start),%cx	# Byte count
48266328Sian		rep				# Relocate
49266328Sian		movsb				#  code
50266328Sian#
51266328Sian# Jump to the relocated code.
52266328Sian#
53266328Sian		jmp main-LOAD+EXEC		# To relocated code
54266328Sian#
55266328Sian# Scan the partition table looking for an active entry.  Note that %ch is
56266328Sian# zero from the repeated string instruction above.  We save the offset of
57239324Simp# the active partition in %si and scan the entire table to ensure that only
58239324Simp# one partition is marked active.
59239324Simp#
60239324Simpmain:		xorw %si,%si			# No active partition
61239324Simp		movw $partbl,%bx		# Partition table
62239324Simp		movb $0x4,%cl			# Number of entries
63239324Simpmain.1: 	cmpb %ch,(%bx)			# Null entry?
64239324Simp		je main.2			# Yes
65239324Simp		jg err_pt			# If 0x1..0x7f
66239324Simp		testw %si,%si	 		# Active already found?
67239324Simp		jnz err_pt			# Yes
68239324Simp		movw %bx,%si			# Point to active
69239324Simpmain.2: 	addb $0x10,%bl			# Till
70239324Simp		loop main.1			#  done
71239324Simp		testw %si,%si	 		# Active found?
72239324Simp		jnz main.3			# Yes
73239324Simp		int $0x18			# BIOS: Diskless boot
74239324Simp#
75239324Simp# Ok, we've found a possible active partition.  Check to see that the drive
76239324Simp# is a valid hard drive number.  XXX - We assume that there are up to 8 valid
77266328Sian# hard drives, regardless of how many are actually installed.  Yuck.
78266328Sian#
79266328Sianmain.3: 	cmpb $0x80,%dl			# Drive valid?
80266328Sian		jb main.4			# No
81266328Sian		cmpb $0x80+NDRIVE,%dl		# Within range?
82239324Simp		jb main.5			# Yes
83239324Simp#
84239324Simp# Ok, now that we have a valid drive and partition entry, load the CHS from
85239324Simp# the partition entry and read the sector from the disk.
86239324Simp#
87239324Simpmain.4: 	movb (%si),%dl			# Load drive
88239324Simpmain.5: 	movb 0x1(%si),%dh		# Load head
89239324Simp		movw 0x2(%si),%cx		# Load cylinder:sector
90239324Simp		movw $LOAD,%bx			# Transfer buffer
91239324Simp		movw $0x201,%ax			# BIOS: Read from
92239324Simp		int $0x13			#  disk
93239324Simp		jc err_rd			# If error
94239324Simp#
95239324Simp# Now that we've loaded the bootstrap, check for the 0xaa55 signature.  If it
96239324Simp# is present, execute the bootstrap we just loaded.
97239324Simp#
98266328Sian		cmpw $MAGIC,0x1fe(%bx)		# Bootable?
99266328Sian		jne err_os			# No
100266328Sian		jmp *%bx			# Invoke bootstrap
101266328Sian#
102239324Simp# Various error message entry points.
103266328Sian#
104266328Sianerr_pt: 	movw $msg_pt,%si		# "Invalid partition
105266328Sian		jmp putstr			#  table"
106266328Sian
107239324Simperr_rd: 	movw $msg_rd,%si		# "Error loading
108239324Simp		jmp putstr			#  operating system"
109266328Sian
110266328Sianerr_os: 	movw $msg_os,%si		# "Missing operating
111266328Sian		jmp putstr			#  system"
112266328Sian#
113# Output an ASCIZ string to the console via the BIOS.
114#
115putstr.0:	movw $0x7,%bx	 		# Page:attribute
116		movb $0xe,%ah			# BIOS: Display
117		int $0x10			#  character
118putstr: 	lodsb				# Get character
119		testb %al,%al			# End of string?
120		jnz putstr.0			# No
121putstr.1:	jmp putstr.1			# Await reset
122
123msg_pt: 	.asciz "Invalid partition table"
124msg_rd: 	.asciz "Error loading operating system"
125msg_os: 	.asciz "Missing operating system"
126
127		.org PT_OFF
128
129partbl: 	.fill 0x10,0x4,0x0		# Partition table
130		.word MAGIC			# Magic number
131