[MBR] Successfully jump to protected mode
[MBR} Successfully set VGA video mode 3 [Host/KernelCopy] Fix MBR_PACKET definition and buffer address [RawIMG] Fix linux iamge generation script [Host/GDTCreator] Fix low limit values
This commit is contained in:
parent
d57078cc2d
commit
3f7e02533f
6 changed files with 65 additions and 84 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
uint64_t makeEntry(uint32_t base, uint16_t limit, bool present, unsigned char dpl, bool executable, bool exec_write) {
|
uint64_t makeEntry(uint32_t base, uint32_t limit, bool present, unsigned char dpl, bool executable, bool exec_write) {
|
||||||
uint64_t value = 0x0;
|
uint64_t value = 0x0;
|
||||||
//auto* target = (uint8_t*) &value;
|
//auto* target = (uint8_t*) &value;
|
||||||
|
|
||||||
|
|
@ -43,9 +43,9 @@ uint64_t makeEntry(uint32_t base, uint16_t limit, bool present, unsigned char dp
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
std::cout << std::hex << "Code: " << makeEntry(0, 0xFFFF, true, 0x0, true, true) << std::endl;
|
std::cout << std::hex << "Code: " << makeEntry(0, 0xFFFFF, true, 0x0, true, true) << std::endl;
|
||||||
std::cout << std::hex << "Data: " << makeEntry(0, 0xFFFF, true, 0x0, false, true) << std::endl;
|
std::cout << std::hex << "Data: " << makeEntry(0, 0xFFFFF, true, 0x0, false, true) << std::endl;
|
||||||
std::cout << std::hex << "User Code: " << makeEntry(0, 0xFFFF, true, 0x3, true, true) << std::endl;
|
std::cout << std::hex << "User Code: " << makeEntry(0, 0xFFFFF, true, 0x3, true, true) << std::endl;
|
||||||
std::cout << std::hex << "User Data: " << makeEntry(0, 0xFFFF, true, 0x3, false, true) << std::endl;
|
std::cout << std::hex << "User Data: " << makeEntry(0, 0xFFFFF, true, 0x3, false, true) << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -27,6 +27,7 @@ typedef struct _MBR_ReadPacket {
|
||||||
os_u16 blocks;
|
os_u16 blocks;
|
||||||
os_u16 buffer_offset;
|
os_u16 buffer_offset;
|
||||||
os_u16 buffer_segment;
|
os_u16 buffer_segment;
|
||||||
|
//os_u32 buffer;
|
||||||
os_u64 lba;
|
os_u64 lba;
|
||||||
os_u16 sig_1;
|
os_u16 sig_1;
|
||||||
} OS_PACK_MID MBR_ReadPacket;
|
} OS_PACK_MID MBR_ReadPacket;
|
||||||
|
|
@ -136,35 +137,18 @@ int main(int argc, char** argv) {
|
||||||
char mbr[512];
|
char mbr[512];
|
||||||
fread(mbr, 1, 512, image);
|
fread(mbr, 1, 512, image);
|
||||||
|
|
||||||
os_bool found = OS_FALSE;
|
printf("Kernel size: %d", kernel_size);
|
||||||
os_s8* ptr = mbr;
|
|
||||||
for(int i = 0; i < 512 - sizeof(MBR_BuildSettings); i++) {
|
|
||||||
MBR_BuildSettings* settings = (MBR_BuildSettings*)ptr;
|
|
||||||
if (settings->sig_0 == MBR_SETTINGS_SIG_0 && settings->sig_1 == MBR_SETTINGS_SIG_1) {
|
|
||||||
settings->sector = kernel_offset / fat.header.base.bytes_per_sector;
|
|
||||||
settings->size = kernel_size;
|
|
||||||
found = OS_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
os_bool found = OS_FALSE;
|
||||||
if (found == OS_FALSE) {
|
os_u8* ptr = mbr;
|
||||||
fprintf(stderr, "Error: could not find BUILD_SETTINGS markers\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = OS_FALSE;
|
|
||||||
|
|
||||||
ptr = mbr;
|
|
||||||
for (int i = 0; i < 512 - sizeof(MBR_ReadPacket); i++) {
|
for (int i = 0; i < 512 - sizeof(MBR_ReadPacket); i++) {
|
||||||
MBR_ReadPacket * packet = (MBR_ReadPacket*)ptr;
|
MBR_ReadPacket * packet = (MBR_ReadPacket*)ptr;
|
||||||
if(packet->sig_0 == MBR_PACKET_SIG_0 && packet->sig_1 == MBR_PACKET_SIG_1) {
|
if(packet->sig_0 == MBR_PACKET_SIG_0 && packet->sig_1 == MBR_PACKET_SIG_1) {
|
||||||
packet->lba = kernel_offset / fat.header.base.bytes_per_sector;
|
packet->lba = kernel_offset / fat.header.base.bytes_per_sector;
|
||||||
packet->blocks = (kernel_size / fat.header.base.bytes_per_sector) + ((kernel_size % fat.header.base.bytes_per_sector) == 0 ? 0 : 1);
|
packet->blocks = (kernel_size / fat.header.base.bytes_per_sector) + ((kernel_size % fat.header.base.bytes_per_sector) == 0 ? 0 : 1);
|
||||||
packet->buffer_offset = 0x0000;
|
packet->buffer_offset = 0x0000;
|
||||||
packet->buffer_segment = 0x0100;
|
packet->buffer_segment = 0x1000;
|
||||||
|
//packet->buffer = 0x10000;
|
||||||
found = OS_TRUE;
|
found = OS_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ SECTIONS
|
||||||
.sig : AT(0x7DFE){
|
.sig : AT(0x7DFE){
|
||||||
SHORT(0xaa55);
|
SHORT(0xaa55);
|
||||||
}
|
}
|
||||||
. = 0x7E00;
|
. = 0x9C00;
|
||||||
.eh_frame : AT(0x7E00){
|
.eh_frame : AT(0x9C00){
|
||||||
*.o(.eh_frame);
|
*.o(.eh_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
95
mbr/mbr.asm
95
mbr/mbr.asm
|
|
@ -15,7 +15,7 @@ fat_header:
|
||||||
; function READ_SECTORS_EXTENDED: Read sectors from disk
|
; function READ_SECTORS_EXTENDED: Read sectors from disk
|
||||||
; Uses INT 13h AH=42h from: http://www.ctyme.com/intr/rb-0708.htm
|
; Uses INT 13h AH=42h from: http://www.ctyme.com/intr/rb-0708.htm
|
||||||
; Stack Parameters (in order of PUSH):
|
; Stack Parameters (in order of PUSH):
|
||||||
; - BYTE: Drive number
|
; - WORD: Drive number (interpret as BYTE)
|
||||||
; - WORD: Address of packet
|
; - WORD: Address of packet
|
||||||
; - WORD: RETURN ADDRESS
|
; - WORD: RETURN ADDRESS
|
||||||
; Returns:
|
; Returns:
|
||||||
|
|
@ -34,7 +34,8 @@ read_sectors_extended:
|
||||||
PUSH BP ; save BP
|
PUSH BP ; save BP
|
||||||
MOV BP, SP ; estabilish stack frame
|
MOV BP, SP ; estabilish stack frame
|
||||||
MOV DX, 0 ; zero-out DX
|
MOV DX, 0 ; zero-out DX
|
||||||
MOV DL, [BP + 10] ; load drive number
|
MOV DX, [BP + 10] ; load drive number
|
||||||
|
MOV DH, 0 ; Zero-out high byte of drive number
|
||||||
MOV SI, [BP + 8] ; load address of packet
|
MOV SI, [BP + 8] ; load address of packet
|
||||||
MOV AH, 42h ; set AH to 42h
|
MOV AH, 42h ; set AH to 42h
|
||||||
MOV AL, 0h ; set AL to 0h
|
MOV AL, 0h ; set AL to 0h
|
||||||
|
|
@ -186,35 +187,23 @@ entry:
|
||||||
; Not doing this may cause an interrupt to use an old SP and new SS
|
; Not doing this may cause an interrupt to use an old SP and new SS
|
||||||
MOV DS, AX ; set up segment registers
|
MOV DS, AX ; set up segment registers
|
||||||
MOV ES, AX ; ^^^
|
MOV ES, AX ; ^^^
|
||||||
MOV FS, AX ; ^^^
|
|
||||||
MOV GS, AX ; ^^^
|
|
||||||
|
|
||||||
PUSH DX ; save drive number (DL)
|
PUSH DX ; save drive number (DL)
|
||||||
|
|
||||||
; Load kernel image
|
; Load kernel image
|
||||||
MOV BX, packet_blocks ; Load address of packet_blocks
|
|
||||||
MOV AX, [BX] ; Load value of packet_blocks
|
; Comment out check, presume that the packet info is populated
|
||||||
CMP AX, 0 ; See if amount of packets to read is 0
|
;MOV BX, packet_blocks ; Load address of packet_blocks
|
||||||
JE endless_loop ; if no packets are to be loaded, the kernel is not present. Loop endlessly
|
;MOV AX, [BX] ; Load value of packet_blocks
|
||||||
POP AX ; load 'drive number'
|
;CMP AX, 0 ; See if amount of packets to read is 0
|
||||||
PUSH AX ; pushing it twice to keep it saved, CBA to mess with SP, BP and stuff right now
|
;JE endless_loop ; if no packets are to be loaded, the kernel is not present. Loop endlessly
|
||||||
PUSH AX ; push parameter 'drive number'
|
|
||||||
|
; Parameter drive number is already in the stack
|
||||||
MOV AX, read_sectors_packet ; load 'packet address'
|
MOV AX, read_sectors_packet ; load 'packet address'
|
||||||
PUSH AX ; push parameter 'packet address'
|
PUSH AX ; push parameter 'packet address'
|
||||||
CALL read_sectors_extended ; try to read these damned sectors
|
CALL read_sectors_extended ; try to read these damned sectors
|
||||||
ADD SP, 4 ; clear previous call parameters
|
ADD SP, 4 ; clear previous call parameters
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Print message
|
|
||||||
MOV AX, msg ; load address of msg
|
|
||||||
PUSH AX ; push parameter 'address of string'
|
|
||||||
MOV AX, 14 ; load size of msg
|
|
||||||
PUSH AX ; push parameter 'size of string'
|
|
||||||
CALL print ; call function 'print'
|
|
||||||
|
|
||||||
ADD SP, 4 ; clear previous call parameters
|
|
||||||
|
|
||||||
; Enable A20
|
; Enable A20
|
||||||
CALL check_a20 ; call check_a20. Result in Ax
|
CALL check_a20 ; call check_a20. Result in Ax
|
||||||
CMP AX, 0 ; compare AX to 0 (0 = A20 disabled)
|
CMP AX, 0 ; compare AX to 0 (0 = A20 disabled)
|
||||||
|
|
@ -231,28 +220,44 @@ entry:
|
||||||
MOV AX, 8 ; load size of 'a20_msg'
|
MOV AX, 8 ; load size of 'a20_msg'
|
||||||
PUSH AX ; push parameter 'size of string'
|
PUSH AX ; push parameter 'size of string'
|
||||||
CALL print ; print 'a20_msg'
|
CALL print ; print 'a20_msg'
|
||||||
|
JMP endless_loop ; loop endlessly
|
||||||
|
|
||||||
|
|
||||||
after_a20:
|
after_a20:
|
||||||
|
|
||||||
|
; set video mode
|
||||||
|
STI ; re-enable interrupts
|
||||||
|
MOV AH, 00h ; int 10h AH=00h = set video mode command
|
||||||
|
MOV AL, 03h ; desired video mode (80x25 characters, 8 colors)
|
||||||
|
INT 10h ; call interrupt
|
||||||
|
|
||||||
|
after_video:
|
||||||
; load GDT
|
; load GDT
|
||||||
CLI ; disable interrupts
|
CLI ; disable interrupts
|
||||||
MOV AX, gdt ; load address of GDT
|
LGDT [gdt_ptr] ; load GDT
|
||||||
MOV [gdt_ptr_base], AX ; save address of GDT to gdt_ptr_base
|
|
||||||
LGDT [gdt_ptr_base] ; load GDT
|
; Enable protected mode
|
||||||
|
MOV EAX, CR0 ; load Control Register 0
|
||||||
|
OR AL, 1 ; set Protection Enable bit
|
||||||
|
MOV CR0, EAX ; save Control Register 0
|
||||||
|
|
||||||
|
JMP 08h:init_32 ; long jump to 32 bit mode
|
||||||
|
|
||||||
|
init_32:
|
||||||
|
USE32
|
||||||
|
MOV AX, 10h ; load 32 bit segment registers
|
||||||
|
MOV AX, 10h
|
||||||
|
MOV DS, AX ; ^^^^
|
||||||
|
MOV SS, AX ; ^^^^
|
||||||
|
MOV FS, AX ; ^^^^
|
||||||
|
MOV GS, AX ; ^^^^
|
||||||
|
MOV SS, AX ; ^^^^
|
||||||
|
MOV EAX, 0x7CFE ; reset stack
|
||||||
|
MOV ESP, EAX ; ^^^^
|
||||||
|
JMP 0x10000 ; jump to stage1 bootloader
|
||||||
|
|
||||||
|
|
||||||
; print message
|
USE16
|
||||||
MOV AX, gdt_msg ; load address of 'gdt_ms'
|
|
||||||
PUSH AX ; push parameter 'address of string'
|
|
||||||
MOV AX, 8 ; load size of 'gdt_msg'
|
|
||||||
PUSH AX ; push parameter 'size of string'
|
|
||||||
CALL print ; print 'gdt_msg'
|
|
||||||
|
|
||||||
JMP endless_loop ; loop endlessly
|
|
||||||
|
|
||||||
|
|
||||||
endless_loop:
|
endless_loop:
|
||||||
JMP endless_loop ; loop endlessly
|
JMP endless_loop ; loop endlessly
|
||||||
|
|
||||||
|
|
@ -268,23 +273,15 @@ packet_buffer_seg dw 0h
|
||||||
packet_lba dq 0h
|
packet_lba dq 0h
|
||||||
packet_sig_1 dw 0x4955
|
packet_sig_1 dw 0x4955
|
||||||
|
|
||||||
build_settings:
|
|
||||||
build_settings_magic_0 dw 0x4952
|
|
||||||
build_settings_offset dw 0x0
|
|
||||||
build_settings_size dw 0x0
|
|
||||||
build_settings_magic_1 dw 0x4953
|
|
||||||
|
|
||||||
msg db "OS3_KRNL_OK!", 10, 13
|
|
||||||
a20_msg db "NO_A20", 10, 13
|
a20_msg db "NO_A20", 10, 13
|
||||||
gdt_msg db "GDT_OK", 10, 13
|
|
||||||
|
|
||||||
gdt:
|
gdt:
|
||||||
null_sec dq 0x0
|
null_sec dq 0x0
|
||||||
kernel_code dq 0xc09a000000ffff
|
kernel_code dq 0xcf9a000000ffff
|
||||||
kernel_data dq 0xc092000000ffff
|
kernel_data dq 0xcf92000000ffff
|
||||||
user_code dq 0xc0fa000000ffff
|
user_code dq 0xcffa000000ffff
|
||||||
user_data dq 0xc0f2000000ffff
|
user_data dq 0xcff2000000ffff
|
||||||
|
|
||||||
gdt_ptr:
|
gdt_ptr:
|
||||||
gdt_ptr_limit dw 40
|
gdt_ptr_limit dw 40
|
||||||
gdt_ptr_base dd 0
|
gdt_ptr_base dd gdt
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo "Generating image $1..."
|
echo "Generating image $1..."
|
||||||
qemu-img create $1 512M
|
qemu-img create "$1" "512M"
|
||||||
mkfs.vfat $1 -n OS3_BOOT
|
mkfs.vfat "$1" -n OS3_BOOT
|
||||||
|
|
@ -3,15 +3,15 @@ SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x10000;
|
. = 0x10000;
|
||||||
.text : AT(0x10000){
|
.text : AT(0x10000){
|
||||||
*.o(.text);
|
*(.text);
|
||||||
}
|
}
|
||||||
.data : {
|
.data : {
|
||||||
*.o(.data);
|
*(.data);
|
||||||
}
|
}
|
||||||
.rodata : {
|
.rodata : {
|
||||||
*.o(.rodata);
|
*(.rodata);
|
||||||
}
|
}
|
||||||
.bss : {
|
.bss : {
|
||||||
*.o(.bss);
|
*(.bss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue