Skip to content

Commit 953b12d

Browse files
committed
Added Real Mode to Protected Mode switch
1 parent d4e4bd6 commit 953b12d

File tree

5 files changed

+149
-10
lines changed

5 files changed

+149
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.vmdk
22
*.o
3+
local_notes/
34
build/

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ app_dashboard = $(BUILD_DIR)/dashboard
2323
# Parameters
2424
BT_STAGE2_SECTOR_COUNT = 19 # In Hex
2525

26+
# General Assumptions
27+
## Integer is 4 bytes
28+
2629
rebuild: clean all
2730

2831
all: images binaries
@@ -93,7 +96,10 @@ debug_stage2_asm: $(bt_stage2_asm_o)
9396
xxd $<
9497

9598
qemu: $(image_vmdk) images
96-
cpulimit -f -l 10 -- qemu-system-x86_64 -smp 1 -m 1M -hda $<
99+
cpulimit -f -l 10 -- qemu-system-x86_64 -smp 1 -m 128M -hda $< -no-shutdown -no-reboot
100+
101+
qemu_debug: $(image_vmdk) images
102+
qemu-system-x86_64 -smp 1 -m 128M -hda $< -no-shutdown -no-reboot -d cpu,exec,in_asm
97103

98104
clean:
99105
rm -f $(image_vmdk) $(bt_stage1) $(bt_stage2) $(bt_stage2_c_o) $(bt_stage2_asm_o)

src/app/dashboard.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ void print_board() {
3535
print_applications(4,4, (char*)application_list, 5, 15);
3636
}
3737

