mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-11 05:24:44 -04:00
Get a VESA mode
This commit is contained in:
parent
f5ff78ea08
commit
e1acb58c12
2
Makefile
2
Makefile
@ -31,7 +31,7 @@ thor.flp: bootloader/stage1.bin bootloader/stage2.bin kernel/kernel.bin programs
|
|||||||
sudo /sbin/losetup -d /dev/loop0
|
sudo /sbin/losetup -d /dev/loop0
|
||||||
|
|
||||||
qemu: default
|
qemu: default
|
||||||
qemu-kvm -cpu host -hda hdd.img
|
qemu-kvm -cpu host -vga std -hda hdd.img
|
||||||
|
|
||||||
bochs: default
|
bochs: default
|
||||||
bochs -qf bochsrc.txt
|
bochs -qf bochsrc.txt
|
||||||
|
@ -98,6 +98,8 @@ static_assert(sizeof(mode_info_block_t) == 256, "The size of a mode info block i
|
|||||||
|
|
||||||
extern vbe_info_block_t vbe_info_block;
|
extern vbe_info_block_t vbe_info_block;
|
||||||
extern bool vesa_enabled;
|
extern bool vesa_enabled;
|
||||||
|
extern mode_info_block_t mode_info_block;
|
||||||
|
extern uint16_t modes;
|
||||||
|
|
||||||
} //end of vesa namespace
|
} //end of vesa namespace
|
||||||
|
|
||||||
|
@ -37,7 +37,9 @@ int16_t e820::bios_e820_entry_count = 0;
|
|||||||
#include "vesa.hpp"
|
#include "vesa.hpp"
|
||||||
|
|
||||||
vesa::vbe_info_block_t vesa::vbe_info_block;
|
vesa::vbe_info_block_t vesa::vbe_info_block;
|
||||||
|
vesa::mode_info_block_t vesa::mode_info_block;
|
||||||
bool vesa::vesa_enabled = false;
|
bool vesa::vesa_enabled = false;
|
||||||
|
uint16_t vesa::modes = 0;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -64,6 +66,10 @@ void set_es(uint16_t seg){
|
|||||||
asm volatile("mov es, %0" : : "rm" (seg));
|
asm volatile("mov es, %0" : : "rm" (seg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_gs(uint16_t seg){
|
||||||
|
asm volatile("mov gs, %0" : : "rm" (seg));
|
||||||
|
}
|
||||||
|
|
||||||
void reset_segments(){
|
void reset_segments(){
|
||||||
set_ds(0);
|
set_ds(0);
|
||||||
set_es(0);
|
set_es(0);
|
||||||
@ -106,16 +112,104 @@ void detect_memory(){
|
|||||||
e820::bios_e820_entry_count = detect_memory_e820();
|
e820::bios_e820_entry_count = detect_memory_e820();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t read_mode(uint16_t i){
|
||||||
|
uint16_t mode;
|
||||||
|
asm volatile("mov gs, %0; mov si, %1; add si, %3; mov %0, gs:[si]"
|
||||||
|
: "=a" (mode)
|
||||||
|
: "rm" (vesa::vbe_info_block.video_modes_ptr[0]),
|
||||||
|
"rm" (vesa::vbe_info_block.video_modes_ptr[1]),
|
||||||
|
"rm" (i));
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t abs_diff(uint16_t a, uint16_t b){
|
||||||
|
if(a > b){
|
||||||
|
return a - b;
|
||||||
|
} else {
|
||||||
|
return b - a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool bit_set(const T& value, uint8_t bit){
|
||||||
|
return value & (1 << bit);
|
||||||
|
}
|
||||||
|
|
||||||
void setup_vesa(){
|
void setup_vesa(){
|
||||||
|
vesa::vbe_info_block.signature[0] = 'V';
|
||||||
|
vesa::vbe_info_block.signature[1] = 'B';
|
||||||
|
vesa::vbe_info_block.signature[2] = 'E';
|
||||||
|
vesa::vbe_info_block.signature[3] = '2';
|
||||||
|
|
||||||
uint16_t return_code;
|
uint16_t return_code;
|
||||||
asm volatile ("int 0x10"
|
asm volatile ("int 0x10"
|
||||||
: "=a"(return_code)
|
: "=a"(return_code)
|
||||||
: "a"(0x4F00), "D"(&vesa::vbe_info_block));
|
: "a"(0x4F00), "D"(&vesa::vbe_info_block)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
if(return_code == 0x4F){
|
if(return_code == 0x4F){
|
||||||
vesa::vesa_enabled = true;
|
uint16_t wanted_x = 1024;
|
||||||
|
uint16_t wanted_y = 768;
|
||||||
|
|
||||||
|
uint16_t best_mode = 0;
|
||||||
|
uint16_t best_size_diff = 65535;
|
||||||
|
|
||||||
|
bool one = false;
|
||||||
|
|
||||||
|
for(uint16_t mode = 0; mode != 0xFFFF; ++mode){
|
||||||
|
asm volatile ("int 0x10"
|
||||||
|
: "=a"(return_code)
|
||||||
|
: "a"(0x4F01), "c"(mode), "D"(&vesa::mode_info_block)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
//Make sure the mode is supported by get mode info function
|
||||||
|
if(return_code != 0x4F){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check that the mode support Linear Frame Buffer
|
||||||
|
if(!bit_set(vesa::mode_info_block.mode_attributes, 7)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure it is a packed pixel or direct color model
|
||||||
|
if(vesa::mode_info_block.memory_model != 4 && vesa::mode_info_block.memory_model != 6){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
one = true;
|
||||||
|
|
||||||
|
auto x_res = vesa::mode_info_block.width;
|
||||||
|
auto y_res = vesa::mode_info_block.height;
|
||||||
|
|
||||||
|
auto size_diff = abs_diff(x_res, wanted_x) + abs_diff(y_res, wanted_y);
|
||||||
|
|
||||||
|
if(size_diff < best_size_diff){
|
||||||
|
best_mode = mode;
|
||||||
|
best_size_diff = size_diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!one || best_mode == 0xFFFF){
|
||||||
|
vesa::vesa_enabled = false;
|
||||||
|
} else {
|
||||||
|
asm volatile ("int 0x10"
|
||||||
|
: "=a"(return_code)
|
||||||
|
: "a"(0x4F01), "c"(best_mode), "D"(&vesa::mode_info_block)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
if(return_code == 0x4F){
|
||||||
|
vesa::vesa_enabled = true;
|
||||||
|
//asm volatile ("int 0x10"
|
||||||
|
// : "=a"(return_code)
|
||||||
|
// : "a"(0x4F02), "b"(best_mode));
|
||||||
|
} else {
|
||||||
|
vesa::vesa_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_gs(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable_interrupts(){
|
void disable_interrupts(){
|
||||||
@ -259,15 +353,15 @@ void __attribute__ ((noreturn)) rm_main(){
|
|||||||
//Analyze memory
|
//Analyze memory
|
||||||
detect_memory();
|
detect_memory();
|
||||||
|
|
||||||
|
//Make sure a20 gate is enabled
|
||||||
|
enable_a20_gate();
|
||||||
|
|
||||||
//Enable VESA
|
//Enable VESA
|
||||||
setup_vesa();
|
setup_vesa();
|
||||||
|
|
||||||
//Disable interrupts
|
//Disable interrupts
|
||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
|
|
||||||
//Make sure a20 gate is enabled
|
|
||||||
enable_a20_gate();
|
|
||||||
|
|
||||||
//Setup an IDT with null limits to prevents interrupts from being used in
|
//Setup an IDT with null limits to prevents interrupts from being used in
|
||||||
//protected mode
|
//protected mode
|
||||||
setup_idt();
|
setup_idt();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "rtc.hpp"
|
#include "rtc.hpp"
|
||||||
#include "elf.hpp"
|
#include "elf.hpp"
|
||||||
#include "paging.hpp"
|
#include "paging.hpp"
|
||||||
|
#include "vesa.hpp"
|
||||||
|
|
||||||
//Commands
|
//Commands
|
||||||
#include "sysinfo.hpp"
|
#include "sysinfo.hpp"
|
||||||
@ -67,13 +68,14 @@ void touch_command(const std::vector<std::string>& params);
|
|||||||
void readelf_command(const std::vector<std::string>& params);
|
void readelf_command(const std::vector<std::string>& params);
|
||||||
void exec_command(const std::vector<std::string>& params);
|
void exec_command(const std::vector<std::string>& params);
|
||||||
void shutdown_command(const std::vector<std::string>& params);
|
void shutdown_command(const std::vector<std::string>& params);
|
||||||
|
void vesainfo_command(const std::vector<std::string>& params);
|
||||||
|
|
||||||
struct command_definition {
|
struct command_definition {
|
||||||
const char* name;
|
const char* name;
|
||||||
void (*function)(const std::vector<std::string>&);
|
void (*function)(const std::vector<std::string>&);
|
||||||
};
|
};
|
||||||
|
|
||||||
command_definition commands[26] = {
|
command_definition commands[27] = {
|
||||||
{"reboot", reboot_command},
|
{"reboot", reboot_command},
|
||||||
{"help", help_command},
|
{"help", help_command},
|
||||||
{"uptime", uptime_command},
|
{"uptime", uptime_command},
|
||||||
@ -100,6 +102,7 @@ command_definition commands[26] = {
|
|||||||
{"readelf", readelf_command},
|
{"readelf", readelf_command},
|
||||||
{"exec", exec_command},
|
{"exec", exec_command},
|
||||||
{"shutdown", shutdown_command},
|
{"shutdown", shutdown_command},
|
||||||
|
{"vesainfo", vesainfo_command},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string current_input(16);
|
std::string current_input(16);
|
||||||
@ -841,6 +844,19 @@ void exec_command(const std::vector<std::string>& params){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vesainfo_command(const std::vector<std::string>&){
|
||||||
|
k_print_line(vesa::modes);
|
||||||
|
k_printf("x=%u : y=%u \n", (size_t) vesa::mode_info_block.width, (size_t) vesa::mode_info_block.height);
|
||||||
|
k_print_line(vesa::mode_info_block.mode_attributes);
|
||||||
|
if(vesa::vesa_enabled){
|
||||||
|
k_print_line("VESA Enabled");
|
||||||
|
|
||||||
|
k_printf("x=%u : y=%u \n", (size_t) vesa::mode_info_block.width, (size_t) vesa::mode_info_block.height);
|
||||||
|
} else {
|
||||||
|
k_print_line("VESA Disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void shutdown_command(const std::vector<std::string>&){
|
void shutdown_command(const std::vector<std::string>&){
|
||||||
if(!acpi::init()){
|
if(!acpi::init()){
|
||||||
k_print_line("Unable to init ACPI");
|
k_print_line("Unable to init ACPI");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user