Compare commits
3 Commits
50b0413483
...
e4ed65b897
Author | SHA1 | Date |
---|---|---|
Bananymous | e4ed65b897 | |
Bananymous | 75579f15d4 | |
Bananymous | fbe75b6d63 |
|
@ -60,8 +60,6 @@ stage2_main:
|
|||
call get_memory_map
|
||||
call read_user_command_line
|
||||
|
||||
call vesa_find_video_mode
|
||||
|
||||
call print_newline
|
||||
|
||||
movw $start_kernel_load_msg, %si
|
||||
|
@ -84,7 +82,7 @@ stage2_main:
|
|||
|
||||
call elf_read_kernel_to_memory
|
||||
|
||||
call vesa_set_target_mode
|
||||
call vesa_set_video_mode
|
||||
|
||||
cli
|
||||
|
||||
|
|
|
@ -1,20 +1,72 @@
|
|||
.set TARGET_WIDTH, 800
|
||||
.set TARGET_HEIGHT, 600
|
||||
.set TARGET_BPP, 32
|
||||
|
||||
.code16
|
||||
.section .stage2
|
||||
|
||||
# Find suitable video mode
|
||||
# kernel framebuffer information format
|
||||
# .align 8
|
||||
# .long 0xBABAB007
|
||||
# .long -(0xBABAB007 + width + height + bpp)
|
||||
# .long width (2 bytes used, 4 bytes for ease of calculation)
|
||||
# .long height (2 bytes used, 4 bytes for ease of calculation)
|
||||
# .long bpp (1 bytes used, 4 bytes for ease of calculation)
|
||||
|
||||
# scan memory 0x100000 -> 0x200000 for framebuffer information
|
||||
# return:
|
||||
# ax: video mode number if found, 0 otherwise
|
||||
.global vesa_find_video_mode
|
||||
# ax: target width
|
||||
# bx: target height
|
||||
# cx: target bpp
|
||||
vesa_scan_kernel_image:
|
||||
pushl %edx
|
||||
pushl %esi
|
||||
|
||||
movl $0x100000, %esi
|
||||
|
||||
.vesa_scan_kernel_image_loop:
|
||||
# check magic
|
||||
cmpl $0xBABAB007, (%esi)
|
||||
jne .vesa_scan_kernel_image_next_addr
|
||||
|
||||
# check checksum
|
||||
movl 0x00(%esi), %edx
|
||||
addl 0x04(%esi), %edx
|
||||
addl 0x08(%esi), %edx
|
||||
addl 0x0C(%esi), %edx
|
||||
addl 0x10(%esi), %edx
|
||||
testl %edx, %edx
|
||||
jnz .vesa_scan_kernel_image_next_addr
|
||||
|
||||
# set return registers
|
||||
movw 0x08(%esi), %ax
|
||||
movw 0x0C(%esi), %bx
|
||||
movw 0x10(%esi), %cx
|
||||
jmp .vesa_scan_kernel_image_done
|
||||
|
||||
.vesa_scan_kernel_image_next_addr:
|
||||
addl $8, %esi
|
||||
cmpl $0x200000, %esi
|
||||
jb .vesa_scan_kernel_image_loop
|
||||
|
||||
# zero out return registers
|
||||
xorw %ax, %ax
|
||||
xorw %bx, %bx
|
||||
xorw %cx, %cx
|
||||
|
||||
.vesa_scan_kernel_image_done:
|
||||
popl %esi
|
||||
popl %edx
|
||||
ret
|
||||
|
||||
# Find suitable video mode and save it in (vesa_target_mode)
|
||||
vesa_find_video_mode:
|
||||
pushw %ax
|
||||
pushw %bx
|
||||
pushw %cx
|
||||
pushw %di
|
||||
pushl %esi
|
||||
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
subl $6, %esp
|
||||
|
||||
# clear target mode and frame buffer
|
||||
movw $0, (vesa_target_mode)
|
||||
movl $0, (framebuffer + 0)
|
||||
|
@ -23,6 +75,15 @@ vesa_find_video_mode:
|
|||
movl $0, (framebuffer + 12)
|
||||
movw $0, (framebuffer + 16)
|
||||
|
||||
call vesa_scan_kernel_image
|
||||
testw %ax, %ax
|
||||
jz .vesa_find_video_mode_loop_modes_done
|
||||
|
||||
# save arguments in stack
|
||||
movw %ax, -2(%ebp)
|
||||
movw %bx, -4(%ebp)
|
||||
movw %cx, -6(%ebp)
|
||||
|
||||
# get vesa information
|
||||
movw $0x4F00, %ax
|
||||
movw $vesa_info_buffer, %di
|
||||
|
@ -57,22 +118,25 @@ vesa_find_video_mode:
|
|||
jz .vesa_find_video_mode_next_mode
|
||||
|
||||
# compare mode's dimensions
|
||||
cmpw $TARGET_WIDTH, (vesa_mode_info_buffer + 0x12)
|
||||
movw -2(%ebp), %ax; cmpw %ax, (vesa_mode_info_buffer + 0x12)
|
||||
jne .vesa_find_video_mode_next_mode
|
||||
cmpw $TARGET_HEIGHT, (vesa_mode_info_buffer + 0x14)
|
||||
movw -4(%ebp), %ax; cmpw %ax, (vesa_mode_info_buffer + 0x14)
|
||||
jne .vesa_find_video_mode_next_mode
|
||||
cmpb $TARGET_BPP, (vesa_mode_info_buffer + 0x19)
|
||||
movb -6(%ebp), %al; cmpb %al, (vesa_mode_info_buffer + 0x19)
|
||||
jne .vesa_find_video_mode_next_mode
|
||||
|
||||
# set address, pitch, type
|
||||
movl (vesa_mode_info_buffer + 0x28), %esi
|
||||
movl %esi, (framebuffer + 0)
|
||||
movw (vesa_mode_info_buffer + 0x10), %ax
|
||||
movw %ax, (framebuffer + 4)
|
||||
movl $TARGET_WIDTH, (framebuffer + 8)
|
||||
movl $TARGET_HEIGHT, (framebuffer + 12)
|
||||
movb $TARGET_BPP, (framebuffer + 16)
|
||||
movb $1, (framebuffer + 17)
|
||||
|
||||
# set width, height, bpp
|
||||
movw -2(%ebp), %ax; movw %ax, (framebuffer + 8)
|
||||
movw -4(%ebp), %ax; movw %ax, (framebuffer + 12)
|
||||
movw -6(%ebp), %ax; movb %al, (framebuffer + 16)
|
||||
|
||||
movw %cx, (vesa_target_mode)
|
||||
jmp .vesa_find_video_mode_loop_modes_done
|
||||
|
||||
|
@ -81,9 +145,11 @@ vesa_find_video_mode:
|
|||
jmp .vesa_find_video_mode_loop_modes
|
||||
|
||||
.vesa_find_video_mode_loop_modes_done:
|
||||
leavel
|
||||
popl %esi
|
||||
popw %di
|
||||
popw %cx
|
||||
popw %bx
|
||||
popw %ax
|
||||
ret
|
||||
|
||||
|
@ -98,13 +164,16 @@ vesa_find_video_mode:
|
|||
jmp print_and_halt
|
||||
|
||||
|
||||
# set mode found from vesa_find_video_mode. if no mode
|
||||
# was found, set it to 80x25 text mode to clear the screen.
|
||||
.global vesa_set_target_mode
|
||||
vesa_set_target_mode:
|
||||
# scan for video mode in kernel memory and set the correct one.
|
||||
# when video mode is not found or does not exists,
|
||||
# set it to 80x25 text mode to clear the screen.
|
||||
.global vesa_set_video_mode
|
||||
vesa_set_video_mode:
|
||||
pushw %ax
|
||||
pushw %bx
|
||||
|
||||
call vesa_find_video_mode
|
||||
|
||||
movw (vesa_target_mode), %bx
|
||||
testw %bx, %bx
|
||||
jz .vesa_set_target_mode_generic
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
.set PG_READ_WRITE, 1<<1
|
||||
.set PG_PAGE_SIZE, 1<<7
|
||||
|
||||
.set FB_WIDTH, 800
|
||||
.set FB_HEIGHT, 600
|
||||
.set FB_BPP, 32
|
||||
|
||||
#define KERNEL_OFFSET 0xFFFFFFFF80000000
|
||||
#define V2P(vaddr) ((vaddr) - KERNEL_OFFSET)
|
||||
|
||||
|
@ -9,8 +13,8 @@
|
|||
|
||||
# multiboot2 header
|
||||
.section .multiboot, "aw"
|
||||
multiboot2_start:
|
||||
.align 8
|
||||
multiboot2_start:
|
||||
.long 0xE85250D6
|
||||
.long 0
|
||||
.long multiboot2_end - multiboot2_start
|
||||
|
@ -21,9 +25,9 @@ multiboot2_start:
|
|||
.short 5
|
||||
.short 0
|
||||
.long 20
|
||||
.long 800
|
||||
.long 600
|
||||
.long 32
|
||||
.long FB_WIDTH
|
||||
.long FB_HEIGHT
|
||||
.long FB_BPP
|
||||
|
||||
# legacy start
|
||||
.align 8
|
||||
|
@ -38,6 +42,16 @@ multiboot2_start:
|
|||
.long 8
|
||||
multiboot2_end:
|
||||
|
||||
.section .bananboot, "aw"
|
||||
.align 8
|
||||
bananboot_start:
|
||||
.long 0xBABAB007
|
||||
.long -(0xBABAB007 + FB_WIDTH + FB_HEIGHT + FB_BPP)
|
||||
.long FB_WIDTH
|
||||
.long FB_HEIGHT
|
||||
.long FB_BPP
|
||||
bananboot_end:
|
||||
|
||||
.section .bss, "aw", @nobits
|
||||
# Create stack
|
||||
.global g_boot_stack_bottom
|
||||
|
|
|
@ -11,6 +11,7 @@ SECTIONS
|
|||
{
|
||||
g_kernel_execute_start = .;
|
||||
*(.multiboot)
|
||||
*(.bananboot)
|
||||
*(.text.*)
|
||||
}
|
||||
.userspace ALIGN(4K) : AT(ADDR(.userspace) - KERNEL_OFFSET)
|
||||
|
|
Loading…
Reference in New Issue