38-
int call_main(unsigned int address, int argc, char *argv[]) {
39-
return ((int (*) (int, char *[]))address)(argc, argv);
38+
int call_main(unsigned short cs,unsigned short ip, int argc, char *argv[]) {
39+
return ((int (*) (int, char *[]))(unsigned int)ip)(argc, argv);
4040
}
4141

4242
int run_dashboard(int argc,char **argv) {
@@ -57,7 +57,7 @@ int run_dashboard(int argc,char **argv) {
5757
continue;
5858
}
5959
char *argv[] = {"argv1, argv2", "argv3"};
60-
int return_status = call_main(0xC000, 3, argv);
60+
int return_status = call_main(0x0C00,0x0000, 3, argv);
6161

6262
print_board();
6363
set_color_bg(C_DARK_GRAY);

src/bootloader/stage2.asm

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[BITS 16]
99

1010
extern entry_stage
11+
global enter_protected_mode
1112

1213
[SECTION .text]
1314
CLI
@@ -19,7 +20,31 @@ extern entry_stage
1920
call entry_stage
2021
JMP label_exit
2122

22-
label_exit:
23+
enter_protected_mode:
24+
; Args: (gdtr_address)
25+
; And never returns.
26+
27+
push ebp
28+
mov ebp, esp
29+
30+
cli
31+
32+
; Load GDT Table
33+
; Workaround for Issue #3
34+
mov eax, [esp+8] ; gdtr_address
35+
mov ebx, eax
36+
add ebx, 8 ; &gdtr_table
37+
mov [eax+2], ebx ; gdtr.base_address = &gdtr_table
38+
39+
lgdt [eax] ; Load GDT Table
40+
41+
; Enter Protected mode
42+
mov eax, cr0
43+
or eax, 0x00000001
44+
mov cr0, eax
45+
jmp 0x08:long_jump_enter_protected
46+
47+
label_exit:
2348
HLT
2449
JMP label_exit
2550

@@ -30,4 +55,36 @@ label_exit:
3055

3156
[SECTION .data]
3257
bl_stage_2 db "Bootloader: Stage 2"
33-
bl_stage_2_len equ ($-bl_stage_2)
58+
bl_stage_2_len equ ($-bl_stage_2)
59+
60+
61+
[BITS 16]
62+
long_jump_enter_protected:
63+
64+
mov ax, 0x10
65+
mov ds, ax
66+
mov ss, ax
67+
mov es, ax
68+
mov fs, ax
69+
mov gs, ax
70+
71+
; Print Done
72+
mov ah,0x0F
73+
mov ebx,0xb8000
74+
mov al,'D'
75+
mov [ebx],ax
76+
77+
add ebx, 2
78+
mov al,'o'
79+
mov [ebx],ax
80+
81+
add ebx, 2
82+
mov al,'n'
83+
mov [ebx],ax
84+
85+
add ebx, 2
86+
mov al,'e'
87+
mov [ebx],ax
88+
89+
; TODO: Will improve this soon.
90+
hlt

src/bootloader/stage2.c

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,80 @@
55

66
char message_welcome[] = "C says 'Hello World'";
77
char message_dashboard[] = "Opening App 'Dashboard'";
8+
char message_protected_mode[] = "Enabling Protected Mode...";
9+
10+
#define GDT_TABLE_SIZE 3
11+
12+
struct GDTReference {
13+
unsigned short size;
14+
unsigned int base_address;
15+
};
16+
17+
struct GDTEntry {
18+
unsigned short limit0;
19+
unsigned short base0;
20+
unsigned char base1;
21+
unsigned char access_byte;
22+
unsigned char flags_limit1;
23+
unsigned char base2;
24+
};
25+
26+
// Issue#2: gdt_table must immediately after gdtr.
27+
struct GDTReference gdtr;
28+
struct GDTEntry gdt_table[GDT_TABLE_SIZE];
29+
30+
void populate_gct_entry(struct GDTEntry *entry,
31+
unsigned int base,
32+
unsigned int limit, // 20 bits
33+
unsigned char flags, // 4 bits
34+
unsigned char access_byte
35+
) {
36+
entry->base0 = (base&0x0000FFFF);
37+
entry->base1 = (base&0x00FF0000)>>16;
38+
entry->base2 = (base&0xFF000000)>>24;
39+
entry->limit0 = (limit&0x0FFFF);
40+
entry->flags_limit1 = (flags<<4)|((limit&0xF0000)>>16);
41+
entry->access_byte = access_byte;
42+
}
43+
44+
extern void enter_protected_mode(int gdtr_address);
45+
46+
int populate_gdt_table() {
47+
// Assumption DS = 0
48+
// Populate simple overlapping code and data segment.
49+
populate_gct_entry(
50+
&gdt_table[0],
51+
0,0,0,0);
52+
populate_gct_entry(
53+
&gdt_table[1],
54+
0x00000000,0x0fffffff,
55+
0b00000000,
56+
0x9a);
57+
populate_gct_entry(
58+
&gdt_table[2],
59+
0x00000000,0x0fffffff,
60+
0b00000000,
61+
0x92);
62+
63+
// Issue#2: For some reason gdtr.base_address assigned is not
64+
// being respected later on. So, as a bad workaround hardcoding
65+
// base_address as &gdtr+8 in stage2.asm.
66+
gdtr.base_address = (int)gdt_table;
67+
gdtr.size = (sizeof(gdt_table));
68+
69+
// Print the table and table addresse.
70+
move_xy(6,14);
71+
print_int((int)&gdtr);
72+
move_xy(6,15);
73+
print_int(gdtr.base_address);
74+
move_xy(6,16);
75+
print_int(gdtr.size);
76+
for(int i=0;i<GDT_TABLE_SIZE;i++) {
77+
move_xy(6,17+i);
78+
print_memory_hex(8*i+(char*)&gdt_table, 8);
79+
}
80+
return (int)&gdtr;
81+
}
882

983
void entry_stage() {
1084
move_xy(6, 11);
@@ -13,8 +87,9 @@ void entry_stage() {
1387
print_line(message_welcome);
1488
set_color_fg(C_WHITE);
1589
move_xy(6, 13);
16-
print_line(message_dashboard);
17-
sleep(100);
18-
run_dashboard(0,0);
19-
while(1);
90+
print_line(message_protected_mode);
91+
int gdtr_address = populate_gdt_table();
92+
// Note: enter_protected_mode never returns.
93+
enter_protected_mode(gdtr_address);
94+
// PC should never reach here :)
2095
}

0 commit comments

Comments
 (0)