/* -*-Asm-*- */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #include #include #include #include #include .file "cdboot.S" #define CODE_ADDR 0x6000 #define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200) #define CDSEC_SHIFT 11 #define CDBLK_LENG 16 .text .code16 .globl start, _start start: _start: call LOCAL(next) LOCAL(next): jmp 1f . = start + 8 bi_pvd: .long 0 /* LBA of primary volume descriptor. */ bi_file: .long 0 /* LBA of boot file. */ bi_length: .long 0 /* Length of boot file. */ bi_csum: .long 0 /* Checksum of boot file */ bi_reserved: .space (10*4) /* Reserved */ 1: popw %bx /* Boot from CDROM. */ xorw %ax, %ax movw %ax, %ss movw $(CODE_ADDR), %sp movw %ax, %ds movw %ax, %es movw $(0x7C00 + err_noboot_msg - start), %si movl %cs: bi_length - LOCAL(next)(%bx), %ecx orl %ecx, %ecx jz LOCAL(fail) addl $((1 << CDSEC_SHIFT) - 1), %ecx shrl $CDSEC_SHIFT, %ecx movl %cs: bi_file - LOCAL(next)(%bx), %esi call LOCAL(read_cdrom) ljmp $(DATA_ADDR >> 4), $0 /* * Parameters: * esi: start sector * ecx: number of sectors */ LOCAL(read_cdrom): xorl %eax, %eax /* Number of blocks to read. */ pushw $CDBLK_LENG /* Block number. */ pushl %eax pushl %esi /* Buffer address. */ pushw $((DATA_ADDR - 0x400)>> 4) pushl %eax pushw $0x10 xorl %edi, %edi movw %sp, %si 1: movw 0x10(%si), %di cmpl %ecx, %edi jbe 2f movl %ecx, %edi 2: mov %di, 2(%si) pushl %ecx movb $0x42, %ah int $0x13 jnc 3f movb $0x42, %ah /* Try again. */ int $0x13 jnc 3f 2: shrw $1, %di /* Reduce transfer size. */ jz LOCAL(cdrom_fail) movw %di, 0x10(%si) movw %di, 2(%si) movb $0x42, %ah int $0x13 jc 2b 3: movw %di, %ax shlw $(CDSEC_SHIFT - 4), %ax addw %ax, 6(%si) addl %edi, 8(%si) popl %ecx subl %edi, %ecx jnz 1b addw $0x12, %sp ret LOCAL(cdrom_fail): movw $(0x7C00 + err_cdfail_msg - start), %si LOCAL(fail): movb $0x0e, %ah xorw %bx, %bx 1: lodsb (%si), %al int $0x10 cmpb $0, %al jne 1b 1: jmp 1b err_noboot_msg: .ascii "no boot info\0" err_cdfail_msg: .ascii "cdrom read fails\0" . = start + 0x1FF .byte 0