-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Marcin Kościelnicki
committed
Jun 5, 2018
1 parent
74c578d
commit 41b4dc3
Showing
8 changed files
with
189 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/kernel | ||
/loader | ||
*.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include <stdint.h> | ||
#include "gdt.h" | ||
|
||
extern void stack; | ||
|
||
struct tss { | ||
uint32_t _pad; | ||
uint64_t rsp[3]; | ||
uint64_t _pad2; | ||
uint64_t ist_rsp[7]; | ||
uint32_t _pad3[3]; | ||
} __attribute__((packed)) tss = { | ||
.rsp[0] = &stack, | ||
}; | ||
|
||
_Static_assert(sizeof tss == 0x68, "meh"); | ||
|
||
struct gdt_entry { | ||
uint16_t limit_lo; | ||
uint16_t base_lo; | ||
uint8_t base_mid; | ||
uint8_t flags_a; | ||
uint8_t flags_b; | ||
uint8_t base_hi; | ||
} gdt[] = { | ||
// 0 | ||
{ 0 }, | ||
// 8: kernel code | ||
{ 0, 0, 0, 0x9b, 0xa0, 0 }, | ||
// 0x10: user code 32-bit | ||
{ 0xffff, 0, 0, 0xfb, 0xcf, 0 }, | ||
// 0x18: user data | ||
{ 0xffff, 0, 0, 0xf3, 0xcf, 0 }, | ||
// 0x20: user code 64-bit | ||
{ 0, 0, 0, 0xfb, 0xa0, 0 }, | ||
// 0x28: TSS | ||
{ sizeof tss - 1, 0, 0, 0x89, 0, 0 }, | ||
{ 0, 0, 0, 0, 0, 0 }, | ||
}; | ||
|
||
struct idt_entry { | ||
uint16_t addr_lo; | ||
uint16_t segment; | ||
uint8_t ist; | ||
uint8_t flags; | ||
uint16_t addr_mid; | ||
uint32_t addr_hi; | ||
uint32_t _pad; | ||
} idt[256] = { | ||
{0}, | ||
}; | ||
|
||
void init_gdt() { | ||
uint64_t tss_addr = (uint64_t)&tss; | ||
gdt[5].base_lo = tss_addr; | ||
gdt[5].base_mid = tss_addr >> 16; | ||
gdt[5].base_hi = tss_addr >> 24; | ||
gdt[6].limit_lo = tss_addr >> 32; | ||
gdt[6].base_lo = tss_addr >> 48; | ||
struct gdtr { | ||
uint16_t _pad[3]; | ||
uint16_t limit; | ||
void *addr; | ||
} gdtr = { | ||
{0, 0, 0}, sizeof gdt - 1, &gdt, | ||
}; | ||
struct idtr { | ||
uint16_t _pad[3]; | ||
uint16_t limit; | ||
void *addr; | ||
} idtr = { | ||
{0, 0, 0}, sizeof idt - 1, &idt, | ||
}; | ||
__asm__ volatile ( | ||
"lgdt (%0)" | ||
: | ||
: "r"(&gdtr.limit) | ||
); | ||
__asm__ volatile ( | ||
"lidt (%0)" | ||
: | ||
: "r"(&idtr.limit) | ||
); | ||
__asm__ volatile ( | ||
"ltr %0" | ||
: | ||
: "r"((uint16_t)0x28) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
void init_gdt(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,5 @@ hlt | |
.section .bss | ||
|
||
.skip 0x1000 | ||
.global stack | ||
stack: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,30 @@ | ||
#include <stdint.h> | ||
#include "gdt.h" | ||
#include "page.h" | ||
char hello[] = "Hello, C world!"; | ||
|
||
__asm__( | ||
".text\n" | ||
"go_user:\n" | ||
"pushq $0x1b\n" | ||
"pushq $0\n" | ||
"pushq $0x2\n" | ||
"pushq $0x23\n" | ||
"pushq %rdi\n" | ||
"iretq\n" | ||
); | ||
|
||
_Noreturn void go_user(void *); | ||
|
||
void main() { | ||
init_gdt(); | ||
init_pg(); | ||
map_page(0x31337000, phys_alloc(), 7); | ||
uint8_t *upage = (void *)0x31337000ull; | ||
upage[0] = 0xeb; | ||
upage[1] = 0xfe; | ||
go_user(upage); | ||
for (int i = 0; i < sizeof hello; i++) { | ||
*(uint16_t *)(0xffff8000000b8000 + i * 2) = hello[i] | 0x0f00; | ||
*(uint16_t *)(0x31337000 + i * 2) = hello[i] | 0x0f00; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#include "page.h" | ||
|
||
extern void kbss_end; | ||
uint64_t phys_next = (uint64_t)(&kbss_end - 0xffff800000000000ull); | ||
|
||
uint64_t phys_alloc() { | ||
if (phys_next & 0xfff) { | ||
phys_next |= 0xfff; | ||
phys_next++; | ||
} | ||
uint64_t res = phys_next; | ||
phys_next += 0x1000; | ||
return res; | ||
} | ||
|
||
void map_page(uint64_t virt, uint64_t phys, int flags) { | ||
uint64_t p_ptl4 = read_cr3() & ~0xfffull; | ||
uint64_t *v_ptl4 = P2V(p_ptl4); | ||
int idx1 = virt >> 12 & 0x1ff; | ||
int idx2 = virt >> 21 & 0x1ff; | ||
int idx3 = virt >> 30 & 0x1ff; | ||
int idx4 = virt >> 39 & 0x1ff; | ||
if (!v_ptl4[idx4]) | ||
v_ptl4[idx4] = phys_alloc() | 7; | ||
uint64_t p_ptl3 = v_ptl4[idx4] & ~0xfffull; | ||
uint64_t *v_ptl3 = P2V(p_ptl3); | ||
if (!v_ptl3[idx3]) | ||
v_ptl3[idx3] = phys_alloc() | 7; | ||
uint64_t p_ptl2 = v_ptl3[idx3] & ~0xfffull; | ||
uint64_t *v_ptl2 = P2V(p_ptl2); | ||
if (!v_ptl2[idx2]) | ||
v_ptl2[idx2] = phys_alloc() | 7; | ||
uint64_t p_ptl1 = v_ptl2[idx2] & ~0xfffull; | ||
uint64_t *v_ptl1 = P2V(p_ptl1); | ||
v_ptl1[idx1] = phys | flags; | ||
} | ||
|
||
void init_pg() { | ||
uint64_t p_ptl4 = read_cr3() & ~0xfffull; | ||
uint64_t *v_ptl4 = P2V(p_ptl4); | ||
v_ptl4[0] = 0; | ||
write_cr3(read_cr3()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <stdint.h> | ||
|
||
static inline void *P2V(uint64_t p) { | ||
return (void *)(0xffff800000000000ull + p); | ||
} | ||
|
||
static inline uint64_t read_cr3() { | ||
uint64_t res; | ||
__asm__ volatile( | ||
"movq %%cr3, %0" | ||
: "=r"(res) | ||
: | ||
); | ||
return res; | ||
} | ||
|
||
static inline void write_cr3(uint64_t val) { | ||
__asm__ volatile( | ||
"movq %0, %%cr3" | ||
: | ||
: "r"(val) | ||
); | ||
} | ||
|
||
uint64_t phys_alloc(); | ||
void init_pg(); | ||
void map_page(uint64_t virt, uint64_t phys, int flags); |