Skip to content

Commit 337f91b

Browse files
add head_64.S and main function (#4)
1 parent 0aad394 commit 337f91b

4 files changed

Lines changed: 207 additions & 36 deletions

File tree

.github/workflows/rust-test.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ on:
1111
- "**.ps1"
1212
- "**.yml"
1313
- "**.toml"
14+
- "**.S"
15+
- "**.ld"
1416
- "!**.md"
1517
pull_request:
1618
types: [opened, synchronize]
@@ -21,6 +23,8 @@ on:
2123
- "**.ps1"
2224
- "**.yml"
2325
- "**.toml"
26+
- "**.S"
27+
- "**.ld"
2428
- "!**.md"
2529

2630
env:

crates/rkos-arch/src/x86/head_64.S

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
Bootstrapping x86_64 kernel
3+
see also: https://wiki.osdev.org/Entering_Long_Mode
4+
*/
5+
/* prepare space for 4-level paging to entering long mode
6+
.bss: | PML4 | PML3 | PML2 | Kernel_Stack(.bss.stack)|
7+
| 4kb | 4kb | 4kb | 16kb |
8+
*/
9+
.section .bss
10+
.align 4096
11+
p4_table:
12+
.skip 4096
13+
p3_table:
14+
.skip 4096
15+
p2_table:
16+
.skip 4096
17+
18+
/* Kernel Stack */
19+
.section .bss.stack
20+
.align 16
21+
stack_bottom:
22+
.skip 16384
23+
stack_top:
24+
25+
/*
26+
64-bit Global Descriptor Table (GDT)
27+
see also: https://wiki.osdev.org/Global_Descriptor_Table
28+
*/
29+
30+
/* because of .rodata is read only now,when adding more features,we should move it to .data */
31+
.section .rodata
32+
/* every items in gdt64 is 8 bytes */
33+
.align 8
34+
gdt64:
35+
/* the first item is null */
36+
.quad 0x0000000000000000
37+
38+
/* the second item is 64-bit code segment
39+
Base 63:56 0x00000000
40+
G 55 0
41+
D/B 54 0
42+
L 53 1 (64-bit code segment)
43+
AVL 52 0
44+
Limit 51:48 0x0000
45+
P 47 1
46+
DPL 46:45 0x00
47+
S 44 1
48+
Type 43:40 0x10
49+
Base 39:16 0x000000
50+
Limit 15:0 0x0000
51+
*/
52+
.quad 0x0020980000000000
53+
gdt64_pointer:
54+
/* length of gdt64 minus 1 */
55+
.word 15
56+
/* pointer to gdt64 */
57+
.quad gdt64
58+
59+
/*
60+
multiboot header
61+
see also: https://wiki.osdev.org/Multiboot_Specification
62+
*/
63+
.section .text.entry
64+
.align 4
65+
66+
.global multiboot_header
67+
multiboot_header:
68+
/* 0x1badb002: magic number for multiboot protocol*/
69+
.long 0x1badb002
70+
/* 0x00010000: flags */
71+
.long 0x00010000
72+
/* checksum */
73+
.long -(0x1badb002 + 0x00010000)
74+
75+
/* pointer to multiboot_header */
76+
.long multiboot_header
77+
.long stext
78+
.long edata
79+
.long ebss
80+
.long _start
81+
82+
/*
83+
start of 32-bit code
84+
*/
85+
.global _start
86+
_start:
87+
.code32
88+
/* set stack pointer */
89+
mov esp, offset stack_top
90+
91+
/*
92+
set up temporary page table
93+
map first 2MB of physical memory to virtual memory
94+
*/
95+
mov eax, offset p3_table
96+
or eax, 0b11 /* 0b11 means present and writable */
97+
mov dword ptr [p4_table], eax
98+
99+
/* p3_table[0] -> p2_table */
100+
mov eax, offset p2_table
101+
or eax, 0b11
102+
mov dword ptr [p3_table], eax
103+
104+
/* map first 2MB of physical memory to virtual memory as huge page */
105+
mov eax, 0x83 /* 0x80 (Huge) + 0x02 (Writable) + 0x01 (Present) */
106+
mov dword ptr [p2_table], eax
107+
108+
/* into long mode */
109+
/* step 1: set CR3 to p4_table */
110+
mov eax, offset p4_table
111+
mov cr3, eax
112+
113+
/* step 2: enable PAE in CR4 */
114+
mov eax, cr4
115+
or eax, 1 << 5
116+
mov cr4, eax
117+
118+
/* step 3: enable LME in EFER */
119+
mov ecx, 0xC0000080
120+
rdmsr
121+
or eax, 1 << 8
122+
wrmsr
123+
124+
/* step 4: enable paging in CR0 */
125+
mov eax, cr0
126+
or eax, 1 << 31
127+
mov cr0, eax
128+
129+
/* step 5: load gdt64 */
130+
lgdt [gdt64_pointer]
131+
132+
/* jump to 64-bit code */
133+
push 8 /* push 64-bit code segment */
134+
mov eax, offset long_mode_start
135+
push eax /* push 64-bit code entry point */
136+
retf /* retf to long mode */
137+
138+
.code64
139+
long_mode_start:
140+
/* first thing: set all data segment registers to 0 */
141+
mov ax, 0
142+
mov ss, ax
143+
mov ds, ax
144+
mov es, ax
145+
mov fs, ax
146+
mov gs, ax
147+
148+
/* call _main */
149+
call _main
150+
151+
/* if _main returns, loop forever */
152+
.loop64:
153+
hlt
154+
jmp .loop64

crates/rkos-arch/src/x86/link.ld

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
linker script for x86_64 kernel
3+
see also: https://wiki.osdev.org/Linker_Scripts
4+
*/
15
OUTPUT_ARCH(i386:x86-64)
26
ENTRY(_start)
37

@@ -8,32 +12,40 @@ KERNEL_BASE_ADDRESS = 0x100000;
812
SECTIONS {
913
. = KERNEL_BASE_ADDRESS;
1014

11-
/* kernel code */
15+
/*
16+
.text: kernel code
17+
start at 0x100000
18+
*/
1219
.text : {
1320
stext = .;
14-
*(.text.entry)
21+
*(.text.entry)
1522
*(.text .text.*)
1623
. = ALIGN(4096);
1724
etext = .;
1825
}
19-
20-
/* kernel rodata */
26+
/*
27+
.rodata: kernel rodata
28+
*/
2129
.rodata : {
2230
srodata = .;
2331
*(.rodata .rodata.*)
2432
. = ALIGN(4096);
2533
erodata = .;
2634
}
2735

28-
/* kernel data */
36+
/*
37+
.data: kernel data
38+
*/
2939
.data : {
3040
sdata = .;
3141
*(.data .data.*)
3242
. = ALIGN(4096);
3343
edata = .;
3444
}
3545

36-
/* kernel bss */
46+
/*
47+
.bss: kernel bss
48+
*/
3749
.bss : {
3850
sbss = .;
3951
*(.bss.stack) /* kernel stack */
@@ -43,7 +55,9 @@ SECTIONS {
4355
ebss = .;
4456
}
4557

46-
/* kernel end */
58+
/*
59+
kernel end
60+
*/
4761
. = ALIGN(4096);
4862
ekernel = .;
4963
}

crates/rkos/src/main.rs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,34 @@
44
use core::arch::global_asm;
55
use core::panic::PanicInfo;
66

7-
global_asm!(
8-
r#"
9-
.section .text.entry
10-
.align 4
11-
12-
.global multiboot_header
13-
multiboot_header:
14-
15-
.long 0x1badb002
16-
.long 0x00010000
17-
.long -(0x1badb002 + 0x00010000)
18-
19-
.long multiboot_header
20-
.long stext
21-
.long edata
22-
.long ebss
23-
.long _start
24-
25-
.global _start
26-
_start:
27-
.code32
28-
mov eax, 0x4f4f4f4f
29-
mov dword ptr [0xb8000], eax
30-
31-
.loop:
32-
hlt
33-
jmp .loop
34-
"#
35-
);
7+
#[cfg(target_arch = "x86_64")]
8+
global_asm!(include_str!("../../rkos-arch/src/x86/head_64.S"));
9+
10+
#[unsafe(no_mangle)]
11+
pub extern "C" fn _main() {
12+
// VGA_BASE: 0xb8000
13+
let vga_buffer = 0xb8000 as *mut u8;
14+
15+
let text = b"[OK] Barrensea rkos has conquered 64-bit Long Mode!!!";
16+
let color_byte = 0x0a;
17+
18+
for (i, &byte) in text.iter().enumerate() {
19+
unsafe {
20+
*vga_buffer.add(i * 2) = byte;
21+
*vga_buffer.add(i * 2 + 1) = color_byte;
22+
}
23+
}
24+
25+
unsafe extern "C" {
26+
fn stext();
27+
fn edata();
28+
fn ebss();
29+
}
30+
let _text_size = edata as *const () as usize - stext as *const () as usize;
31+
let _bss_size = ebss as *const () as usize - edata as *const () as usize;
32+
33+
//loop {}
34+
}
3635

3736
#[panic_handler]
3837
fn panic(_info: &PanicInfo) -> ! {

0 commit comments

Comments
 (0)