/* Segment constants */ #define BOOT_SEG 0x7C0 /* Segment we reside on startup */ #define BOOT_RELOC_SEG 0x7A0 /* Relocation segment */ /* Constants */ #define RDAR_MAGIC ">RDAR!" #define RDAR_MAGIC_LEN 6 #define BOOT_PATH "boot/biosboot.bin" #define BOOT_PATH_LEN 17 .code16 _start: /* Normalize CS + other selectors */ ljmp $BOOT_SEG,$1f 1: xor %ax, %ax mov %ax, %ss mov %ax, %gs mov %ax, %fs /* * The second stage bootloader expects to be loaded to 0x7C00 but since we are * already executing at this address we'll need to relocate ourselves first before * we clobber it. */ mov $BOOT_SEG, %ax mov %ax, %ds mov $BOOT_RELOC_SEG, %ax mov %ax, %es xor %si, %si xor %di, %di mov $0x200, %cx cld rep movsb /* Jump to our relocated self */ ljmp $BOOT_RELOC_SEG,$reloc reloc: /* Load %DS with our new segment */ mov $BOOT_RELOC_SEG, %ax mov %ax, %ds /* Save the drive number */ mov %dl, drive_num /* Set our stack */ mov $0x7C00, %sp /* Write out our boot string */ mov $boot_msg, %si call putstr /* Load two sectors */ movw $2, dap_blkcnt movl $1, dap_lba_low call disk_read_lba /* Get stage2 */ call find_stage2 /* Obtain the data offset */ mov $BOOT_SEG, %ax mov %ax, %ds add $40, %si movw (%si), %ax /* Set DS for stage 2 */ mov $BOOT_SEG<<4, %bx or %ax, %bx shr $4, %bx mov %bx, %ds /* Jump to stage 2 */ pushw $BOOT_SEG pushw %ax lret /* * Locate stage2 on the disk * * Stage 2 data descriptor is returned in %SI */ find_stage2: push %ds push %es /* Verify that magic is correct */ mov $BOOT_SEG, %ax mov %ax, %ds xor %bx, %bx /* Tracks %SI */ xor %si, %si mov $BOOT_RELOC_SEG, %ax mov %ax, %es mov $rdar_magic, %di mov $RDAR_MAGIC_LEN, %cx rep cmpsb jne .bad_magic /* Iterate every data descriptor */ clc /* Carry set if found */ 1: movw %ds:6, %cx /* Add data descriptor size */ mov %bx, %si mov %si, %dx add %cx, %bx mov $rdar_magic, %di mov $RDAR_MAGIC_LEN, %cx rep cmpsb jne .not_found /* Does the path match? */ mov %dx, %si add $8, %si mov $stage2_path, %di mov $BOOT_PATH_LEN, %cx rep cmpsb jne 1b mov %dx, %si stc pop %es pop %ds jnc .not_found ret .not_found: pop %ds mov $not_found_msg, %si call putstr 1: cli hlt jmp 1b .bad_magic: /* Restore %DS */ mov $BOOT_RELOC_SEG, %ax mov %ax, %ds mov $bad_magic_msg, %si call putstr 1: cli hlt jmp 1b /* * Read sectors from the disk */ disk_read_lba: pusha mov $dap, %si mov $0x42, %ah mov drive_num, %dl int $0x13 jc .error popa ret .error: mov $disk_err_msg, %si call putstr 1: cli hlt jmp 1b /* * Write a string to the console * * %si: String to write * * XXX: Clobbers %AL */ putstr: lodsb or %al, %al jz 1f call putchr jmp putstr 1: ret /* * Write a single character to the console * * %al: Character to write */ putchr: mov $0x0E, %ah xor %bh, %bh int $0x10 ret dap: .byte 0x10 .byte 0x00 dap_blkcnt: .word 0 dap_destptr: .word 0x7C00 dap_destseg: .word 0x0000 dap_lba_low: .long 0 dap_lba_high: .long 0 drive_num: .byte 0x00 boot_msg: .ascii "booting\r\n\0" bad_magic_msg: .ascii "bad RDAR magic\r\n\0" not_found_msg: .ascii "stage 2 not found\r\n\0" disk_err_msg: .ascii "\r\n!!!disk error!!!\r\n\0" rdar_magic: .ascii RDAR_MAGIC stage2_path: .ascii BOOT_PATH .org 510 .byte 0x55 .byte 0xAA