|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/bsp/boot/x86/tools/bootsect/bootsect.S/* [<][>][^][v][top][bottom][index][help] */1 /*- 2 * Copyright (c) 2005, Kohsuke Ohtani 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of any co-contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /** 31 * bootsect.S - Boot sector for FAT 32 * 33 * The boot sector is 512 byte code to load the OS image. It is loaded 34 * to address 0:7c00 by POST BIOS. 35 * The boot sector searches the target file within the root directory of 36 * FAT file system, and loads it to predefined memory address. Then, it 37 * jumps to the first byte of the loaded image. 38 * 39 * All disk access are done by using BIOS Int13h interface. The BIOS 40 * parameter block (BPB) has the disk/FAT information, and it exists 41 * in the first portion of the FAT boot sector. It must be filled by the 42 * FAT format utility, or the prex kernel install utility (mkboot.com). 43 * This program assumes that correct BPB is stored in the boot sector. 44 * 45 * Limitation: 46 * - Support only FAT12/16. FAT32 is not supported. 47 * 48 * Memory usage: 49 * > 5000 - 6FFF ... Disk work area 50 * > 7000 - 7BFF ... Stack 51 * > 7C00 - 7DFF ... This boot sector 52 * >10000 - ... FAT cache 53 * >20000 - ... Data cache 54 * >30000 - ... Image load address 55 */ 56 .code16 57 .text 58 .align 1 59 60 # Memory locations 61 #define BOOT_STACK 0x7c00 62 63 #define LOAD_ADDR 0x30000 64 #define ENTRY_SEG 0x3000 65 #define ENTRY_OFF 0x0000 66 67 #define WORK_AREA 0x5000 68 #define FAT_SEG 0x1000 69 #define DATA_SEG 0x2000 70 71 #define LOAD_MAX 0xA0000 72 73 # FAT Directory entry 74 #define F_NAME 0 75 #define F_ATTR 11 76 #define F_RESERVED 12 77 #define F_TIME 22 78 #define F_DATA 24 79 #define F_CLUSTER 26 80 #define F_SIZE 28 81 82 #define DIR_SIZE 32 83 #define DIRENT_PER_SECTOR 16 84 85 # BIOS parameter block (BPB) location (%bp points to 0x7c00) 86 #define OEM_ID 0x03(%bp) 87 #define BYTE_PER_SECTOR 0x0b(%bp) 88 #define SECT_PER_CLUSTER 0x0d(%bp) 89 #define RESERVED_SECTORS 0x0e(%bp) 90 #define NUM_OF_FATS 0x10(%bp) 91 #define ROOT_ENTRIES 0x11(%bp) 92 #define TOTAL_SECTORS 0x13(%bp) 93 #define MEDIA_DESCRIPTOR 0x15(%bp) 94 #define SECTORS_PER_FAT 0x16(%bp) 95 #define SECTORS_PER_TRACK 0x18(%bp) 96 #define HEADS 0x1a(%bp) 97 #define HIDDEN_SECTORS 0x1c(%bp) 98 #define BIG_TOTAL_SECTORS 0x20(%bp) 99 #define PHYSICAL_DRIVE 0x24(%bp) 100 #define EXT_BOOT_SIGNATURE 0x26(%bp) 101 #define SERIAL_NO 0x27(%bp) 102 #define VOLUME_ID 0x2b(%bp) 103 #define FILE_SYS_ID 0x36(%bp) 104 105 #define FILE_SYS_ID_NUM 0x3a(%bp) 106 107 # Local data area (Note: These data will overlap the existing code) 108 #define FAT_START 0x40(%bp) 109 #define DATA_START 0x44(%bp) 110 111 .global _boot 112 113 # 114 # Boot the system 115 # 116 _boot: 117 jmp start # Skip BPB 118 nop # Nop is for DOS compatibility 119 120 # 121 # BPB 122 # 123 .ascii "PREX1.00" 124 .fill 0x33, 1, 0 # Drive parameter must be 125 # filled by intaller 126 127 # 128 # Setup stack and segment registers 129 # 130 start: 131 cli 132 cld # Clear direction flag 133 xorl %eax, %eax # Set EAX to zero 134 movw %ax, %ds 135 movw %ax, %es 136 movw %ax, %ss 137 movw $(BOOT_STACK), %sp 138 movw %sp, %bp # EBP = Bios Parameter Block 139 sti 140 141 # 142 # Display boot message 143 # 144 movw $load_msg, %si 145 movw $21, %cx 146 call puts 147 148 # 149 # Store disk information 150 # 151 movl HIDDEN_SECTORS, %ebx # Get hidden sector 152 movw RESERVED_SECTORS, %ax # Add reserved sector 153 addl %eax, %ebx # High 16 bit of EAX is 0 154 movl %ebx, FAT_START # FAT start = hidden + reserved 155 156 movzbw NUM_OF_FATS, %ax # Normally 2 157 mulw SECTORS_PER_FAT # AX = Num of sector of FATs 158 addl %ebx, %eax # EAX = Start of root directory 159 160 movw ROOT_ENTRIES, %bx 161 shrw $4, %bx # / 16 = DIRENT_PER_SECTOR 162 movw %bx, %cx # CX = Num of sectors for root directory 163 164 addl %eax, %ebx # DATA start = FAT start + root 165 movl %ebx, DATA_START # Start sector of data area 166 167 # 168 # Find the OS image in the root directory 169 # 170 # EAX = Start sector of root 171 next_sector: 172 pushw %cx 173 movl $(WORK_AREA), %ebx 174 pushw %bx 175 call read_sector # Read 1 sector in root 176 popw %di # DI = dir_entry 177 movw $(DIRENT_PER_SECTOR), %cx # CX = directory count 178 next_entry: 179 cmpb $0, (%di) # End of dir entry ? 180 je error # Not found 181 testb $0x18, F_ATTR(%di) # Subdir or Volume ? 182 jnz not_file # Skip it 183 pusha 184 movw $11, %cx # File name + ext = 11 byte 185 movw $image_name, %si 186 repe # Compare file name 187 cmpsb 188 popa 189 je found_file 190 not_file: 191 addw $(DIR_SIZE), %di # Check next directory entry 192 loop next_entry 193 popw %cx 194 loop next_sector 195 # Fall through 196 # 197 # Error case 198 # 199 error: 200 movw $err_msg, %si 201 movw $5, %cx 202 call puts 203 hang: 204 hlt 205 jmp hang # Stop here 206 207 # 208 # Load image 209 # 210 found_file: 211 movzwl F_CLUSTER(%di), %eax # EAX = 1st cluster of loader 212 movl $(LOAD_ADDR), %ebx # EBX = 32bit load address 213 load_next: 214 call read_cluster # Read cluster of loader 215 call next_cluster # Get next cluster# in EAX 216 jb load_next # EOF ? 217 218 # 219 # Turn fdd motor off 220 # 221 movw $0x3f2, %dx 222 xorb %al, %al 223 outb %al, %dx 224 225 # 226 # Jump to loaded image 227 # 228 ljmp $0x3000, $0x0 229 230 # 231 # Puts - Print string 232 # 233 # Entry: 234 # SI - Pointer to message string 235 # CX - Number of character 236 # 237 puts: 238 lodsb 239 movb $0x0e, %ah 240 movw $0x0007, %bx 241 int $0x10 242 loop puts 243 ret 244 245 # 246 # next_cluster - Return next cluster 247 # 248 # Entry: 249 # EAX - Current cluter# 250 # 251 # Exit: 252 # AF - End of cluster 253 # EAX - Next cluter# 254 # 255 # Modified: 256 # Flags,CX,EDX,SI,DI 257 # 258 next_cluster: 259 pushl %ebx 260 movw %ax, %di # Save cluster# in DI 261 262 movw $0xfff8, %si # Set default EOF to FAT16 263 264 movl %eax, %ecx 265 shll $1, %eax # * 2 266 267 cmpb $0x36, FILE_SYS_ID_NUM # ID is 'FAT16' ? 268 je fat_16 269 addl %ecx, %eax # * 3 270 shrl $1, %eax # / 2 271 movw $0xff8, %si # EOF for FAT12 272 fat_16: 273 # EAX - Offset of FAT entry 274 xorw %dx, %dx 275 divw BYTE_PER_SECTOR 276 addl FAT_START, %eax # EAX = Sector# for FAT 277 # DX = Offset in sector 278 movl $(WORK_AREA), %ebx 279 pushw %bx 280 call read_sector # Read 2 sector for border 281 call read_sector # data 282 popw %bx 283 addw %dx, %bx 284 movw (%bx), %ax 285 cmpw $0xfff8, %si # FAT16 ? 286 je chk_end 287 288 shrw $1, %di 289 jc odd_pos 290 andb $0x0f, %ah 291 jmp chk_end 292 odd_pos: 293 shrw $4, %ax 294 chk_end: 295 cmpw %si, %ax 296 popl %ebx 297 ret 298 299 # 300 # read_cluster - Read one cluster 301 # 302 # Entry: 303 # EBX - 32-bit pointer to buffer 304 # EAX - Cluster number 305 # 306 # Exit: 307 # EBX - Point to next buffer 308 # 309 # Modified: 310 # flags,ECX,ECX,EDX 311 # 312 read_cluster: 313 pushl %eax 314 decw %ax # Translate clust# to sec# 315 decw %ax 316 xorl %ecx, %ecx 317 movb SECT_PER_CLUSTER, %cl 318 mull %ecx 319 addl DATA_START, %eax # EAX = Read sec# 320 # CX = Read sector size 321 read_loop: 322 call read_sector 323 cmpl $(LOAD_MAX), %ebx 324 jae error 325 loop read_loop 326 popl %eax 327 ret 328 329 # 330 # read_sector - Read one sector 331 # 332 # Entry: 333 # EBX - 32-bit pointer to buffer 334 # EAX - Logical sector# to read 335 # 336 # Exit: 337 # EBX - Pointer to next buffer 338 # EAX - Next sector 339 # 340 # Modified: 341 # Flags 342 # 343 read_sector: 344 pushal 345 pushw %ds 346 pushw %es 347 348 movl %eax, %esi # ESI = buffer 349 350 movzwl SECTORS_PER_TRACK, %ecx # Get sec/track 351 xorl %edx, %edx 352 divl %ecx # EAX = track# 353 # DX = sec# 354 movw $(DATA_SEG), %cx # Check in cache 355 leaw last_data, %di 356 cmpl DATA_START, %esi 357 jae data_reqest 358 movw $(FAT_SEG), %cx 359 leaw last_fat, %di 360 data_reqest: 361 # CX = Cached segment 362 pushal # [DI] = Cached track 363 movw %cx, %es 364 xorw %bx, %bx # ES:BX = Cache address 365 cmpl (%di), %eax # Last track ? 366 je hit_cache 367 movl %eax, (%di) # Save current track# 368 call read_track 369 hit_cache: 370 popal 371 372 pushw %es 373 popw %ds 374 375 shlw $9, %dx # sec# * 512 376 movw %dx, %si # DS:SI = Offset in cache 377 378 movw %bx, %di # [EBX] -> ES:[DI] 379 andw $0xf, %di 380 shrl $4, %ebx 381 movw %bx, %es 382 383 mov $512, %cx # Copy 1 sector 384 rep 385 movsb 386 387 popw %es 388 popw %ds 389 popal 390 391 addl $512, %ebx # Next buffer 392 incl %eax # Next sector 393 ret 394 395 # 396 # read_track - Read one track 397 # 398 # Entry: 399 # ES:[BX] - Pointer to buffer 400 # EAX - Track number to read 401 # 402 # Exit: 403 # None 404 # 405 # Modified: 406 # Flags,EAX,ECX,EDX 407 # 408 read_track: 409 movzwl HEADS, %ecx # Get num of head 410 xorl %edx, %edx 411 divl %ecx # AX = cyl# 412 # DL = head# 413 414 movb %al, %ch # CH = cyl# (low 8 bits) 415 andb $3, %ah 416 shlb $6, %ah 417 orb $1, %ah 418 movb %ah, %cl # CL[7:6] = cyl# (high 2 bits) 419 # CL[5:0] = sec# = 1 420 movb %dl, %dh # DH = Head# 421 movw SECTORS_PER_TRACK, %ax # AL = Num of sectors to read 422 movb $2, %ah # AH = 02h (Read Disk Sectors) 423 movb PHYSICAL_DRIVE, %dl # DL = Drive# 424 int $0x13 # Invoke Disk BIOS 425 jc error 426 ret 427 428 # 429 # Local Data 430 # 431 last_fat: .long 0xffffffff 432 last_data: .long 0xffffffff 433 434 load_msg: .ascii "Loading " 435 image_name: .ascii "PREXOS " 436 crlf: .byte 0x0a, 0x0d 437 err_msg: .ascii "Error" 438 439 .org 510 440 .word 0xaa55 /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |