forked from Bananymous/banan-os
update main #1
|
@ -8,6 +8,7 @@ set(BOOTLOADER_SOURCES
|
||||||
disk.S
|
disk.S
|
||||||
elf.S
|
elf.S
|
||||||
ext2.S
|
ext2.S
|
||||||
|
framebuffer.S
|
||||||
memory_map.S
|
memory_map.S
|
||||||
utils.S
|
utils.S
|
||||||
)
|
)
|
||||||
|
|
|
@ -60,6 +60,8 @@ stage2_main:
|
||||||
call get_memory_map
|
call get_memory_map
|
||||||
call read_user_command_line
|
call read_user_command_line
|
||||||
|
|
||||||
|
call vesa_find_video_mode
|
||||||
|
|
||||||
call print_newline
|
call print_newline
|
||||||
|
|
||||||
movw $start_kernel_load_msg, %si
|
movw $start_kernel_load_msg, %si
|
||||||
|
@ -82,12 +84,7 @@ stage2_main:
|
||||||
|
|
||||||
call elf_read_kernel_to_memory
|
call elf_read_kernel_to_memory
|
||||||
|
|
||||||
# re-enter 80x25 text mode to clear screen
|
call vesa_set_target_mode
|
||||||
pushw %ax
|
|
||||||
movb $0x03, %al
|
|
||||||
movb $0x00, %ah
|
|
||||||
int $0x10
|
|
||||||
popw %ax
|
|
||||||
|
|
||||||
cli
|
cli
|
||||||
|
|
||||||
|
@ -167,5 +164,7 @@ gdtr:
|
||||||
banan_boot_info:
|
banan_boot_info:
|
||||||
boot_command_line:
|
boot_command_line:
|
||||||
.long command_line
|
.long command_line
|
||||||
|
boot_framebuffer:
|
||||||
|
.long framebuffer
|
||||||
boot_memory_map:
|
boot_memory_map:
|
||||||
.long memory_map
|
.long memory_map
|
||||||
|
|
|
@ -79,5 +79,5 @@ command_line_enter_msg:
|
||||||
command_line:
|
command_line:
|
||||||
# 100 character command line
|
# 100 character command line
|
||||||
command_line_buffer:
|
command_line_buffer:
|
||||||
.ascii "root=/dev/sda2 console=ttyS0"
|
.ascii "root=/dev/sda2"
|
||||||
.skip 100 - 28
|
.skip 100 - 28
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
.set TARGET_WIDTH, 800
|
||||||
|
.set TARGET_HEIGHT, 600
|
||||||
|
.set TARGET_BPP, 32
|
||||||
|
|
||||||
|
.code16
|
||||||
|
.section .stage2
|
||||||
|
|
||||||
|
# Find suitable video mode
|
||||||
|
# return:
|
||||||
|
# ax: video mode number if found, 0 otherwise
|
||||||
|
.global vesa_find_video_mode
|
||||||
|
vesa_find_video_mode:
|
||||||
|
pushw %ax
|
||||||
|
pushw %cx
|
||||||
|
pushw %di
|
||||||
|
pushl %esi
|
||||||
|
|
||||||
|
# clear target mode and frame buffer
|
||||||
|
movw $0, (vesa_target_mode)
|
||||||
|
movl $0, (framebuffer + 0)
|
||||||
|
movl $0, (framebuffer + 4)
|
||||||
|
movl $0, (framebuffer + 8)
|
||||||
|
movl $0, (framebuffer + 12)
|
||||||
|
movw $0, (framebuffer + 16)
|
||||||
|
|
||||||
|
# get vesa information
|
||||||
|
movw $0x4F00, %ax
|
||||||
|
movw $vesa_info_buffer, %di
|
||||||
|
int $0x10
|
||||||
|
cmpb $0x4F, %al; jne .vesa_unsupported
|
||||||
|
cmpb $0x00, %ah; jne .vesa_error
|
||||||
|
|
||||||
|
# confirm that response starts with 'VESA'
|
||||||
|
cmpl $0x41534556, (vesa_info_buffer)
|
||||||
|
jne .vesa_error
|
||||||
|
|
||||||
|
# confirm that version is atleast 2.0
|
||||||
|
cmpw $0x0200, (vesa_info_buffer + 0x04)
|
||||||
|
jb .vesa_unsupported_version
|
||||||
|
|
||||||
|
movl $(vesa_info_buffer + 0x0E), %esi
|
||||||
|
movl (%esi), %esi
|
||||||
|
.vesa_find_video_mode_loop_modes:
|
||||||
|
cmpw $0xFFFF, (%esi)
|
||||||
|
je .vesa_find_video_mode_loop_modes_done
|
||||||
|
|
||||||
|
# get info of next mode
|
||||||
|
movw $0x4F01, %ax
|
||||||
|
movw (%esi), %cx
|
||||||
|
movw $vesa_mode_info_buffer, %di
|
||||||
|
int $0x10
|
||||||
|
cmpb $0x4F, %al; jne .vesa_unsupported
|
||||||
|
cmpb $0x00, %ah; jne .vesa_error
|
||||||
|
|
||||||
|
# check whether in graphics mode
|
||||||
|
testb $0x10, (vesa_mode_info_buffer + 0)
|
||||||
|
jz .vesa_find_video_mode_next_mode
|
||||||
|
|
||||||
|
# compare mode's dimensions
|
||||||
|
cmpw $TARGET_WIDTH, (vesa_mode_info_buffer + 0x12)
|
||||||
|
jne .vesa_find_video_mode_next_mode
|
||||||
|
cmpw $TARGET_HEIGHT, (vesa_mode_info_buffer + 0x14)
|
||||||
|
jne .vesa_find_video_mode_next_mode
|
||||||
|
cmpb $TARGET_BPP, (vesa_mode_info_buffer + 0x19)
|
||||||
|
jne .vesa_find_video_mode_next_mode
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
movw %cx, (vesa_target_mode)
|
||||||
|
jmp .vesa_find_video_mode_loop_modes_done
|
||||||
|
|
||||||
|
.vesa_find_video_mode_next_mode:
|
||||||
|
addl $2, %esi
|
||||||
|
jmp .vesa_find_video_mode_loop_modes
|
||||||
|
|
||||||
|
.vesa_find_video_mode_loop_modes_done:
|
||||||
|
popl %esi
|
||||||
|
popw %di
|
||||||
|
popw %cx
|
||||||
|
popw %ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.vesa_unsupported:
|
||||||
|
movw $vesa_unsupported_msg, %si
|
||||||
|
jmp print_and_halt
|
||||||
|
.vesa_unsupported_version:
|
||||||
|
movw $vesa_unsupported_version_msg, %si
|
||||||
|
jmp print_and_halt
|
||||||
|
.vesa_error:
|
||||||
|
movw $vesa_error_msg, %si
|
||||||
|
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:
|
||||||
|
pushw %ax
|
||||||
|
pushw %bx
|
||||||
|
|
||||||
|
movw (vesa_target_mode), %bx
|
||||||
|
testw %bx, %bx
|
||||||
|
jz .vesa_set_target_mode_generic
|
||||||
|
|
||||||
|
movw $0x4F02, %ax
|
||||||
|
orw $0x4000, %bx
|
||||||
|
int $0x10
|
||||||
|
|
||||||
|
jmp .set_video_done
|
||||||
|
|
||||||
|
.vesa_set_target_mode_generic:
|
||||||
|
movb $0x03, %al
|
||||||
|
movb $0x00, %ah
|
||||||
|
int $0x10
|
||||||
|
|
||||||
|
.set_video_done:
|
||||||
|
popw %bx
|
||||||
|
popw %ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
vesa_error_msg:
|
||||||
|
.asciz "VESA error"
|
||||||
|
vesa_unsupported_msg:
|
||||||
|
.asciz "VESA unsupported"
|
||||||
|
vesa_unsupported_version_msg:
|
||||||
|
.asciz "VESA unsupported version"
|
||||||
|
vesa_success_msg:
|
||||||
|
.asciz "VESA success"
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
|
||||||
|
vesa_info_buffer:
|
||||||
|
.skip 512
|
||||||
|
|
||||||
|
vesa_mode_info_buffer:
|
||||||
|
.skip 256
|
||||||
|
|
||||||
|
vesa_target_mode:
|
||||||
|
.skip 2
|
||||||
|
|
||||||
|
.global framebuffer
|
||||||
|
framebuffer:
|
||||||
|
.skip 4 # address
|
||||||
|
.skip 4 # pitch
|
||||||
|
.skip 4 # width
|
||||||
|
.skip 4 # height
|
||||||
|
.skip 1 # bpp
|
||||||
|
.skip 1 # type
|
|
@ -2,7 +2,18 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define BANAN_BOOTLOADER_MAGIC 0xD3C60CFF
|
#define BANAN_BOOTLOADER_MAGIC 0xD3C60CFF
|
||||||
|
#define BANAN_BOOTLOADER_FB_RGB 1
|
||||||
|
|
||||||
|
struct BananBootFramebufferInfo
|
||||||
|
{
|
||||||
|
uint32_t address;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint8_t bpp;
|
||||||
|
uint8_t type;
|
||||||
|
};
|
||||||
|
|
||||||
struct BananBootloaderMemoryMapEntry
|
struct BananBootloaderMemoryMapEntry
|
||||||
{
|
{
|
||||||
|
@ -20,5 +31,6 @@ struct BananBootloaderMemoryMapInfo
|
||||||
struct BananBootloaderInfo
|
struct BananBootloaderInfo
|
||||||
{
|
{
|
||||||
uint32_t command_line_addr;
|
uint32_t command_line_addr;
|
||||||
|
uint32_t framebuffer_addr;
|
||||||
uint32_t memory_map_addr;
|
uint32_t memory_map_addr;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
|
@ -71,6 +71,17 @@ namespace Kernel
|
||||||
const char* command_line = reinterpret_cast<const char*>(banan_bootloader_info.command_line_addr);
|
const char* command_line = reinterpret_cast<const char*>(banan_bootloader_info.command_line_addr);
|
||||||
MUST(g_boot_info.command_line.append(command_line));
|
MUST(g_boot_info.command_line.append(command_line));
|
||||||
|
|
||||||
|
const auto& framebuffer = *reinterpret_cast<BananBootFramebufferInfo*>(banan_bootloader_info.framebuffer_addr);
|
||||||
|
if (framebuffer.type == BANAN_BOOTLOADER_FB_RGB)
|
||||||
|
{
|
||||||
|
g_boot_info.framebuffer.address = framebuffer.address;
|
||||||
|
g_boot_info.framebuffer.width = framebuffer.width;
|
||||||
|
g_boot_info.framebuffer.height = framebuffer.height;
|
||||||
|
g_boot_info.framebuffer.pitch = framebuffer.pitch;
|
||||||
|
g_boot_info.framebuffer.bpp = framebuffer.bpp;
|
||||||
|
g_boot_info.framebuffer.type = FramebufferType::RGB;
|
||||||
|
}
|
||||||
|
|
||||||
const auto& memory_map = *reinterpret_cast<BananBootloaderMemoryMapInfo*>(banan_bootloader_info.memory_map_addr);
|
const auto& memory_map = *reinterpret_cast<BananBootloaderMemoryMapInfo*>(banan_bootloader_info.memory_map_addr);
|
||||||
MUST(g_boot_info.memory_map_entries.resize(memory_map.entry_count));
|
MUST(g_boot_info.memory_map_entries.resize(memory_map.entry_count));
|
||||||
for (size_t i = 0; i < memory_map.entry_count; i++)
|
for (size_t i = 0; i < memory_map.entry_count; i++)
|
||||||
|
|
Loading…
Reference in New Issue