Added active partition locator, and simple MBR built using it.
[people/xl0/gpxe-arm.git] / src / arch / i386 / prefix / bootpart.S
1 #define BOOT_SEG        0x07c0
2 #define EXEC_SEG        0x0100
3 #define STACK_SEG       0x0200
4 #define STACK_SIZE      0x2000
5         
6         .text
7         .arch i386
8         .section ".prefix", "awx", @progbits
9         .code16
10
11 /*
12  * Find active partition
13  *
14  * Parameters:
15  *   %dl        : BIOS drive number
16  *   %bp        : Active partition handler routine
17  */
18 find_active_partition:
19         /* Set up stack at STACK_SEG:STACK_SIZE */
20         movw    $STACK_SEG, %ax
21         movw    %ax, %ss
22         movw    $STACK_SIZE, %sp
23         /* Relocate self to EXEC_SEG */
24         pushw   $BOOT_SEG
25         popw    %ds
26         pushw   $EXEC_SEG
27         popw    %es
28         xorw    %si, %si
29         xorw    %di, %di
30         movw    $0x200, %cx
31         rep movsb
32         ljmp    $EXEC_SEG, $1f
33 1:      pushw   %ds
34         popw    %es
35         pushw   %cs
36         popw    %ds
37         /* Read and process root partition table */
38         xorb    %dh, %dh
39         movw    $0x0001, %cx
40         xorl    %esi, %esi
41         xorl    %edi, %edi
42         call    process_table
43         /* Print failure message */
44         movw    $10f, %si
45         movw    $(20f-10f), %cx
46 1:      movw    $0x0007, %bx
47         movb    $0x0e, %ah
48         lodsb
49         int     $0x10
50         loop    1b
51         /* Boot next device */
52         int     $0x18
53 10:     .ascii  "Could not locate active partition\r\n"
54 20:     
55
56 /*
57  * Process partition table
58  *
59  * Parameters:
60  *   %dl        : BIOS drive number
61  *   %dh        : Head
62  *   %cl        : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
63  *   %ch        : Low eight bits of cylinder
64  *   %esi:%edi  : LBA address
65  *   %bp        : Active partition handler routine
66  *
67  * Returns:
68  *   CF set on error
69  */
70 process_table:
71         pushal
72         movw    $446, %bx
73 1:      call    read_sector
74         jc      99f
75         call    process_partition
76         addw    $16, %bx
77         cmpw    $510, %bx
78         jne     1b
79 99:     popal
80         ret
81
82 /*
83  * Process partition
84  *
85  * Parameters:
86  *   %dl        : BIOS drive number
87  *   %dh        : Head
88  *   %cl        : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
89  *   %ch        : Low eight bits of cylinder
90  *   %esi:%edi  : LBA address
91  *   %bx        : Offset within partition table
92  *   %bp        : Active partition handler routine
93  */
94 process_partition:
95         pushal
96         /* Load C/H/S values from partition entry */
97         movb    %es:1(%bx), %dh
98         movw    %es:2(%bx), %cx
99         /* Update LBA address from partition entry */
100         addl    %es:8(%bx), %edi
101         adcl    $0, %esi
102         /* Check active flag */
103         testb   $0x80, %es:(%bx)
104         jz      1f
105         call    read_sector
106         jc      99f
107         jmp     *%bp
108 1:      /* Check for extended partition */
109         movb    %es:4(%bx), %al
110         cmpb    $0x05, %al
111         je      2f
112         cmpb    $0x0f, %al
113         je      2f
114         cmpb    $0x85, %al
115         jne     99f
116 2:      call    process_table
117 99:     popal
118         ret
119
120 /*
121  * Read single sector to 0000:7c00 and verify 0x55aa signature
122  *
123  * Parameters:
124  *   %dl        : BIOS drive number
125  *   %dh        : Head
126  *   %cl        : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
127  *   %ch        : Low eight bits of cylinder
128  *   %esi:%edi  : LBA address
129  *
130  * Returns:
131  *   CF set on error
132  */
133 read_sector:
134         pushal
135         /* Check for LBA extensions */
136         call    check_lba
137         jnc     read_lba
138 read_chs:
139         /* Read sector using C/H/S address */
140         movw    $0x0201, %ax
141         xorw    %bx, %bx
142         stc
143         int     $0x13
144         sti
145         jmp     99f
146 read_lba:
147         /* Read sector using LBA address */
148         movb    $0x42, %ah
149         movl    %esi, (lba_desc + 12)
150         movl    %edi, (lba_desc + 8)
151         movw    $lba_desc, %si
152         int     $0x13
153 99:     /* Check for 55aa signature */
154         jc      99f
155         cmpw    $0xaa55, %es:(510)
156         je      99f
157         stc
158 99:     popal
159         ret
160
161 lba_desc:
162         .byte   0x10
163         .byte   0
164         .word   1
165         .word   0x0000
166         .word   0x07c0
167         .long   0, 0
168
169 /*
170  * Check for LBA extensions
171  *      
172  * Parameters:
173  *   %dl        : BIOS drive number
174  *
175  * Returns:
176  *   CF clear if LBA extensions supported
177  */
178 check_lba:
179         pushal
180         movb    $0x41, %ah
181         movw    $0x55aa, %bx
182         stc
183         int     $0x13
184         jc      99f
185         cmpw    $0xaa55, %bx
186         je      99f
187         stc
188 99:     popal
189         ret