• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1FILE_LICENCE ( GPL2_OR_LATER )
2
3#define BOOT_SEG	0x07c0
4#define EXEC_SEG	0x0100
5#define STACK_SEG 	0x0200
6#define STACK_SIZE	0x2000
7
8	.text
9	.arch i386
10	.section ".prefix", "awx", @progbits
11	.code16
12
13/*
14 * Find active partition
15 *
16 * Parameters:
17 *   %dl	: BIOS drive number
18 *   %bp	: Active partition handler routine
19 */
20find_active_partition:
21	/* Set up stack at STACK_SEG:STACK_SIZE */
22	movw	$STACK_SEG, %ax
23	movw	%ax, %ss
24	movw	$STACK_SIZE, %sp
25
26	/* Relocate self to EXEC_SEG */
27	pushw	$BOOT_SEG
28	popw	%ds
29	pushw	$EXEC_SEG
30	popw	%es
31	xorw	%si, %si
32	xorw	%di, %di
33	movw	$0x200, %cx
34	rep movsb
35	ljmp	$EXEC_SEG, $1f
361:	pushw	%ds
37	popw	%es
38	pushw	%cs
39	popw	%ds
40
41	/* Check for LBA extensions */
42	movb	$0x41, %ah
43	movw	$0x55aa, %bx
44	stc
45	int	$0x13
46	jc	1f
47	cmpw	$0xaa55, %bx
48	jne	1f
49	movw	$read_lba, read_sectors
501:
51	/* Read and process root partition table */
52	xorb	%dh, %dh
53	movw	$0x0001, %cx
54	xorl	%esi, %esi
55	xorl	%edi, %edi
56	call	process_table
57
58	/* Print failure message */
59	movw	$10f, %si
60	jmp	boot_error
6110:	.asciz	"Could not locate active partition\r\n"
62
63/*
64 * Print failure message and boot next device
65 *
66 * Parameters:
67 *   %si	: Failure string
68 */
69boot_error:
70	cld
71	movw	$0x0007, %bx
72	movb	$0x0e, %ah
731:	lodsb
74	testb	%al, %al
75	je	99f
76	int	$0x10
77	jmp	1b
7899:	/* Boot next device */
79	int	$0x18
80
81/*
82 * Process partition table
83 *
84 * Parameters:
85 *   %dl	: BIOS drive number
86 *   %dh	: Head
87 *   %cl	: Sector (bits 0-5), high two bits of cylinder (bits 6-7)
88 *   %ch	: Low eight bits of cylinder
89 *   %esi:%edi	: LBA address
90 *   %bp	: Active partition handler routine
91 *
92 * Returns:
93 *   CF set on error
94 */
95process_table:
96	pushal
97	call	read_boot_sector
98	jc	99f
99	movw	$446, %bx
1001:	call	process_partition
101	addw	$16, %bx
102	cmpw	$510, %bx
103	jne	1b
10499:	popal
105	ret
106
107/*
108 * Process partition
109 *
110 * Parameters:
111 *   %dl	: BIOS drive number
112 *   %dh	: Head
113 *   %cl	: Sector (bits 0-5), high two bits of cylinder (bits 6-7)
114 *   %ch	: Low eight bits of cylinder
115 *   %esi:%edi	: LBA address
116 *   %bx	: Offset within partition table
117 *   %bp	: Active partition handler routine
118 */
119process_partition:
120	pushal
121	/* Load C/H/S values from partition entry */
122	movb	%es:1(%bx), %dh
123	movw	%es:2(%bx), %cx
124	/* Update LBA address from partition entry */
125	addl	%es:8(%bx), %edi
126	adcl	$0, %esi
127	/* Check active flag */
128	testb	$0x80, %es:(%bx)
129	jz	1f
130	call	read_boot_sector
131	jc	99f
132	jmp	*%bp
1331:	/* Check for extended partition */
134	movb	%es:4(%bx), %al
135	cmpb	$0x05, %al
136	je	2f
137	cmpb	$0x0f, %al
138	je	2f
139	cmpb	$0x85, %al
140	jne	99f
1412:	call	process_table
14299:	popal
143	/* Reload original partition table */
144	call	read_boot_sector
145	ret
146
147/*
148 * Read single sector to %es:0000 and verify 0x55aa signature
149 *
150 * Parameters:
151 *   %dl	: BIOS drive number
152 *   %dh	: Head
153 *   %cl	: Sector (bits 0-5), high two bits of cylinder (bits 6-7)
154 *   %ch	: Low eight bits of cylinder
155 *   %esi:%edi	: LBA address
156 *
157 * Returns:
158 *   CF set on error
159 */
160read_boot_sector:
161	pushw	%ax
162	movw	$1, %ax
163	call	*read_sectors
164	jc	99f
165	cmpw	$0xaa55, %es:(510)
166	je	99f
167	stc
16899:	popw	%ax
169	ret
170
171/*
172 * Read sectors to %es:0000
173 *
174 * Parameters:
175 *   %dl	: BIOS drive number
176 *   %dh	: Head
177 *   %cl	: Sector (bits 0-5), high two bits of cylinder (bits 6-7)
178 *   %ch	: Low eight bits of cylinder
179 *   %esi:%edi	: LBA address
180 *   %ax	: Number of sectors (max 127)
181 *
182 * Returns:
183 *   CF set on error
184 */
185read_sectors:	.word	read_chs
186
187read_chs:
188	/* Read sectors using C/H/S address */
189	pushal
190	xorw	%bx, %bx
191	movb	$0x02, %ah
192	stc
193	int	$0x13
194	sti
195	popal
196	ret
197
198read_lba:
199	/* Read sectors using LBA address */
200	pushal
201	movw	%ax, (lba_desc + 2)
202	pushw	%es
203	popw	(lba_desc + 6)
204	movl	%edi, (lba_desc + 8)
205	movl	%esi, (lba_desc + 12)
206	movw	$lba_desc, %si
207	movb	$0x42, %ah
208	int	$0x13
209	popal
210	ret
211
212lba_desc:
213	.byte	0x10
214	.byte	0
215	.word	1
216	.word	0x0000
217	.word	0x0000
218	.long	0, 0
219