2015-10-10 16:03:53 +00:00
# include <base.hpp>
2015-10-10 12:59:23 +00:00
# include <output.hpp>
# include <serial.hpp>
2015-10-10 16:03:53 +00:00
# include <textDISP.hpp>
2015-10-10 17:34:31 +00:00
# include <gdt.hpp>
2015-10-11 10:38:56 +00:00
# include <idt.hpp>
2015-10-13 14:11:06 +00:00
# include <keyboard.hpp>
2016-04-15 20:04:01 +00:00
# include <Multitasking.hpp>
2016-02-04 11:57:35 +00:00
# include <multiboot.h>
2016-03-15 20:38:25 +00:00
# include <blockdev.hpp>
2016-06-17 19:39:43 +00:00
# include <pmm.hpp>
2015-10-11 10:38:56 +00:00
extern " C " void intr_stub_0 ( void ) ;
2016-06-26 15:14:09 +00:00
void main ( void * * programs , MTGosHAL : : Serial & debug , MTGosHAL : : PMM & mm , MTGosHAL : : Screen & out ,
2016-07-24 08:58:58 +00:00
MTGosHAL : : Screen & err , MTGosHAL : : Keyboard & in , MTGosHAL : : Multitasking & tasks , MTGosHAL : : BlockDevice & disk ) ;
2016-05-22 20:26:47 +00:00
void * * progs ;
2015-10-10 16:03:53 +00:00
namespace MTGosHAL {
2016-07-24 08:58:58 +00:00
Serial debug ;
GDT gdt ;
IDT idt ;
PMM mm ;
Screen out ;
Screen err ;
Keyboard in ;
Multitasking tasks ;
BlockDevice disk ;
void main ( int eax , struct multiboot_info * ebx ) {
//Init debug output
2016-07-24 10:21:12 +00:00
new ( & debug ) Serial ( ) ;
debug < < " Hello debugger! This is MTGos v00r01 \n These logs are probably very long, so please redirect the output to a file. \n " ;
2016-06-17 19:39:43 +00:00
2016-07-24 10:21:12 +00:00
debug < < " Init GDT \n " ;
new ( & gdt ) GDT ( ) ;
gdt . setEntry ( 0 , 0 , 0 , 0 ) ;
2016-07-24 08:58:58 +00:00
gdt . setEntry ( 1 , 0 , 0xfffff , GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT ) ;
gdt . setEntry ( 2 , 0 , 0xfffff , GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT ) ;
gdt . setEntry ( 3 , 0 , 0xfffff , GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3 ) ;
gdt . setEntry ( 4 , 0 , 0xfffff , GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3 ) ;
gdt . setEntry ( 5 , ( uint32_t ) tasks . tss , sizeof ( tasks . tss ) , GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT ) ;
gdt . setEntry ( 6 , 0 , 0xfffff , GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT ) ;
gdt . apply ( ) ;
2016-06-17 19:39:43 +00:00
2016-07-24 10:21:12 +00:00
debug < < " Init IDT \n " ;
new ( & idt ) IDT ( ) ;
for ( int i = 0 ; i < 256 ; i + + ) {
2016-07-24 08:58:58 +00:00
idt . setEntry ( i , ( void * ) ( ( uint32_t ) & intr_stub_0 + i * 16 ) , SEG_KERNEL , IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED ) ;
}
idt . setEntry ( 48 , ( void * ) ( ( uint32_t ) & intr_stub_0 + 768 ) , SEG_KERNEL , IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED ) ;
idt . setEntry ( 8 , ( void * ) ( ( uint32_t ) & intr_stub_0 + 128 ) , SEG_DBL_FAULT , IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED ) ;
idt . apply ( ) ;
2016-07-24 10:21:12 +00:00
asm volatile ( " ltr %%ax " : : " a " ( 5 < < 3 ) ) ;
debug < < " Init MM \n " ;
new ( & mm ) PMM ( ebx ) ;
2016-06-17 19:39:43 +00:00
2016-07-24 10:21:12 +00:00
debug < < " Init Screen output \n " ;
new ( & out ) Screen ( ebx ) ;
new ( & err ) Screen ( ebx ) ;
2016-07-24 08:58:58 +00:00
out < < BG_color : : BLACK < < FG_color : : WHITE < < " Loading MTGos... \n " ;
err < < BG_color : : BLACK < < FG_color : : RED ;
2016-06-17 19:39:43 +00:00
2016-07-24 10:21:12 +00:00
debug < < " Init Keyboard \n " ;
new ( & in ) Keyboard ( ) ;
2016-06-17 19:39:43 +00:00
2016-07-24 08:58:58 +00:00
debug < < " Init Multitasking \n " ;
new ( & tasks ) Multitasking ( ) ;
2016-06-17 19:39:43 +00:00
2016-07-24 10:21:12 +00:00
debug < < " Init Disk \n " ;
new ( & disk ) BlockDevice ( ) ;
2016-06-17 19:39:43 +00:00
2016-07-24 10:21:12 +00:00
debug < < " Kernel initialized \n " ;
2016-07-24 08:58:58 +00:00
if ( eax ! = 0x2BADB002 )
err < < " System wasn't loaded by a Multiboot-conformant launcher! \n " ;
2016-07-24 10:21:12 +00:00
multiboot_mod_list * mods = ( multiboot_mod_list * ) ebx - > mods_addr ;
2016-07-24 08:58:58 +00:00
progs = ( void * * ) mm . alloc ( 4096 ) ;
2016-07-24 10:21:12 +00:00
for ( int i = 0 ; i < 1024 ; i + + ) {
progs [ i ] = nullptr ;
}
2016-07-24 08:58:58 +00:00
for ( uint32_t i = 0 ; i < ( ebx - > mods_count < 1023 ? ebx - > mods_count : 1023 ) ; i + + ) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
progs [ i ] = ( void * ) ( mods [ i ] . mod_start ) ;
debug < < " Found module! \n " ;
}
: : main ( progs , debug , mm , out , err , in , tasks , disk ) ;
2016-07-24 10:21:12 +00:00
uint8_t buf [ 512 ] ;
disk . readSector ( disk . getDriveNumByName ( " ATA0m " ) , 0 , buf ) ;
out < < ( char * ) buf ;
out < < " こんにちは、ユニコード。 \n Здравствуй, Юникод. \n Γεια σ ο υ , Γιούνικοντ. \n 안녕하세요, 유니코드. \n " _s ;
sti ( ) ;
2016-07-24 08:58:58 +00:00
for ( ; ; ) ;
}
2015-10-10 12:59:23 +00:00
}
2015-10-14 18:02:41 +00:00
typedef void ( * constructor ) ( ) ;
2016-02-06 18:57:44 +00:00
typedef void ( * destructor ) ( ) ;
extern " C " destructor start_dtors ;
extern " C " destructor end_dtors ;
2016-02-04 11:57:35 +00:00
extern " C " void init ( int eax , struct multiboot_info * ebx ) {
2016-07-24 08:58:58 +00:00
MTGosHAL : : main ( eax , ebx ) ;
for ( destructor * i = & start_dtors ; i ! = & end_dtors ; i + + )
( * i ) ( ) ;
2015-10-10 12:59:23 +00:00
}
extern " C " void __cxa_pure_virtual ( ) {
2016-07-24 08:58:58 +00:00
MTGosHAL : : debug < < " A pure virtual function just got called. \n " ;
2015-10-10 12:59:23 +00:00
}