📄 startup.s
字号:
call prot_to_real /* enter real mode */ .code16 movb $0x1, %ah int $0x16 jz notpending movw %ax, %dx DATA32 jmp pendingnotpending: decl %edxpending: DATA32 call real_to_prot .code32 movl %edx, %eax popl %ebp ret /* * grub_uint16_t grub_console_getxy (void) * BIOS call "INT 10H Function 03h" to get cursor position * Call with %ah = 0x03 * %bh = page * Returns %ch = starting scan line * %cl = ending scan line * %dh = row (0 is top) * %dl = column (0 is left) */FUNCTION(grub_console_getxy) pushl %ebp pushl %ebx /* save EBX */ call prot_to_real .code16 xorb %bh, %bh /* set page to 0 */ movb $0x3, %ah int $0x10 /* get cursor position */ DATA32 call real_to_prot .code32 movb %dl, %ah movb %dh, %al popl %ebx popl %ebp ret/* * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y) * BIOS call "INT 10H Function 02h" to set cursor position * Call with %ah = 0x02 * %bh = page * %dh = row (0 is top) * %dl = column (0 is left) */FUNCTION(grub_console_gotoxy) pushl %ebp pushl %ebx /* save EBX */ movb %dl, %dh /* %dh = y */ movb %al, %dl /* %dl = x */ call prot_to_real .code16 xorb %bh, %bh /* set page to 0 */ movb $0x2, %ah int $0x10 /* set cursor position */ DATA32 call real_to_prot .code32 popl %ebx popl %ebp ret /* * void grub_console_cls (void) * BIOS call "INT 10H Function 09h" to write character and attribute * Call with %ah = 0x09 * %al = (character) * %bh = (page number) * %bl = (attribute) * %cx = (number of times) */FUNCTION(grub_console_cls) pushl %ebp pushl %ebx /* save EBX */ call prot_to_real .code16 /* move the cursor to the beginning */ movb $0x02, %ah xorb %bh, %bh xorw %dx, %dx int $0x10 /* write spaces to the entire screen */ movw $0x0920, %ax movw $0x07, %bx movw $(80 * 25), %cx int $0x10 /* move back the cursor */ movb $0x02, %ah int $0x10 DATA32 call real_to_prot .code32 popl %ebx popl %ebp ret /* * void grub_console_setcursor (int on) * BIOS call "INT 10H Function 01h" to set cursor type * Call with %ah = 0x01 * %ch = cursor starting scanline * %cl = cursor ending scanline */console_cursor_state: .byte 1console_cursor_shape: .word 0 FUNCTION(grub_console_setcursor) pushl %ebp pushl %ebx /* push ON */ pushl %eax /* check if the standard cursor shape has already been saved */ movw console_cursor_shape, %ax testw %ax, %ax jne 1f call prot_to_real .code16 movb $0x03, %ah xorb %bh, %bh int $0x10 DATA32 call real_to_prot .code32 movw %cx, console_cursor_shape1: /* set %cx to the designated cursor shape */ movw $0x2000, %cx popl %eax testl %eax, %eax jz 2f movw console_cursor_shape, %cx2: call prot_to_real .code16 movb $0x1, %ah int $0x10 DATA32 call real_to_prot .code32 popl %ebx popl %ebp ret /* * grub_getrtsecs() * if a seconds value can be read, read it and return it (BCD), * otherwise return 0xFF * BIOS call "INT 1AH Function 02H" to check whether a character is pending * Call with %ah = 0x2 * Return: * If RT Clock can give correct values * %ch = hour (BCD) * %cl = minutes (BCD) * %dh = seconds (BCD) * %dl = daylight savings time (00h std, 01h daylight) * Carry flag = clear * else * Carry flag = set * (this indicates that the clock is updating, or * that it isn't running) */FUNCTION(grub_getrtsecs) pushl %ebp call prot_to_real /* enter real mode */ .code16 clc movb $0x2, %ah int $0x1a DATA32 jnc gottime movb $0xff, %dhgottime: DATA32 call real_to_prot .code32 movb %dh, %al popl %ebp ret /* * grub_get_rtc() * return the real time in ticks, of which there are about * 18-20 per second */FUNCTION(grub_get_rtc) pushl %ebp call prot_to_real /* enter real mode */ .code16 /* %ax is already zero */ int $0x1a DATA32 call real_to_prot .code32 movl %ecx, %eax shll $16, %eax movw %dx, %ax popl %ebp ret/* * unsigned char grub_vga_set_mode (unsigned char mode) */FUNCTION(grub_vga_set_mode) pushl %ebp pushl %ebx movl %eax, %ecx call prot_to_real .code16 /* get current mode */ xorw %bx, %bx movb $0x0f, %ah int $0x10 movb %al, %dl /* set the new mode */ movb %cl, %al xorb %ah, %ah int $0x10 DATA32 call real_to_prot .code32 movb %dl, %al popl %ebx popl %ebp ret/* * unsigned char *grub_vga_get_font (void) */FUNCTION(grub_vga_get_font) pushl %ebp pushl %ebx call prot_to_real .code16 movw $0x1130, %ax movb $0x06, %bh int $0x10 movw %es, %bx movw %bp, %dx DATA32 call real_to_prot .code32 movzwl %bx, %ecx shll $4, %ecx movw %dx, %ax addl %ecx, %eax popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info) * * Register allocations for parameters: * %eax *controller_info */FUNCTION(grub_vbe_get_controller_info) pushl %ebp pushl %edi movw %ax, %di /* Store *controller_info to %edx:%di. */ xorw %ax, %ax shrl $4, %eax mov %eax, %edx /* prot_to_real destroys %eax. */ call prot_to_real .code16 pushw %es movw %dx, %es /* *controller_info is now on %es:%di. */ movw $0x4f00, %ax int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ popw %es DATA32 call real_to_prot .code32 movl %edx, %eax andl $0x0FFFF, %eax /* Return value in %eax. */ popl %edi popl %ebp ret/* * grub_vbe_status_t grub_vbe_get_mode_info (grub_uint32_t mode, * struct grub_vbe_mode_info_block *mode_info) * * Register allocations for parameters: * %eax mode * %edx *mode_info */FUNCTION(grub_vbe_get_mode_info) pushl %ebp pushl %edi movl %eax, %ecx /* Store mode number to %ecx. */ movw %dx, %di /* Store *mode_info to %edx:%di. */ xorw %dx, %dx shrl $4, %edx call prot_to_real .code16 pushw %es movw %dx, %es /* *mode_info is now on %es:%di. */ movw $0x4f01, %ax int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ popw %es DATA32 call real_to_prot .code32 movl %edx, %eax andl $0x0FFFF, %eax /* Return value in %eax. */ popl %edi popl %ebp ret/* * grub_vbe_status_t grub_vbe_set_mode (grub_uint32_t mode, * struct grub_vbe_crtc_info_block *crtc_info) * * Register allocations for parameters: * %eax mode * %edx *crtc_info */FUNCTION(grub_vbe_set_mode) pushl %ebp pushl %ebx movl %eax, %ebx /* Store mode in %ebx. */ movw %dx, %di /* Store *crtc_info to %edx:%di. */ xorw %dx, %dx shrl $4, %edx call prot_to_real .code16 pushw %es movw %dx, %es /* *crtc_info is now on %es:%di. */ movw $0x4f02, %ax int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ popw %es DATA32 call real_to_prot .code32 movw %dx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_get_mode (grub_uint32_t *mode) * * Register allocations for parameters: * %eax *mode */FUNCTION(grub_vbe_get_mode) pushl %ebp pushl %ebx pushl %eax /* Push *mode to stack. */ call prot_to_real .code16 movw $0x4f03, %ax int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ DATA32 call real_to_prot .code32 popl %edi /* Pops *mode from stack to %edi. */ andl $0xFFFF, %ebx movl %ebx, (%edi) movw %dx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_set_memory_window (grub_uint32_t window, * grub_uint32_t position); * * Register allocations for parameters: * %eax window * %edx position */FUNCTION(grub_vbe_set_memory_window) pushl %ebp pushl %ebx movl %eax, %ebx call prot_to_real .code16 movw $0x4f05, %ax andw $0x00ff, %bx /* BL = window, BH = 0, Set memory window. */ int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ DATA32 call real_to_prot .code32 movw %dx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_get_memory_window (grub_uint32_t window, * grub_uint32_t *position); * * Register allocations for parameters: * %eax window * %edx *position */FUNCTION(grub_vbe_get_memory_window) pushl %ebp pushl %ebx pushl %edx /* Push *position to stack. */ movl %eax, %ebx /* Store window in %ebx. */ call prot_to_real .code16 movw $0x4f05, %ax andw $0x00ff, %bx /* BL = window. */ orw $0x0100, %bx /* BH = 1, Get memory window. */ int $0x10 movw %ax, %bx /* real_to_prot destroys %eax. */ DATA32 call real_to_prot .code32 popl %edi /* pops *position from stack to %edi. */ andl $0xFFFF, %edx movl %edx, (%edi) /* Return position to caller. */ movw %bx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_set_scanline_length (grub_uint32_t length) * * Register allocations for parameters: * %eax length */FUNCTION(grub_vbe_set_scanline_length) pushl %ebp pushl %ebx movl %eax, %ecx /* Store length in %ecx. */ call prot_to_real .code16 movw $0x4f06, %ax movw $0x0002, %bx /* BL = 2, Set Scan Line in Bytes. */ int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ DATA32 call real_to_prot .code32 movw %dx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_get_scanline_length (grub_uint32_t *length) * * Register allocations for parameters: * %eax *length */FUNCTION(grub_vbe_get_scanline_length) pushl %ebp pushl %ebx pushl %edx /* Push *length to stack. */ call prot_to_real .code16 movw $0x4f06, %ax movw $0x0001, %bx /* BL = 1, Get Scan Line Length (in bytes). */ int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ DATA32 call real_to_prot .code32 popl %edi /* Pops *length from stack to %edi. */ andl $0xFFFF, %ebx movl %ebx, (%edi) /* Return length to caller. */ movw %dx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_set_display_start (grub_uint32_t x, * grub_uint32_t y) * * Register allocations for parameters: * %eax x * %edx y */FUNCTION(grub_vbe_set_display_start) pushl %ebp pushl %ebx movl %eax, %ecx /* Store x in %ecx. */ call prot_to_real .code16 movw $0x4f07, %ax movw $0x0080, %bx /* BL = 80h, Set Display Start during Vertical Retrace. */ int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ DATA32 call real_to_prot .code32 movw %dx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_get_display_start (grub_uint32_t *x, * grub_uint32_t *y) * * Register allocations for parameters: * %eax *x * %edx *y */FUNCTION(grub_vbe_get_display_start) pushl %ebp pushl %ebx pushl %eax /* Push *x to stack. */ pushl %edx /* Push *y to stack. */ call prot_to_real .code16 movw $0x4f07, %ax movw $0x0001, %bx /* BL = 1, Get Display Start. */ int $0x10 movw %ax, %bx /* real_to_prot destroys %eax. */ DATA32 call real_to_prot .code32 popl %edi /* Pops *y from stack to %edi. */ andl $0xFFFF, %edx movl %edx, (%edi) /* Return y-position to caller. */ popl %edi /* Pops *x from stack to %edi. */ andl $0xFFFF, %ecx movl %ecx, (%edi) /* Return x-position to caller. */ movw %bx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret/* * grub_vbe_status_t grub_vbe_set_palette_data (grub_uint32_t color_count, * grub_uint32_t start_index, * struct grub_vbe_palette_data *palette_data) * * Register allocations for parameters: * %eax color_count * %edx start_index * %ecx *palette_data */FUNCTION(grub_vbe_set_palette_data) pushl %ebp pushl %ebx movl %eax, %ebx /* Store color_count in %ebx. */ movw %cx, %di /* Store *palette_data to %ecx:%di. */ xorw %cx, %cx shrl $4, %ecx call prot_to_real .code16 pushw %es movw %cx, %es /* *palette_data is now on %es:%di. */ movw %bx, %cx /* color_count is now on %cx. */ movw $0x4f09, %ax xorw %bx, %bx /* BL = 0, Set Palette Data. */ int $0x10 movw %ax, %dx /* real_to_prot destroys %eax. */ popw %es DATA32 call real_to_prot .code32 movw %dx, %ax andl $0xFFFF, %eax /* Return value in %eax. */ popl %ebx popl %ebp ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -