Run first app from ramdisk!
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@ iso_root
|
|||||||
mop3.iso
|
mop3.iso
|
||||||
bochs-log.txt
|
bochs-log.txt
|
||||||
bochs-com1.txt
|
bochs-com1.txt
|
||||||
|
mop3dist.tar
|
||||||
|
|||||||
13
Makefile
13
Makefile
@@ -1,12 +1,5 @@
|
|||||||
platform ?= amd64
|
platform ?= amd64
|
||||||
|
|
||||||
all_kernel:
|
include apps.mk
|
||||||
make -C kernel platform=$(platform) all
|
include kernel.mk
|
||||||
|
include dist.mk
|
||||||
clean_kernel:
|
|
||||||
make -C kernel platform=$(platform) clean
|
|
||||||
|
|
||||||
format_kernel:
|
|
||||||
make -C kernel platform=$(platform) format
|
|
||||||
|
|
||||||
.PHONY: all_kernel clean_kernel format_kernel
|
|
||||||
|
|||||||
10
amd64/flags.mk
Normal file
10
amd64/flags.mk
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
cflags += --target=x86_64-pc-none-elf \
|
||||||
|
-mno-sse \
|
||||||
|
-mno-sse2 \
|
||||||
|
-mno-avx \
|
||||||
|
-mno-mmx \
|
||||||
|
-mno-80387 \
|
||||||
|
-mno-red-zone
|
||||||
|
|
||||||
|
ldflags += --target=x86_64-pc-none-elf \
|
||||||
|
-Wl,-zmax-page-size=0x1000
|
||||||
42
amd64/link.ld
Normal file
42
amd64/link.ld
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
OUTPUT_FORMAT(elf64-x86-64)
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
PHDRS {
|
||||||
|
text PT_LOAD;
|
||||||
|
rodata PT_LOAD;
|
||||||
|
data PT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0x0000000050000000;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.text .text.*)
|
||||||
|
} :text
|
||||||
|
|
||||||
|
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
} :rodata
|
||||||
|
|
||||||
|
.note.gnu.build-id : {
|
||||||
|
*(.note.gnu.build-id)
|
||||||
|
} :rodata
|
||||||
|
|
||||||
|
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.*)
|
||||||
|
} :data
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
*(.bss .bss.*)
|
||||||
|
} :data
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.eh_frame*)
|
||||||
|
*(.note .note.*)
|
||||||
|
}
|
||||||
|
}
|
||||||
9
apps.mk
Normal file
9
apps.mk
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
apps := init
|
||||||
|
|
||||||
|
all_apps:
|
||||||
|
@for d in $(apps); do make -C $$d platform=$(platform) all; done
|
||||||
|
|
||||||
|
clean_apps:
|
||||||
|
@for d in $(apps); do make -C $$d platform=$(platform) clean; done
|
||||||
|
|
||||||
|
.PHONY: all_apps clean_apps
|
||||||
13
aux/devel.sh
Executable file
13
aux/devel.sh
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
if [ "$1" = "debug" ]; then
|
||||||
|
make -B all_kernel buildtype=debug
|
||||||
|
else
|
||||||
|
make -B all_kernel
|
||||||
|
fi
|
||||||
|
|
||||||
|
make -B all_apps
|
||||||
|
make -B all_dist
|
||||||
|
./aux/limine_iso_amd64.sh
|
||||||
@@ -10,6 +10,8 @@ cp -v boot/limine/limine-bios.sys boot/limine/limine-bios-cd.bin \
|
|||||||
|
|
||||||
cp -v boot/limine/BOOTX64.EFI boot/limine/BOOTIA32.EFI iso_root/EFI/BOOT
|
cp -v boot/limine/BOOTX64.EFI boot/limine/BOOTIA32.EFI iso_root/EFI/BOOT
|
||||||
|
|
||||||
|
cp -v mop3dist.tar iso_root/boot
|
||||||
|
|
||||||
xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \
|
xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \
|
||||||
-no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
|
-no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
|
||||||
-apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \
|
-apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
qemu-system-x86_64 -M q35 -m 4G -serial stdio -enable-kvm -cdrom mop3.iso $@
|
qemu-system-x86_64 -M q35 -m 4G -serial stdio -enable-kvm -cdrom mop3.iso -smp 4 $@
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ timeout: 10
|
|||||||
/mop3
|
/mop3
|
||||||
protocol: limine
|
protocol: limine
|
||||||
path: boot():/boot/kernel.elf
|
path: boot():/boot/kernel.elf
|
||||||
|
module_path: boot():/boot/mop3dist.tar
|
||||||
|
|||||||
8
dist.mk
Normal file
8
dist.mk
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
exe := $(foreach d,$(apps),$(wildcard $(d)/*.exe))
|
||||||
|
|
||||||
|
all_dist: mop3dist.tar
|
||||||
|
|
||||||
|
mop3dist.tar:
|
||||||
|
tar -cf $@ --transform='s|.*/||' $(exe)
|
||||||
|
|
||||||
|
.PHONY: all_dist
|
||||||
15
generic/flags.mk
Normal file
15
generic/flags.mk
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
cflags += -nostdinc \
|
||||||
|
-nostdlib \
|
||||||
|
-ffreestanding \
|
||||||
|
-fno-builtin \
|
||||||
|
-std=c11 \
|
||||||
|
-pedantic \
|
||||||
|
-Wall \
|
||||||
|
-Wextra \
|
||||||
|
-mcmodel=kernel
|
||||||
|
|
||||||
|
ldflags += -ffreestanding \
|
||||||
|
-nostdlib \
|
||||||
|
-fno-builtin \
|
||||||
|
-fuse-ld=lld \
|
||||||
|
-static
|
||||||
2
init/.gitignore
vendored
Normal file
2
init/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*.o
|
||||||
|
*.exe
|
||||||
1
init/Makefile
Normal file
1
init/Makefile
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include ../user.mk
|
||||||
1
init/app.mk
Normal file
1
init/app.mk
Normal file
@@ -0,0 +1 @@
|
|||||||
|
app := init.exe
|
||||||
5
init/init.S
Normal file
5
init/init.S
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
pushq $123
|
||||||
|
addq $8, %rsp
|
||||||
|
jmp _start
|
||||||
3
init/src.mk
Normal file
3
init/src.mk
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
S += init.S
|
||||||
|
|
||||||
|
o += init.o
|
||||||
10
kernel.mk
Normal file
10
kernel.mk
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
all_kernel:
|
||||||
|
make -C kernel platform=$(platform) all
|
||||||
|
|
||||||
|
clean_kernel:
|
||||||
|
make -C kernel platform=$(platform) clean
|
||||||
|
|
||||||
|
format_kernel:
|
||||||
|
make -C kernel platform=$(platform) format
|
||||||
|
|
||||||
|
.PHONY: all_kernel clean_kernel format_kernel
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <amd64/apic.h>
|
#include <amd64/apic.h>
|
||||||
|
#include <amd64/intr_defs.h>
|
||||||
#include <amd64/msr-index.h>
|
#include <amd64/msr-index.h>
|
||||||
#include <amd64/msr.h>
|
#include <amd64/msr.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
@@ -14,10 +15,10 @@
|
|||||||
#define IOAPICS_MAX 24
|
#define IOAPICS_MAX 24
|
||||||
#define INTERRUPT_SRC_OVERRIDES_MAX 24
|
#define INTERRUPT_SRC_OVERRIDES_MAX 24
|
||||||
|
|
||||||
#define LAPIC_ID 0x20 /* ID */
|
#define LAPIC_ID 0x20 /* ID */
|
||||||
#define LAPIC_EOI 0xB0 /* End of interrupt */
|
#define LAPIC_EOI 0xB0 /* End of interrupt */
|
||||||
#define LAPIC_SIVR 0xF0 /* Spurious interrupt vector register */
|
#define LAPIC_SIVR 0xF0 /* Spurious interrupt vector register */
|
||||||
#define LAPIC_ICR 0x300
|
#define LAPIC_ICR 0x300 /* Interrupt command register */
|
||||||
#define LAPIC_LVTTR 0x320 /* LVT timer register */
|
#define LAPIC_LVTTR 0x320 /* LVT timer register */
|
||||||
#define LAPIC_TIMICT 0x380 /* Initial count register */
|
#define LAPIC_TIMICT 0x380 /* Initial count register */
|
||||||
#define LAPIC_TIMCCT 0x390 /* Current count register */
|
#define LAPIC_TIMCCT 0x390 /* Current count register */
|
||||||
@@ -60,7 +61,7 @@ static struct acpi_madt_ioapic* amd64_ioapic_find (uint8_t irq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void amd64_ioapic_route_irq (uint8_t vec, uint8_t irq, uint64_t flags, uint64_t lapic_id) {
|
void amd64_ioapic_route_irq (uint8_t vec, uint8_t irq, uint64_t flags, uint64_t lapic_id) {
|
||||||
struct acpi_madt_ioapic* apic;
|
struct acpi_madt_ioapic* apic = NULL;
|
||||||
struct acpi_madt_interrupt_source_override* override;
|
struct acpi_madt_interrupt_source_override* override;
|
||||||
bool found_override = false;
|
bool found_override = false;
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
@@ -155,7 +156,7 @@ void amd64_ioapic_init (void) {
|
|||||||
struct acpi_madt_ioapic* ioapic = (struct acpi_madt_ioapic*)current;
|
struct acpi_madt_ioapic* ioapic = (struct acpi_madt_ioapic*)current;
|
||||||
mm_map_kernel_page ((uintptr_t)ioapic->address,
|
mm_map_kernel_page ((uintptr_t)ioapic->address,
|
||||||
(uintptr_t)hhdm->offset + (uintptr_t)ioapic->address,
|
(uintptr_t)hhdm->offset + (uintptr_t)ioapic->address,
|
||||||
MM_PG_PRESENT | MM_PG_RW);
|
MM_PG_PRESENT | MM_PG_RW | MM_PD_RELOAD);
|
||||||
apics[ioapic_entries++] = *ioapic;
|
apics[ioapic_entries++] = *ioapic;
|
||||||
} break;
|
} break;
|
||||||
case ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE: {
|
case ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE: {
|
||||||
@@ -188,7 +189,7 @@ void amd64_lapic_tick (uint32_t tick) { amd64_lapic_write (LAPIC_TIMICT, tick);
|
|||||||
static uint32_t amd64_lapic_calibrate (uint32_t us) {
|
static uint32_t amd64_lapic_calibrate (uint32_t us) {
|
||||||
amd64_lapic_write (LAPIC_DCR, 0x03);
|
amd64_lapic_write (LAPIC_DCR, 0x03);
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_LVTTR, 0x20 | (1 << 16));
|
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 16));
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_TIMICT, 0xFFFFFFFF);
|
amd64_lapic_write (LAPIC_TIMICT, 0xFFFFFFFF);
|
||||||
|
|
||||||
@@ -202,7 +203,7 @@ static uint32_t amd64_lapic_calibrate (uint32_t us) {
|
|||||||
static void amd64_lapic_start (uint32_t ticks) {
|
static void amd64_lapic_start (uint32_t ticks) {
|
||||||
amd64_lapic_write (LAPIC_DCR, 0x03);
|
amd64_lapic_write (LAPIC_DCR, 0x03);
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_LVTTR, 0x20 | (1 << 17));
|
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 17));
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_TIMICT, ticks);
|
amd64_lapic_write (LAPIC_TIMICT, ticks);
|
||||||
}
|
}
|
||||||
@@ -215,7 +216,8 @@ uint64_t amd64_lapic_init (uint32_t us) {
|
|||||||
uintptr_t lapic_paddr = amd64_rdmsr (MSR_APIC_BASE) & 0xFFFFF000;
|
uintptr_t lapic_paddr = amd64_rdmsr (MSR_APIC_BASE) & 0xFFFFF000;
|
||||||
lapic_mmio_base = lapic_paddr + (uintptr_t)hhdm->offset;
|
lapic_mmio_base = lapic_paddr + (uintptr_t)hhdm->offset;
|
||||||
|
|
||||||
mm_map_kernel_page (lapic_paddr, lapic_mmio_base, MM_PG_PRESENT | MM_PG_RW | MM_PD_LOCK);
|
mm_map_kernel_page (lapic_paddr, lapic_mmio_base,
|
||||||
|
MM_PG_PRESENT | MM_PG_RW | MM_PD_LOCK | MM_PD_RELOAD);
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_SIVR, 0xFF | (1 << 8));
|
amd64_lapic_write (LAPIC_SIVR, 0xFF | (1 << 8));
|
||||||
|
|
||||||
@@ -225,3 +227,8 @@ uint64_t amd64_lapic_init (uint32_t us) {
|
|||||||
|
|
||||||
return ticks;
|
return ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amd64_lapic_ipi (uint8_t lapic_id, uint8_t vec) {
|
||||||
|
amd64_lapic_write (LAPIC_ICR + 0x10, (lapic_id << 24));
|
||||||
|
amd64_lapic_write (LAPIC_ICR, vec);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ void amd64_ioapic_init (void);
|
|||||||
uint32_t amd64_lapic_id (void);
|
uint32_t amd64_lapic_id (void);
|
||||||
void amd64_lapic_tick (uint32_t tick);
|
void amd64_lapic_tick (uint32_t tick);
|
||||||
void amd64_lapic_eoi (void);
|
void amd64_lapic_eoi (void);
|
||||||
|
void amd64_lapic_ipi (uint8_t lapic_id, uint8_t vec);
|
||||||
uint64_t amd64_lapic_init (uint32_t us);
|
uint64_t amd64_lapic_init (uint32_t us);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_APIC_H
|
#endif // _KERNEL_AMD64_APIC_H
|
||||||
|
|||||||
@@ -2,11 +2,15 @@
|
|||||||
#include <amd64/debug.h>
|
#include <amd64/debug.h>
|
||||||
#include <amd64/hpet.h>
|
#include <amd64/hpet.h>
|
||||||
#include <amd64/init.h>
|
#include <amd64/init.h>
|
||||||
|
#include <amd64/intr_defs.h>
|
||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
#include <irq/irq.h>
|
#include <irq/irq.h>
|
||||||
|
#include <libk/std.h>
|
||||||
#include <limine/limine.h>
|
#include <limine/limine.h>
|
||||||
#include <mm/liballoc.h>
|
#include <mm/liballoc.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
|
#include <proc/proc.h>
|
||||||
|
#include <rd/rd.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
#include <sys/mm.h>
|
#include <sys/mm.h>
|
||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
@@ -17,11 +21,6 @@
|
|||||||
|
|
||||||
ALIGNED (16) static uint8_t uacpi_memory_buffer[UACPI_MEMORY_BUFFER_MAX];
|
ALIGNED (16) static uint8_t uacpi_memory_buffer[UACPI_MEMORY_BUFFER_MAX];
|
||||||
|
|
||||||
void ack (void* arg) {
|
|
||||||
(void)arg;
|
|
||||||
debugprintf (". %u\n", thiscpu->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bootmain (void) {
|
void bootmain (void) {
|
||||||
struct cpu* bsp_cpu = cpu_make ();
|
struct cpu* bsp_cpu = cpu_make ();
|
||||||
cpu_assign (bsp_cpu->id);
|
cpu_assign (bsp_cpu->id);
|
||||||
@@ -31,6 +30,8 @@ void bootmain (void) {
|
|||||||
pmm_init ();
|
pmm_init ();
|
||||||
mm_init ();
|
mm_init ();
|
||||||
|
|
||||||
|
rd_init ();
|
||||||
|
|
||||||
uacpi_setup_early_table_access ((void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
|
uacpi_setup_early_table_access ((void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
|
||||||
|
|
||||||
amd64_ioapic_init ();
|
amd64_ioapic_init ();
|
||||||
@@ -38,10 +39,16 @@ void bootmain (void) {
|
|||||||
|
|
||||||
smp_init ();
|
smp_init ();
|
||||||
|
|
||||||
irq_attach (&ack, NULL, 32 + 0);
|
/* busy wait for cpus to come online */
|
||||||
|
for (volatile int i = 0; i < INT_MAX; i++)
|
||||||
|
;
|
||||||
|
|
||||||
|
mm_init2 ();
|
||||||
|
|
||||||
__asm__ volatile ("sti");
|
__asm__ volatile ("sti");
|
||||||
|
|
||||||
|
proc_init ();
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
#include <proc/proc.h>
|
||||||
|
|
||||||
#define KSTACK_SIZE (16 * 1024)
|
#define KSTACK_SIZE (32 * 1024)
|
||||||
|
|
||||||
struct gdt_entry {
|
struct gdt_entry {
|
||||||
uint16_t limitlow;
|
uint16_t limitlow;
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ void amd64_hpet_init (void) {
|
|||||||
hpet_paddr = (uintptr_t)hpet->address.address;
|
hpet_paddr = (uintptr_t)hpet->address.address;
|
||||||
|
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
mm_map_kernel_page (hpet_paddr, (uintptr_t)hhdm->offset + hpet_paddr, MM_PG_PRESENT | MM_PG_RW);
|
mm_map_kernel_page (hpet_paddr, (uintptr_t)hhdm->offset + hpet_paddr,
|
||||||
|
MM_PG_PRESENT | MM_PG_RW | MM_PD_RELOAD);
|
||||||
|
|
||||||
hpet_32bits = (amd64_hpet_read (HPET_GCIDR) & (1 << 13)) ? 0 : 1;
|
hpet_32bits = (amd64_hpet_read (HPET_GCIDR) & (1 << 13)) ? 0 : 1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <amd64/apic.h>
|
#include <amd64/apic.h>
|
||||||
#include <amd64/intr.h>
|
#include <amd64/intr.h>
|
||||||
|
#include <amd64/intr_defs.h>
|
||||||
#include <amd64/io.h>
|
#include <amd64/io.h>
|
||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
#include <irq/irq.h>
|
#include <irq/irq.h>
|
||||||
@@ -100,54 +101,23 @@ static void amd64_idt_init (void) {
|
|||||||
#define IDT_ENTRY(n, ist) \
|
#define IDT_ENTRY(n, ist) \
|
||||||
extern void amd64_intr##n (void); \
|
extern void amd64_intr##n (void); \
|
||||||
amd64_idt_set (&idt_entries[(n)], (uint64_t)&amd64_intr##n, 0x8E, (ist))
|
amd64_idt_set (&idt_entries[(n)], (uint64_t)&amd64_intr##n, 0x8E, (ist))
|
||||||
IDT_ENTRY (0, 0);
|
/* clang-format off */
|
||||||
IDT_ENTRY (1, 0);
|
IDT_ENTRY (0, 0); IDT_ENTRY (1, 0); IDT_ENTRY (2, 0); IDT_ENTRY (3, 0);
|
||||||
IDT_ENTRY (2, 0);
|
IDT_ENTRY (4, 0); IDT_ENTRY (5, 0); IDT_ENTRY (6, 0); IDT_ENTRY (7, 0);
|
||||||
IDT_ENTRY (3, 0);
|
IDT_ENTRY (8, 0); IDT_ENTRY (9, 0); IDT_ENTRY (10, 0); IDT_ENTRY (11, 0);
|
||||||
IDT_ENTRY (4, 0);
|
IDT_ENTRY (12, 0); IDT_ENTRY (13, 0); IDT_ENTRY (14, 0); IDT_ENTRY (15, 0);
|
||||||
IDT_ENTRY (5, 0);
|
IDT_ENTRY (16, 0); IDT_ENTRY (17, 0); IDT_ENTRY (18, 0); IDT_ENTRY (19, 0);
|
||||||
IDT_ENTRY (6, 0);
|
IDT_ENTRY (20, 0); IDT_ENTRY (21, 0); IDT_ENTRY (22, 0); IDT_ENTRY (23, 0);
|
||||||
IDT_ENTRY (7, 0);
|
IDT_ENTRY (24, 0); IDT_ENTRY (25, 0); IDT_ENTRY (26, 0); IDT_ENTRY (27, 0);
|
||||||
IDT_ENTRY (8, 0);
|
IDT_ENTRY (28, 0); IDT_ENTRY (29, 0); IDT_ENTRY (30, 0); IDT_ENTRY (31, 0);
|
||||||
IDT_ENTRY (9, 0);
|
IDT_ENTRY (32, 1); IDT_ENTRY (33, 1); IDT_ENTRY (34, 1); IDT_ENTRY (35, 1);
|
||||||
IDT_ENTRY (10, 0);
|
IDT_ENTRY (36, 1); IDT_ENTRY (37, 1); IDT_ENTRY (38, 1); IDT_ENTRY (39, 1);
|
||||||
IDT_ENTRY (11, 0);
|
IDT_ENTRY (40, 1); IDT_ENTRY (41, 1); IDT_ENTRY (42, 1); IDT_ENTRY (43, 1);
|
||||||
IDT_ENTRY (12, 0);
|
IDT_ENTRY (44, 1); IDT_ENTRY (45, 1); IDT_ENTRY (46, 1); IDT_ENTRY (47, 1);
|
||||||
IDT_ENTRY (13, 0);
|
|
||||||
IDT_ENTRY (14, 0);
|
IDT_ENTRY (SCHED_PREEMPT_TIMER, 1);
|
||||||
IDT_ENTRY (15, 0);
|
IDT_ENTRY (TLB_SHOOTDOWN, 1);
|
||||||
IDT_ENTRY (16, 0);
|
/* clang-format on */
|
||||||
IDT_ENTRY (17, 0);
|
|
||||||
IDT_ENTRY (18, 0);
|
|
||||||
IDT_ENTRY (19, 0);
|
|
||||||
IDT_ENTRY (20, 0);
|
|
||||||
IDT_ENTRY (21, 0);
|
|
||||||
IDT_ENTRY (22, 0);
|
|
||||||
IDT_ENTRY (23, 0);
|
|
||||||
IDT_ENTRY (24, 0);
|
|
||||||
IDT_ENTRY (25, 0);
|
|
||||||
IDT_ENTRY (26, 0);
|
|
||||||
IDT_ENTRY (27, 0);
|
|
||||||
IDT_ENTRY (28, 0);
|
|
||||||
IDT_ENTRY (29, 0);
|
|
||||||
IDT_ENTRY (30, 0);
|
|
||||||
IDT_ENTRY (31, 0);
|
|
||||||
IDT_ENTRY (32, 1);
|
|
||||||
IDT_ENTRY (33, 1);
|
|
||||||
IDT_ENTRY (34, 1);
|
|
||||||
IDT_ENTRY (35, 1);
|
|
||||||
IDT_ENTRY (36, 1);
|
|
||||||
IDT_ENTRY (37, 1);
|
|
||||||
IDT_ENTRY (38, 1);
|
|
||||||
IDT_ENTRY (39, 1);
|
|
||||||
IDT_ENTRY (40, 1);
|
|
||||||
IDT_ENTRY (41, 1);
|
|
||||||
IDT_ENTRY (42, 1);
|
|
||||||
IDT_ENTRY (43, 1);
|
|
||||||
IDT_ENTRY (44, 1);
|
|
||||||
IDT_ENTRY (45, 1);
|
|
||||||
IDT_ENTRY (46, 1);
|
|
||||||
IDT_ENTRY (47, 1);
|
|
||||||
#undef IDT_ENTRY
|
#undef IDT_ENTRY
|
||||||
|
|
||||||
idt.limit = sizeof (idt_entries) - 1;
|
idt.limit = sizeof (idt_entries) - 1;
|
||||||
@@ -177,7 +147,11 @@ static void amd64_intr_exception (struct saved_regs* regs) {
|
|||||||
regs->error, regs->rip, regs->cs, regs->rflags, regs->rsp, regs->ss, cr2, cr3,
|
regs->error, regs->rip, regs->cs, regs->rflags, regs->rsp, regs->ss, cr2, cr3,
|
||||||
regs->rbx);
|
regs->rbx);
|
||||||
|
|
||||||
amd64_spin ();
|
if (regs->cs == (0x18 | 0x03)) {
|
||||||
|
proc_kill (thiscpu->proc_current);
|
||||||
|
} else {
|
||||||
|
amd64_spin ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void amd64_intr_handler (void* stack_ptr) {
|
void amd64_intr_handler (void* stack_ptr) {
|
||||||
@@ -185,16 +159,20 @@ void amd64_intr_handler (void* stack_ptr) {
|
|||||||
|
|
||||||
if (regs->trap <= 31) {
|
if (regs->trap <= 31) {
|
||||||
amd64_intr_exception (regs);
|
amd64_intr_exception (regs);
|
||||||
} else if (regs->trap >= 32) {
|
} else {
|
||||||
amd64_lapic_eoi ();
|
amd64_lapic_eoi ();
|
||||||
|
|
||||||
__asm__ volatile ("sti");
|
struct irq* irq = irq_find (regs->trap);
|
||||||
|
|
||||||
irq_invoke_each (regs->trap);
|
if (irq != NULL) {
|
||||||
|
if (!(irq->flags & IRQ_INTERRUPT_SAFE))
|
||||||
|
__asm__ volatile ("sti");
|
||||||
|
|
||||||
__asm__ volatile ("cli");
|
irq->func (irq->arg, stack_ptr);
|
||||||
} else {
|
|
||||||
DEBUG ("unknown trap %lu\n", regs->trap);
|
if (!(irq->flags & IRQ_INTERRUPT_SAFE))
|
||||||
|
__asm__ volatile ("cli");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,3 +213,12 @@ void irq_restore (void) {
|
|||||||
if (prev == 1)
|
if (prev == 1)
|
||||||
amd64_irq_restore_flags (thiscpu->irq_ctx.rflags);
|
amd64_irq_restore_flags (thiscpu->irq_ctx.rflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t amd64_resolve_irq (uint8_t irq) {
|
||||||
|
static const uint8_t mappings[] = {
|
||||||
|
[SCHED_PREEMPT_TIMER] = 0,
|
||||||
|
[TLB_SHOOTDOWN] = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
return mappings[irq];
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ struct saved_regs {
|
|||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
void amd64_load_idt (void);
|
void amd64_load_idt (void);
|
||||||
|
uint8_t amd64_resolve_irq (uint8_t irq);
|
||||||
void amd64_intr_init (void);
|
void amd64_intr_init (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_INTR_H
|
#endif // _KERNEL_AMD64_INTR_H
|
||||||
|
|||||||
7
kernel/amd64/intr_defs.h
Normal file
7
kernel/amd64/intr_defs.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _KERNEL_AMD64_INTR_DEFS_H
|
||||||
|
#define _KERNEL_AMD64_INTR_DEFS_H
|
||||||
|
|
||||||
|
#define SCHED_PREEMPT_TIMER 80
|
||||||
|
#define TLB_SHOOTDOWN 81
|
||||||
|
|
||||||
|
#endif // _KERNEL_AMD64_INTR_DEFS_H
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include <amd64/intr_defs.h>
|
||||||
|
|
||||||
.extern amd64_intr_handler
|
.extern amd64_intr_handler
|
||||||
|
|
||||||
#define err(z) \
|
#define err(z) \
|
||||||
@@ -108,3 +110,6 @@ make_intr_stub(no_err, 44)
|
|||||||
make_intr_stub(no_err, 45)
|
make_intr_stub(no_err, 45)
|
||||||
make_intr_stub(no_err, 46)
|
make_intr_stub(no_err, 46)
|
||||||
make_intr_stub(no_err, 47)
|
make_intr_stub(no_err, 47)
|
||||||
|
|
||||||
|
make_intr_stub(no_err, SCHED_PREEMPT_TIMER)
|
||||||
|
make_intr_stub(no_err, TLB_SHOOTDOWN)
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
|
#include <amd64/apic.h>
|
||||||
|
#include <amd64/intr_defs.h>
|
||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
|
#include <irq/irq.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
#include <limine/requests.h>
|
#include <limine/requests.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
#include <sys/mm.h>
|
#include <sys/mm.h>
|
||||||
|
#include <sys/smp.h>
|
||||||
|
|
||||||
#define AMD64_PG_PRESENT (1 << 0)
|
#define AMD64_PG_PRESENT (1 << 0)
|
||||||
#define AMD64_PG_RW (1 << 1)
|
#define AMD64_PG_RW (1 << 1)
|
||||||
#define AMD64_PG_USER (1 << 2)
|
#define AMD64_PG_USER (1 << 2)
|
||||||
|
|
||||||
#define AMD64_PG_TABLE_ENTRIES_MAX 512
|
|
||||||
|
|
||||||
struct pg_index {
|
struct pg_index {
|
||||||
uint16_t pml4, pml3, pml2, pml1;
|
uint16_t pml4, pml3, pml2, pml1;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
struct pd kernel_pd = {.lock = SPIN_LOCK_INIT};
|
static struct pd kernel_pd = {.lock = SPIN_LOCK_INIT};
|
||||||
|
/* This is needed to sync between map/unmap operations and TLB shootdown. */
|
||||||
|
static spin_lock_t mm_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
static uintptr_t amd64_current_cr3 (void) {
|
static uintptr_t amd64_current_cr3 (void) {
|
||||||
uintptr_t cr3;
|
uintptr_t cr3;
|
||||||
@@ -41,7 +46,7 @@ static struct pg_index amd64_mm_page_index (uint64_t vaddr) {
|
|||||||
|
|
||||||
static uint64_t* amd64_mm_next_table (uint64_t* table, uint64_t entry_idx, bool alloc) {
|
static uint64_t* amd64_mm_next_table (uint64_t* table, uint64_t entry_idx, bool alloc) {
|
||||||
uint64_t entry = table[entry_idx];
|
uint64_t entry = table[entry_idx];
|
||||||
uint64_t paddr;
|
physaddr_t paddr;
|
||||||
|
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
@@ -53,11 +58,11 @@ static uint64_t* amd64_mm_next_table (uint64_t* table, uint64_t entry_idx, bool
|
|||||||
|
|
||||||
paddr = pmm_alloc (1);
|
paddr = pmm_alloc (1);
|
||||||
|
|
||||||
if (paddr == 0)
|
if (paddr == PMM_ALLOC_ERR)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset ((void*)((uintptr_t)hhdm->offset + (uintptr_t)paddr), 0, PAGE_SIZE);
|
memset ((void*)((uintptr_t)hhdm->offset + (uintptr_t)paddr), 0, PAGE_SIZE);
|
||||||
table[entry_idx] = paddr | AMD64_PG_PRESENT | AMD64_PG_RW;
|
table[entry_idx] = paddr | AMD64_PG_PRESENT | AMD64_PG_RW | AMD64_PG_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint64_t*)((uintptr_t)hhdm->offset + (uintptr_t)paddr);
|
return (uint64_t*)((uintptr_t)hhdm->offset + (uintptr_t)paddr);
|
||||||
@@ -79,6 +84,8 @@ static void amd64_reload_cr3 (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
||||||
|
spin_lock (&mm_lock);
|
||||||
|
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
bool do_reload = false;
|
bool do_reload = false;
|
||||||
|
|
||||||
@@ -108,11 +115,13 @@ void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flag
|
|||||||
do_reload = true;
|
do_reload = true;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (do_reload)
|
if (do_reload && (flags & MM_PD_RELOAD))
|
||||||
amd64_reload_cr3 ();
|
amd64_reload_cr3 ();
|
||||||
|
|
||||||
if (flags & MM_PD_LOCK)
|
if (flags & MM_PD_LOCK)
|
||||||
spin_unlock (&pd->lock);
|
spin_unlock (&pd->lock);
|
||||||
|
|
||||||
|
spin_unlock (&mm_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
||||||
@@ -120,6 +129,8 @@ void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags) {
|
void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags) {
|
||||||
|
spin_lock (&mm_lock);
|
||||||
|
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
bool do_reload = false;
|
bool do_reload = false;
|
||||||
|
|
||||||
@@ -129,15 +140,15 @@ void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags) {
|
|||||||
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
||||||
struct pg_index pg_index = amd64_mm_page_index (vaddr);
|
struct pg_index pg_index = amd64_mm_page_index (vaddr);
|
||||||
|
|
||||||
uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, true);
|
uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, false);
|
||||||
if (pml3 == NULL)
|
if (pml3 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, true);
|
uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, false);
|
||||||
if (pml2 == NULL)
|
if (pml2 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, true);
|
uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, false);
|
||||||
if (pml1 == NULL)
|
if (pml1 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -147,11 +158,13 @@ void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags) {
|
|||||||
do_reload = true;
|
do_reload = true;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (do_reload)
|
if (do_reload && (flags & MM_PD_RELOAD))
|
||||||
amd64_reload_cr3 ();
|
amd64_reload_cr3 ();
|
||||||
|
|
||||||
if (flags & MM_PD_LOCK)
|
if (flags & MM_PD_LOCK)
|
||||||
spin_unlock (&pd->lock);
|
spin_unlock (&pd->lock);
|
||||||
|
|
||||||
|
spin_unlock (&mm_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm_unmap_kernel_page (uintptr_t vaddr, uint32_t flags) {
|
void mm_unmap_kernel_page (uintptr_t vaddr, uint32_t flags) {
|
||||||
@@ -162,4 +175,44 @@ void mm_lock_kernel (void) { spin_lock (&kernel_pd.lock); }
|
|||||||
|
|
||||||
void mm_unlock_kernel (void) { spin_unlock (&kernel_pd.lock); }
|
void mm_unlock_kernel (void) { spin_unlock (&kernel_pd.lock); }
|
||||||
|
|
||||||
|
uintptr_t mm_alloc_user_pd_phys (void) {
|
||||||
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
|
physaddr_t cr3 = pmm_alloc (1);
|
||||||
|
if (cr3 == PMM_ALLOC_ERR)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint8_t* vu_cr3 = (uint8_t*)((uintptr_t)hhdm->offset + cr3);
|
||||||
|
memset ((void*)vu_cr3, 0, PAGE_SIZE / 2);
|
||||||
|
|
||||||
|
uint8_t* vk_cr3 = (uint8_t*)((uintptr_t)hhdm->offset + (uintptr_t)kernel_pd.cr3_paddr);
|
||||||
|
|
||||||
|
memcpy (&vu_cr3[PAGE_SIZE / 2], &vk_cr3[PAGE_SIZE / 2], PAGE_SIZE / 2);
|
||||||
|
|
||||||
|
return cr3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mm_reload (void) {
|
||||||
|
spin_lock (&mm_lock);
|
||||||
|
|
||||||
|
struct limine_mp_response* mp = limine_mp_request.response;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mp->cpu_count; i++) {
|
||||||
|
amd64_lapic_ipi (mp->cpus[i]->lapic_id, TLB_SHOOTDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock (&mm_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amd64_tlb_shootdown_irq (void* arg, void* regs) {
|
||||||
|
(void)arg, (void)regs;
|
||||||
|
|
||||||
|
amd64_reload_cr3 ();
|
||||||
|
DEBUG ("cpu %u TLB shootdown\n", thiscpu->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mm_init2 (void) {
|
||||||
|
irq_attach (&amd64_tlb_shootdown_irq, NULL, TLB_SHOOTDOWN, IRQ_INTERRUPT_SAFE);
|
||||||
|
}
|
||||||
|
|
||||||
void mm_init (void) { kernel_pd.cr3_paddr = amd64_current_cr3 (); }
|
void mm_init (void) { kernel_pd.cr3_paddr = amd64_current_cr3 (); }
|
||||||
|
|||||||
@@ -12,5 +12,6 @@ struct pd {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void amd64_load_kernel_cr3 (void);
|
void amd64_load_kernel_cr3 (void);
|
||||||
|
void mm_init2 (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_MM_H
|
#endif // _KERNEL_AMD64_MM_H
|
||||||
|
|||||||
17
kernel/amd64/proc.h
Normal file
17
kernel/amd64/proc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _KERNEL_AMD64_PROC_H
|
||||||
|
#define _KERNEL_AMD64_PROC_H
|
||||||
|
|
||||||
|
#include <amd64/intr.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
|
||||||
|
#define PROC_USTACK_TOP 0x00007FFFFFFFF000ULL
|
||||||
|
#define USTACK_SIZE (256 * PAGE_SIZE)
|
||||||
|
|
||||||
|
struct proc_platformdata {
|
||||||
|
struct saved_regs regs;
|
||||||
|
uintptr_t syscall_stack;
|
||||||
|
uintptr_t user_stack;
|
||||||
|
uint64_t fsbase;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _KERNEL_AMD64_PROC_H
|
||||||
24
kernel/amd64/sched.S
Normal file
24
kernel/amd64/sched.S
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#define pop_regs \
|
||||||
|
popq %r15; \
|
||||||
|
popq %r14; \
|
||||||
|
popq %r13; \
|
||||||
|
popq %r12; \
|
||||||
|
popq %r11; \
|
||||||
|
popq %r10; \
|
||||||
|
popq %r9; \
|
||||||
|
popq %r8; \
|
||||||
|
popq %rbx; \
|
||||||
|
popq %rbp; \
|
||||||
|
popq %rdi; \
|
||||||
|
popq %rsi; \
|
||||||
|
popq %rdx; \
|
||||||
|
popq %rcx; \
|
||||||
|
popq %rax;
|
||||||
|
|
||||||
|
.global amd64_do_sched
|
||||||
|
amd64_do_sched:
|
||||||
|
movq %rsi, %cr3
|
||||||
|
movq %rdi, %rsp
|
||||||
|
pop_regs
|
||||||
|
add $16, %rsp
|
||||||
|
iretq
|
||||||
6
kernel/amd64/sched.h
Normal file
6
kernel/amd64/sched.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _KERNEL_AMD64_SCHED_H
|
||||||
|
#define _KERNEL_AMD64_SCHED_H
|
||||||
|
|
||||||
|
void amd64_do_sched (void* regs, void* cr3);
|
||||||
|
|
||||||
|
#endif // _KERNEL_AMD64_SCHED_H
|
||||||
4
kernel/amd64/sched1.c
Normal file
4
kernel/amd64/sched1.c
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#include <amd64/sched.h>
|
||||||
|
#include <sys/mm.h>
|
||||||
|
|
||||||
|
void do_sched (void* regs, struct pd* pd) { amd64_do_sched (regs, (void*)pd->cr3_paddr); }
|
||||||
@@ -23,6 +23,7 @@ struct cpu* cpu_make (void) {
|
|||||||
struct cpu* cpu = &cpus[id];
|
struct cpu* cpu = &cpus[id];
|
||||||
|
|
||||||
memset (cpu, 0, sizeof (*cpu));
|
memset (cpu, 0, sizeof (*cpu));
|
||||||
|
cpu->lock = SPIN_LOCK_INIT;
|
||||||
cpu->id = id;
|
cpu->id = id;
|
||||||
|
|
||||||
return cpu_get (id);
|
return cpu_get (id);
|
||||||
|
|||||||
@@ -5,21 +5,31 @@
|
|||||||
#include <amd64/tss.h>
|
#include <amd64/tss.h>
|
||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
#include <proc/proc.h>
|
||||||
|
|
||||||
#define CPUS_MAX 32
|
#define CPUS_MAX 32
|
||||||
|
|
||||||
struct cpu {
|
struct cpu {
|
||||||
uint64_t lapic_ticks;
|
uint64_t lapic_ticks;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
atomic_int nesting;
|
atomic_int nesting;
|
||||||
} irq_ctx;
|
} irq_ctx;
|
||||||
|
|
||||||
|
uint8_t user_stack[USTACK_SIZE] ALIGNED (16);
|
||||||
|
|
||||||
volatile uint8_t kernel_stack[KSTACK_SIZE] ALIGNED (16);
|
volatile uint8_t kernel_stack[KSTACK_SIZE] ALIGNED (16);
|
||||||
volatile uint8_t except_stack[KSTACK_SIZE] ALIGNED (16);
|
volatile uint8_t except_stack[KSTACK_SIZE] ALIGNED (16);
|
||||||
volatile uint8_t irq_stack[KSTACK_SIZE] ALIGNED (16);
|
volatile uint8_t irq_stack[KSTACK_SIZE] ALIGNED (16);
|
||||||
volatile struct gdt_extended gdt ALIGNED (16);
|
volatile struct gdt_extended gdt ALIGNED (16);
|
||||||
volatile struct tss tss;
|
volatile struct tss tss;
|
||||||
|
|
||||||
|
spin_lock_t lock;
|
||||||
|
|
||||||
|
struct proc* proc_run_q;
|
||||||
|
struct proc* proc_current;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cpu* cpu_make (void);
|
struct cpu* cpu_make (void);
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ c += amd64/bootmain.c \
|
|||||||
amd64/hpet.c \
|
amd64/hpet.c \
|
||||||
amd64/mm.c \
|
amd64/mm.c \
|
||||||
amd64/time.c \
|
amd64/time.c \
|
||||||
amd64/smp.c
|
amd64/smp.c \
|
||||||
|
amd64/sched1.c
|
||||||
|
|
||||||
S += amd64/intr_stub.S \
|
S += amd64/intr_stub.S \
|
||||||
amd64/spin.S
|
amd64/spin.S \
|
||||||
|
amd64/sched.S
|
||||||
|
|
||||||
o += amd64/bootmain.o \
|
o += amd64/bootmain.o \
|
||||||
amd64/init.o \
|
amd64/init.o \
|
||||||
@@ -29,4 +31,6 @@ o += amd64/bootmain.o \
|
|||||||
amd64/hpet.o \
|
amd64/hpet.o \
|
||||||
amd64/mm.o \
|
amd64/mm.o \
|
||||||
amd64/time.o \
|
amd64/time.o \
|
||||||
amd64/smp.o
|
amd64/smp.o \
|
||||||
|
amd64/sched.o \
|
||||||
|
amd64/sched1.o
|
||||||
|
|||||||
4548
kernel/aux/elf.h
Normal file
4548
kernel/aux/elf.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
#include <amd64/apic.h>
|
#include <amd64/apic.h>
|
||||||
|
#include <amd64/intr.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TODO: figure out a generic way to work with IRQs */
|
/* TODO: figure out a generic way to work with IRQs */
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
static struct irq* irqs = NULL;
|
static struct irq* irqs = NULL;
|
||||||
static spin_lock_t irqs_lock;
|
static spin_lock_t irqs_lock;
|
||||||
|
|
||||||
bool irq_attach (void (*func) (void*), void* arg, uint32_t irq_num) {
|
bool irq_attach (void (*func) (void*, void*), void* arg, uint32_t irq_num, uint32_t flags) {
|
||||||
struct irq* irq = malloc (sizeof (*irq));
|
struct irq* irq = malloc (sizeof (*irq));
|
||||||
if (irq == NULL) {
|
if (irq == NULL) {
|
||||||
return false;
|
return false;
|
||||||
@@ -22,19 +23,21 @@ bool irq_attach (void (*func) (void*), void* arg, uint32_t irq_num) {
|
|||||||
irq->func = func;
|
irq->func = func;
|
||||||
irq->arg = arg;
|
irq->arg = arg;
|
||||||
irq->irq_num = irq_num;
|
irq->irq_num = irq_num;
|
||||||
|
irq->flags = flags;
|
||||||
|
|
||||||
spin_lock (&irqs_lock);
|
spin_lock (&irqs_lock);
|
||||||
linklist_append (struct irq*, irqs, irq);
|
linklist_append (struct irq*, irqs, irq);
|
||||||
spin_unlock (&irqs_lock);
|
spin_unlock (&irqs_lock);
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
amd64_ioapic_route_irq (irq_num, irq_num - 0x20, 0, amd64_lapic_id ());
|
uint8_t resolution = amd64_resolve_irq (irq_num);
|
||||||
|
amd64_ioapic_route_irq (irq_num, resolution, 0, amd64_lapic_id ());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_detach (void (*func) (void*)) {
|
void irq_detach (void (*func) (void*, void*)) {
|
||||||
spin_lock (&irqs_lock);
|
spin_lock (&irqs_lock);
|
||||||
|
|
||||||
struct irq *irq, *irq_tmp;
|
struct irq *irq, *irq_tmp;
|
||||||
@@ -46,14 +49,18 @@ void irq_detach (void (*func) (void*)) {
|
|||||||
spin_unlock (&irqs_lock);
|
spin_unlock (&irqs_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_invoke_each (uint32_t irq_num) {
|
struct irq* irq_find (uint32_t irq_num) {
|
||||||
spin_lock (&irqs_lock);
|
spin_lock (&irqs_lock);
|
||||||
|
|
||||||
struct irq *irq, *irq_tmp;
|
struct irq *irq, *irq_tmp;
|
||||||
linklist_foreach (irqs, irq, irq_tmp) {
|
linklist_foreach (irqs, irq, irq_tmp) {
|
||||||
if (irq->irq_num == irq_num)
|
if (irq->irq_num == irq_num) {
|
||||||
irq->func (irq->arg);
|
spin_unlock (&irqs_lock);
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock (&irqs_lock);
|
spin_unlock (&irqs_lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,21 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
|
#define IRQ_INTERRUPT_SAFE (1 << 0)
|
||||||
|
|
||||||
|
typedef void (*irq_func_t) (void* arg, void* regs);
|
||||||
|
|
||||||
struct irq {
|
struct irq {
|
||||||
struct irq* next;
|
struct irq* next;
|
||||||
|
|
||||||
void (*func) (void*);
|
irq_func_t func;
|
||||||
void* arg;
|
void* arg;
|
||||||
uint32_t irq_num;
|
uint32_t irq_num;
|
||||||
|
uint32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool irq_attach (void (*func) (void*), void* arg, uint32_t irq_num);
|
bool irq_attach (irq_func_t, void* arg, uint32_t irq_num, uint32_t flags);
|
||||||
void irq_detach (void (*func) (void*));
|
void irq_detach (irq_func_t func);
|
||||||
void irq_invoke_each (uint32_t irq_num);
|
struct irq* irq_find (uint32_t irq_num);
|
||||||
|
|
||||||
#endif // _KERNEL_IRQ_IRQ_H
|
#endif // _KERNEL_IRQ_IRQ_H
|
||||||
|
|||||||
@@ -45,16 +45,16 @@ bool bm_test (struct bm* bm, size_t k) {
|
|||||||
* Set a range of bits in a bitmap. if starting bit is out of range, we fail.
|
* Set a range of bits in a bitmap. if starting bit is out of range, we fail.
|
||||||
*/
|
*/
|
||||||
bool bm_set_region (struct bm* bm, size_t k, size_t m) {
|
bool bm_set_region (struct bm* bm, size_t k, size_t m) {
|
||||||
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
if (((k + m) > bm->nbits) || (k + m) < k)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++) {
|
for (size_t i = k; i < (k + m); i++) {
|
||||||
bool taken = bm_test (bm, i);
|
bool taken = bm_test (bm, i);
|
||||||
if (taken)
|
if (taken)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++)
|
for (size_t i = k; i < (k + m); i++)
|
||||||
bm_set (bm, i);
|
bm_set (bm, i);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -64,10 +64,10 @@ bool bm_set_region (struct bm* bm, size_t k, size_t m) {
|
|||||||
* Clear a range of bits in a bitmap. starting bit must be in range.
|
* Clear a range of bits in a bitmap. starting bit must be in range.
|
||||||
*/
|
*/
|
||||||
void bm_clear_region (struct bm* bm, size_t k, size_t m) {
|
void bm_clear_region (struct bm* bm, size_t k, size_t m) {
|
||||||
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
if (((k + m) > bm->nbits) || (k + m) < k)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++)
|
for (size_t i = k; i < (k + m); i++)
|
||||||
bm_clear (bm, i);
|
bm_clear (bm, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +78,10 @@ void bm_clear_region (struct bm* bm, size_t k, size_t m) {
|
|||||||
* useful for implementing the physical memory manager algorithm.
|
* useful for implementing the physical memory manager algorithm.
|
||||||
*/
|
*/
|
||||||
bool bm_test_region (struct bm* bm, size_t k, size_t m) {
|
bool bm_test_region (struct bm* bm, size_t k, size_t m) {
|
||||||
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
|
if (((k + m) > bm->nbits) || (k + m) < k)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (size_t i = k; i < m; i++) {
|
for (size_t i = k; i < (k + m); i++) {
|
||||||
bool test = bm_test (bm, i);
|
bool test = bm_test (bm, i);
|
||||||
if (test)
|
if (test)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -130,6 +130,66 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define dlinklist_index_of(type, head, ele, out_idx) \
|
||||||
|
do { \
|
||||||
|
(out_idx) = -1; \
|
||||||
|
int __idx = 0; \
|
||||||
|
type __tmp = (head); \
|
||||||
|
while (__tmp != NULL) { \
|
||||||
|
if (__tmp == (ele)) { \
|
||||||
|
(out_idx) = __idx; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
__tmp = __tmp->next; \
|
||||||
|
__idx++; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define dlinklist_index_of_prop(type, head, propname, propvalue, out_idx) \
|
||||||
|
do { \
|
||||||
|
(out_idx) = -1; \
|
||||||
|
int __idx = 0; \
|
||||||
|
type __tmp = (head); \
|
||||||
|
while (__tmp != NULL) { \
|
||||||
|
if (__tmp->propname == (propvalue)) { \
|
||||||
|
(out_idx) = __idx; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
__tmp = __tmp->next; \
|
||||||
|
__idx++; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define linklist_index_of(type, head, ele, out_idx) \
|
||||||
|
do { \
|
||||||
|
(out_idx) = -1; \
|
||||||
|
int __idx = 0; \
|
||||||
|
type __tmp = (head); \
|
||||||
|
while (__tmp != NULL) { \
|
||||||
|
if (__tmp == (ele)) { \
|
||||||
|
(out_idx) = __idx; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
__tmp = __tmp->next; \
|
||||||
|
__idx++; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define linklist_index_of_prop(type, head, propname, propvalue, out_idx) \
|
||||||
|
do { \
|
||||||
|
(out_idx) = -1; \
|
||||||
|
int __idx = 0; \
|
||||||
|
type __tmp = (head); \
|
||||||
|
while (__tmp != NULL) { \
|
||||||
|
if (__tmp->propname == (propvalue)) { \
|
||||||
|
(out_idx) = __idx; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
__tmp = __tmp->next; \
|
||||||
|
__idx++; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define linklist_append(type, head, new) \
|
#define linklist_append(type, head, new) \
|
||||||
do { \
|
do { \
|
||||||
if ((new) != NULL) { \
|
if ((new) != NULL) { \
|
||||||
|
|||||||
@@ -19,3 +19,4 @@ DECL_REQ (hhdm, HHDM);
|
|||||||
DECL_REQ (memmap, MEMMAP);
|
DECL_REQ (memmap, MEMMAP);
|
||||||
DECL_REQ (rsdp, RSDP);
|
DECL_REQ (rsdp, RSDP);
|
||||||
DECL_REQ (mp, MP);
|
DECL_REQ (mp, MP);
|
||||||
|
DECL_REQ (module, MODULE);
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ EXTERN_REQ (hhdm);
|
|||||||
EXTERN_REQ (memmap);
|
EXTERN_REQ (memmap);
|
||||||
EXTERN_REQ (rsdp);
|
EXTERN_REQ (rsdp);
|
||||||
EXTERN_REQ (mp);
|
EXTERN_REQ (mp);
|
||||||
|
EXTERN_REQ (module);
|
||||||
|
|
||||||
#endif // _KERNEL_LIMINE_REQUESTS_H
|
#endif // _KERNEL_LIMINE_REQUESTS_H
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <mm/types.h>
|
#include <mm/types.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
|
#include <sys/mm.h>
|
||||||
|
|
||||||
/* Porting */
|
|
||||||
spin_lock_t _liballoc_lock = SPIN_LOCK_INIT;
|
spin_lock_t _liballoc_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
int liballoc_lock (void) {
|
int liballoc_lock (void) {
|
||||||
@@ -28,6 +29,7 @@ void* liballoc_alloc (int pages) {
|
|||||||
|
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
uintptr_t addr = (uintptr_t)(p_addr + hhdm->offset);
|
uintptr_t addr = (uintptr_t)(p_addr + hhdm->offset);
|
||||||
|
|
||||||
return (void*)addr;
|
return (void*)addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,18 +57,9 @@ int liballoc_free (void* ptr, int pages) {
|
|||||||
|
|
||||||
#define MODE MODE_BEST
|
#define MODE MODE_BEST
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
||||||
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
unsigned int l_allocated = 0; //< The real amount of memory allocated.
|
|
||||||
unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed).
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int l_initialized = 0; //< Flag to indicate initialization.
|
static int l_initialized = 0; //< Flag to indicate initialization.
|
||||||
static int l_pageSize = 4096; //< Individual page size
|
static int l_pageSize = 4096; //< Individual page size
|
||||||
static int l_pageCount = 16; //< Minimum number of pages to allocate.
|
static int l_pageCount = 16; //< Minimum number of pages to allocate.
|
||||||
@@ -79,9 +72,6 @@ static int l_pageCount = 16; //< Minimum number of pages to allocate.
|
|||||||
*/
|
*/
|
||||||
static inline int getexp (unsigned int size) {
|
static inline int getexp (unsigned int size) {
|
||||||
if (size < (1 << MINEXP)) {
|
if (size < (1 << MINEXP)) {
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("getexp returns -1 for %i less than MINEXP\n", size);
|
|
||||||
#endif
|
|
||||||
return -1; // Smaller than the quantum.
|
return -1; // Smaller than the quantum.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,10 +83,6 @@ static inline int getexp (unsigned int size) {
|
|||||||
shift += 1;
|
shift += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("getexp returns %i (%i bytes) for %i size\n", shift - 1, (1 << (shift - 1)), size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return shift - 1;
|
return shift - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,37 +116,6 @@ static void* liballoc_memcpy (void* s1, const void* s2, size_t n) {
|
|||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
static void dump_array () {
|
|
||||||
int i = 0;
|
|
||||||
struct boundary_tag* tag = NULL;
|
|
||||||
|
|
||||||
printf ("------ Free pages array ---------\n");
|
|
||||||
printf ("System memory allocated: %i\n", l_allocated);
|
|
||||||
printf ("Memory in used (malloc'ed): %i\n", l_inuse);
|
|
||||||
|
|
||||||
for (i = 0; i < MAXEXP; i++) {
|
|
||||||
printf ("%.2i(%i): ", i, l_completePages[i]);
|
|
||||||
|
|
||||||
tag = l_freePages[i];
|
|
||||||
while (tag != NULL) {
|
|
||||||
if (tag->split_left != NULL)
|
|
||||||
printf ("*");
|
|
||||||
printf ("%i", tag->real_size);
|
|
||||||
if (tag->split_right != NULL)
|
|
||||||
printf ("*");
|
|
||||||
|
|
||||||
printf (" ");
|
|
||||||
tag = tag->next;
|
|
||||||
}
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("'*' denotes a split to the left/right of a tag\n");
|
|
||||||
fflush (stdout);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void insert_tag (struct boundary_tag* tag, int index) {
|
static inline void insert_tag (struct boundary_tag* tag, int index) {
|
||||||
int realIndex;
|
int realIndex;
|
||||||
|
|
||||||
@@ -281,15 +236,6 @@ static struct boundary_tag* allocate_new_tag (unsigned int size) {
|
|||||||
tag->split_left = NULL;
|
tag->split_left = NULL;
|
||||||
tag->split_right = NULL;
|
tag->split_right = NULL;
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag, pages,
|
|
||||||
pages * l_pageSize, size);
|
|
||||||
|
|
||||||
l_allocated += pages * l_pageSize;
|
|
||||||
|
|
||||||
printf ("Total memory usage = %i KB\n", (int)((l_allocated / (1024))));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,9 +247,6 @@ void* malloc (size_t size) {
|
|||||||
liballoc_lock ();
|
liballoc_lock ();
|
||||||
|
|
||||||
if (l_initialized == 0) {
|
if (l_initialized == 0) {
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("%s\n", "liballoc initializing.");
|
|
||||||
#endif
|
|
||||||
for (index = 0; index < MAXEXP; index++) {
|
for (index = 0; index < MAXEXP; index++) {
|
||||||
l_freePages[index] = NULL;
|
l_freePages[index] = NULL;
|
||||||
l_completePages[index] = 0;
|
l_completePages[index] = 0;
|
||||||
@@ -320,10 +263,6 @@ void* malloc (size_t size) {
|
|||||||
while (tag != NULL) {
|
while (tag != NULL) {
|
||||||
// If there's enough space in this tag.
|
// If there's enough space in this tag.
|
||||||
if ((tag->real_size - sizeof (struct boundary_tag)) >= (size + sizeof (struct boundary_tag))) {
|
if ((tag->real_size - sizeof (struct boundary_tag)) >= (size + sizeof (struct boundary_tag))) {
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("Tag search found %i >= %i\n", (tag->real_size - sizeof (struct boundary_tag)),
|
|
||||||
(size + sizeof (struct boundary_tag)));
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,13 +290,6 @@ void* malloc (size_t size) {
|
|||||||
|
|
||||||
// Removed... see if we can re-use the excess space.
|
// Removed... see if we can re-use the excess space.
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf (
|
|
||||||
"Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n",
|
|
||||||
tag->real_size - sizeof (struct boundary_tag), size,
|
|
||||||
tag->real_size - size - sizeof (struct boundary_tag), index, 1 << index);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned int remainder =
|
unsigned int remainder =
|
||||||
tag->real_size - size - sizeof (struct boundary_tag) * 2; // Support a new tag + remainder
|
tag->real_size - size - sizeof (struct boundary_tag) * 2; // Support a new tag + remainder
|
||||||
|
|
||||||
@@ -365,30 +297,14 @@ void* malloc (size_t size) {
|
|||||||
int childIndex = getexp (remainder);
|
int childIndex = getexp (remainder);
|
||||||
|
|
||||||
if (childIndex >= 0) {
|
if (childIndex >= 0) {
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex,
|
|
||||||
(1 << childIndex));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct boundary_tag* new_tag = split_tag (tag);
|
struct boundary_tag* new_tag = split_tag (tag);
|
||||||
|
|
||||||
(void)new_tag;
|
(void)new_tag;
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n", tag->real_size,
|
|
||||||
new_tag->real_size, new_tag->index);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = (void*)((uintptr_t)tag + sizeof (struct boundary_tag));
|
ptr = (void*)((uintptr_t)tag + sizeof (struct boundary_tag));
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
l_inuse += size;
|
|
||||||
printf ("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024);
|
|
||||||
dump_array ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
liballoc_unlock ();
|
liballoc_unlock ();
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@@ -409,29 +325,14 @@ void free (void* ptr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
l_inuse -= tag->size;
|
|
||||||
printf ("free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MELT LEFT...
|
// MELT LEFT...
|
||||||
while ((tag->split_left != NULL) && (tag->split_left->index >= 0)) {
|
while ((tag->split_left != NULL) && (tag->split_left->index >= 0)) {
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("Melting tag left into available memory. Left was %i, becomes %i (%i)\n",
|
|
||||||
tag->split_left->real_size, tag->split_left->real_size + tag->real_size,
|
|
||||||
tag->split_left->real_size);
|
|
||||||
#endif
|
|
||||||
tag = melt_left (tag);
|
tag = melt_left (tag);
|
||||||
remove_tag (tag);
|
remove_tag (tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MELT RIGHT...
|
// MELT RIGHT...
|
||||||
while ((tag->split_right != NULL) && (tag->split_right->index >= 0)) {
|
while ((tag->split_right != NULL) && (tag->split_right->index >= 0)) {
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("Melting tag right into available memory. This was was %i, becomes %i (%i)\n",
|
|
||||||
tag->real_size, tag->split_right->real_size + tag->real_size,
|
|
||||||
tag->split_right->real_size);
|
|
||||||
#endif
|
|
||||||
tag = absorb_right (tag);
|
tag = absorb_right (tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,12 +354,6 @@ void free (void* ptr) {
|
|||||||
|
|
||||||
liballoc_free (tag, pages);
|
liballoc_free (tag, pages);
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
l_allocated -= pages * l_pageSize;
|
|
||||||
printf ("Resource freeing %x of %i pages\n", tag, pages);
|
|
||||||
dump_array ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
liballoc_unlock ();
|
liballoc_unlock ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -470,12 +365,6 @@ void free (void* ptr) {
|
|||||||
|
|
||||||
insert_tag (tag, index);
|
insert_tag (tag, index);
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf ("Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n",
|
|
||||||
tag->real_size, tag->size, index);
|
|
||||||
dump_array ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
liballoc_unlock ();
|
liballoc_unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,8 @@ void pmm_free (physaddr_t p_addr, size_t nblks) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If aligned_p_addr is within the range if this region, it belongs to it. */
|
/* If aligned_p_addr is within the range if this region, it belongs to it. */
|
||||||
if (aligned_p_addr >= pmm_region->membase && aligned_p_addr < pmm_region->size) {
|
if (aligned_p_addr >= pmm_region->membase &&
|
||||||
|
aligned_p_addr < pmm_region->membase + pmm_region->size) {
|
||||||
physaddr_t addr = aligned_p_addr - pmm_region->membase;
|
physaddr_t addr = aligned_p_addr - pmm_region->membase;
|
||||||
|
|
||||||
size_t bit = div_align_up (addr, PAGE_SIZE);
|
size_t bit = div_align_up (addr, PAGE_SIZE);
|
||||||
|
|||||||
1
kernel/proc/.gitignore
vendored
Normal file
1
kernel/proc/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.o
|
||||||
245
kernel/proc/proc.c
Normal file
245
kernel/proc/proc.c
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
#include <aux/compiler.h>
|
||||||
|
#include <aux/elf.h>
|
||||||
|
#include <irq/irq.h>
|
||||||
|
#include <libk/align.h>
|
||||||
|
#include <libk/list.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
#include <libk/string.h>
|
||||||
|
#include <limine/requests.h>
|
||||||
|
#include <mm/liballoc.h>
|
||||||
|
#include <mm/pmm.h>
|
||||||
|
#include <proc/proc.h>
|
||||||
|
#include <rd/rd.h>
|
||||||
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
|
#include <sys/mm.h>
|
||||||
|
#include <sys/sched.h>
|
||||||
|
#include <sys/smp.h>
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
#include <amd64/intr_defs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct elf_aux {
|
||||||
|
uint64_t entry;
|
||||||
|
uint64_t phdr;
|
||||||
|
uint64_t phent;
|
||||||
|
uint64_t phnum;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct procw* procs;
|
||||||
|
static spin_lock_t procs_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
|
static bool proc_check_elf (uint8_t* elf) {
|
||||||
|
if (!((elf[0] == 0x7F) && (elf[1] == 'E') && (elf[2] == 'L') && (elf[3] == 'F')))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages,
|
||||||
|
uint32_t flags) {
|
||||||
|
struct proc_mapping* mapping = malloc (sizeof (*mapping));
|
||||||
|
mapping->paddr = start_paddr;
|
||||||
|
mapping->vaddr = start_vaddr;
|
||||||
|
mapping->size = pages * PAGE_SIZE;
|
||||||
|
|
||||||
|
flags &= ~MM_PD_LOCK; /* clear LOCK flag if present, because we lock manualy */
|
||||||
|
|
||||||
|
spin_lock (&proc->pd.lock);
|
||||||
|
|
||||||
|
linklist_append (struct proc_mapping*, proc->mappings, mapping);
|
||||||
|
|
||||||
|
for (uintptr_t vpage = start_vaddr, ppage = start_paddr; vpage < start_vaddr + pages * PAGE_SIZE;
|
||||||
|
vpage += PAGE_SIZE, ppage += PAGE_SIZE) {
|
||||||
|
mm_map_page (&proc->pd, ppage, vpage, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock (&proc->pd.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) {
|
||||||
|
struct elf_aux aux;
|
||||||
|
|
||||||
|
Elf64_Ehdr* ehdr = (Elf64_Ehdr*)elf;
|
||||||
|
aux.entry = ehdr->e_entry;
|
||||||
|
aux.phnum = ehdr->e_phnum;
|
||||||
|
aux.phent = ehdr->e_phentsize;
|
||||||
|
|
||||||
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
|
for (uint64_t segment = 0; segment < ehdr->e_phnum; segment++) {
|
||||||
|
Elf64_Phdr* phdr =
|
||||||
|
(Elf64_Phdr*)((uintptr_t)elf + ehdr->e_phoff + (ehdr->e_phentsize * segment));
|
||||||
|
|
||||||
|
switch (phdr->p_type) {
|
||||||
|
case PT_PHDR: {
|
||||||
|
aux.phdr = (uint64_t)phdr->p_vaddr;
|
||||||
|
} break;
|
||||||
|
case PT_LOAD: {
|
||||||
|
uintptr_t v_addr = align_down (phdr->p_vaddr, PAGE_SIZE);
|
||||||
|
uintptr_t off = phdr->p_vaddr - v_addr;
|
||||||
|
|
||||||
|
size_t blks = div_align_up (phdr->p_memsz + off, PAGE_SIZE);
|
||||||
|
|
||||||
|
uintptr_t p_addr = pmm_alloc (blks);
|
||||||
|
if (p_addr == PMM_ALLOC_ERR)
|
||||||
|
DEBUG ("pmm oom error while loading ELF segments! (tried to alloc %zu blks)\n", blks);
|
||||||
|
|
||||||
|
memset ((void*)((uintptr_t)hhdm->offset + p_addr), 0, blks * PAGE_SIZE);
|
||||||
|
memcpy ((void*)((uintptr_t)hhdm->offset + p_addr + off),
|
||||||
|
(void*)((uintptr_t)elf + phdr->p_offset), phdr->p_filesz);
|
||||||
|
|
||||||
|
uint32_t pg_flags = MM_PG_USER | MM_PG_PRESENT;
|
||||||
|
if (phdr->p_flags & PF_W)
|
||||||
|
pg_flags |= MM_PG_RW;
|
||||||
|
|
||||||
|
proc_map (proc, p_addr, v_addr, blks, pg_flags);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return aux;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct proc* proc_spawn_rd (char* name) {
|
||||||
|
struct rd_file* rd_file = rd_get_file (name);
|
||||||
|
|
||||||
|
bool ok = proc_check_elf (rd_file->content);
|
||||||
|
DEBUG ("ELF magic %s\n", (ok ? "OK" : "BAD"));
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct proc* proc = malloc (sizeof (*proc));
|
||||||
|
if (proc == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset (proc, 0, sizeof (*proc));
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
proc->pd.lock = SPIN_LOCK_INIT;
|
||||||
|
proc->pd.cr3_paddr = mm_alloc_user_pd_phys ();
|
||||||
|
if (proc->pd.cr3_paddr == 0) {
|
||||||
|
free (proc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc->pdata.syscall_stack = pmm_alloc (KSTACK_SIZE / PAGE_SIZE);
|
||||||
|
if (proc->pdata.syscall_stack == PMM_ALLOC_ERR) {
|
||||||
|
free (proc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc->pdata.user_stack = pmm_alloc (USTACK_SIZE / PAGE_SIZE);
|
||||||
|
if (proc->pdata.user_stack == PMM_ALLOC_ERR) {
|
||||||
|
free (proc);
|
||||||
|
pmm_free (proc->pdata.syscall_stack, USTACK_SIZE / PAGE_SIZE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t user_stack = proc->pdata.user_stack;
|
||||||
|
|
||||||
|
proc->pdata.syscall_stack += KSTACK_SIZE;
|
||||||
|
proc->pdata.user_stack += USTACK_SIZE;
|
||||||
|
|
||||||
|
proc_map (proc, user_stack, PROC_USTACK_TOP - USTACK_SIZE, USTACK_SIZE / PAGE_SIZE,
|
||||||
|
MM_PG_USER | MM_PG_PRESENT | MM_PG_RW);
|
||||||
|
|
||||||
|
struct elf_aux aux = proc_load_segments (proc, rd_file->content);
|
||||||
|
|
||||||
|
proc->pdata.regs.ss = 0x20 | 0x03;
|
||||||
|
proc->pdata.regs.rsp = (uint64_t)PROC_USTACK_TOP;
|
||||||
|
proc->pdata.regs.rflags = 0x202;
|
||||||
|
proc->pdata.regs.cs = 0x18 | 0x03;
|
||||||
|
proc->pdata.regs.rip = aux.entry;
|
||||||
|
proc->lock = SPIN_LOCK_INIT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void proc_register (struct proc* proc) {
|
||||||
|
/* make available globally. */
|
||||||
|
struct procw* procw = malloc (sizeof (*procw));
|
||||||
|
if (procw == NULL)
|
||||||
|
return;
|
||||||
|
procw->proc = proc;
|
||||||
|
proc->procw = procw;
|
||||||
|
|
||||||
|
spin_lock (&procs_lock);
|
||||||
|
|
||||||
|
spin_lock (&thiscpu->lock);
|
||||||
|
|
||||||
|
linklist_append (struct procw*, procs, procw);
|
||||||
|
linklist_append (struct proc*, thiscpu->proc_run_q, proc);
|
||||||
|
|
||||||
|
if (thiscpu->proc_current == NULL)
|
||||||
|
thiscpu->proc_current = proc;
|
||||||
|
|
||||||
|
spin_unlock (&thiscpu->lock);
|
||||||
|
|
||||||
|
spin_unlock (&procs_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_sched (void) {
|
||||||
|
spin_lock (&thiscpu->lock);
|
||||||
|
|
||||||
|
if (thiscpu->proc_run_q == NULL || thiscpu->proc_current == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
thiscpu->proc_current = thiscpu->proc_current->next;
|
||||||
|
|
||||||
|
if (thiscpu->proc_current == NULL) {
|
||||||
|
thiscpu->proc_current = thiscpu->proc_run_q;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
spin_unlock (&thiscpu->lock);
|
||||||
|
|
||||||
|
if (thiscpu->proc_current != NULL) {
|
||||||
|
do_sched (&thiscpu->proc_current->pdata.regs, &thiscpu->proc_current->pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
extern void amd64_spin (void);
|
||||||
|
|
||||||
|
amd64_spin ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_kill (struct proc* proc) {
|
||||||
|
spin_lock (&procs_lock);
|
||||||
|
|
||||||
|
spin_lock (&thiscpu->lock);
|
||||||
|
|
||||||
|
linklist_remove (struct procw*, procs, proc->procw);
|
||||||
|
linklist_remove (struct proc*, thiscpu->proc_run_q, proc);
|
||||||
|
|
||||||
|
if (thiscpu->proc_current == proc)
|
||||||
|
thiscpu->proc_current = NULL;
|
||||||
|
|
||||||
|
spin_unlock (&thiscpu->lock);
|
||||||
|
|
||||||
|
spin_unlock (&procs_lock);
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
free (proc->procw);
|
||||||
|
free (proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void proc_irq_sched (void* arg, void* regs) {
|
||||||
|
(void)arg, (void)regs;
|
||||||
|
proc_sched ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_init (void) {
|
||||||
|
struct proc* init = proc_spawn_rd ("init.exe");
|
||||||
|
proc_register (init);
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
irq_attach (&proc_irq_sched, NULL, SCHED_PREEMPT_TIMER, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
do_sched (&init->pdata.regs, &init->pd);
|
||||||
|
}
|
||||||
49
kernel/proc/proc.h
Normal file
49
kernel/proc/proc.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef _KERNEL_PROC_PROC_H
|
||||||
|
#define _KERNEL_PROC_PROC_H
|
||||||
|
|
||||||
|
#include <aux/compiler.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/mm.h>
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
#include <amd64/gdt.h> /* KSTACK_SIZE */
|
||||||
|
#include <amd64/proc.h> /* USTACK_SIZE */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct cpu;
|
||||||
|
|
||||||
|
struct proc_mapping {
|
||||||
|
struct proc_mapping* next;
|
||||||
|
uintptr_t paddr;
|
||||||
|
uintptr_t vaddr;
|
||||||
|
size_t size;
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
struct procw;
|
||||||
|
|
||||||
|
struct proc {
|
||||||
|
struct proc* next;
|
||||||
|
struct proc_mapping* mappings; /* pd.lock implicitly protects this field */
|
||||||
|
struct proc_platformdata pdata;
|
||||||
|
struct pd pd;
|
||||||
|
spin_lock_t lock;
|
||||||
|
struct cpu* cpu;
|
||||||
|
struct procw* procw; /* link to it's global struct */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct proc is a member of a CPU's proc_run_q.
|
||||||
|
* struct procw is a process wrapper that is a member of
|
||||||
|
* a global process list.
|
||||||
|
*/
|
||||||
|
struct procw {
|
||||||
|
struct procw* next;
|
||||||
|
struct proc* proc;
|
||||||
|
};
|
||||||
|
|
||||||
|
void proc_sched (void);
|
||||||
|
void proc_kill (struct proc* proc);
|
||||||
|
void proc_init (void);
|
||||||
|
|
||||||
|
#endif // _KERNEL_PROC_PROC_H
|
||||||
3
kernel/proc/src.mk
Normal file
3
kernel/proc/src.mk
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
c += proc/proc.c
|
||||||
|
|
||||||
|
o += proc/proc.o
|
||||||
1
kernel/rd/.gitignore
vendored
Normal file
1
kernel/rd/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.o
|
||||||
81
kernel/rd/rd.c
Normal file
81
kernel/rd/rd.c
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include <aux/compiler.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
#include <libk/string.h>
|
||||||
|
#include <limine/requests.h>
|
||||||
|
#include <rd/rd.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
|
|
||||||
|
#define RD_FILES_MAX 64
|
||||||
|
#define RD_PATH "/boot/mop3dist.tar"
|
||||||
|
|
||||||
|
static struct rd_file rd_files[RD_FILES_MAX];
|
||||||
|
|
||||||
|
struct rd_file* rd_get_file (char* filename) {
|
||||||
|
for (size_t i = 0; i < RD_FILES_MAX; i++) {
|
||||||
|
if ((rd_files[i].hdr != NULL) &&
|
||||||
|
(memcmp (rd_files[i].hdr->filename, filename, strlen (filename)) == 0))
|
||||||
|
return &rd_files[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t rd_tar_get_size (uint8_t* in) {
|
||||||
|
size_t size = 0;
|
||||||
|
size_t j;
|
||||||
|
size_t count = 1;
|
||||||
|
|
||||||
|
for (j = 11; j > 0; j--, count *= 8)
|
||||||
|
size += ((in[j - 1] - '0') * count);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t rd_tar_parse (uint8_t* addr) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0;; i++) {
|
||||||
|
struct tar_hdr* hdr = (struct tar_hdr*)addr;
|
||||||
|
|
||||||
|
if (hdr->filename[i] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
size_t size = rd_tar_get_size (hdr->size);
|
||||||
|
|
||||||
|
rd_files[i].hdr = hdr;
|
||||||
|
rd_files[i].content = (uint8_t*)((uintptr_t)hdr + 512);
|
||||||
|
rd_files[i].size = rd_tar_get_size ((uint8_t*)hdr->size);
|
||||||
|
|
||||||
|
DEBUG ("filename=%s\n", hdr->filename);
|
||||||
|
|
||||||
|
addr += ((size / 512) + 1) * 512;
|
||||||
|
|
||||||
|
if (size % 512)
|
||||||
|
addr += 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rd_init (void) {
|
||||||
|
struct limine_module_response* module = limine_module_request.response;
|
||||||
|
|
||||||
|
uint8_t* rd_addr = NULL;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < module->module_count; i++) {
|
||||||
|
struct limine_file* file = module->modules[i];
|
||||||
|
DEBUG ("%s\n", file->path);
|
||||||
|
|
||||||
|
if (memcmp (file->path, RD_PATH, strlen (RD_PATH)) == 0) {
|
||||||
|
rd_addr = file->address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rd_addr == NULL) {
|
||||||
|
DEBUG ("mop3dist.tar NOT FOUND!\n");
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
rd_tar_parse (rd_addr);
|
||||||
|
}
|
||||||
27
kernel/rd/rd.h
Normal file
27
kernel/rd/rd.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef _KERNEL_RD_RD_H
|
||||||
|
#define _KERNEL_RD_RD_H
|
||||||
|
|
||||||
|
#include <aux/compiler.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
|
||||||
|
struct tar_hdr {
|
||||||
|
char filename[100];
|
||||||
|
uint8_t mode[8];
|
||||||
|
uint8_t uid[8];
|
||||||
|
uint8_t gid[8];
|
||||||
|
uint8_t size[12];
|
||||||
|
uint8_t mtime[12];
|
||||||
|
uint8_t checksum[8];
|
||||||
|
uint8_t type_flag;
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
struct rd_file {
|
||||||
|
struct tar_hdr* hdr;
|
||||||
|
uint8_t* content;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rd_file* rd_get_file (char* filename);
|
||||||
|
void rd_init (void);
|
||||||
|
|
||||||
|
#endif // _KERNEL_RD_RD_H
|
||||||
3
kernel/rd/src.mk
Normal file
3
kernel/rd/src.mk
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
c += rd/rd.c
|
||||||
|
|
||||||
|
o += rd/rd.o
|
||||||
@@ -5,3 +5,5 @@ include mm/src.mk
|
|||||||
include limine/src.mk
|
include limine/src.mk
|
||||||
include uACPI/src.mk
|
include uACPI/src.mk
|
||||||
include irq/src.mk
|
include irq/src.mk
|
||||||
|
include rd/src.mk
|
||||||
|
include proc/src.mk
|
||||||
|
|||||||
@@ -10,8 +10,11 @@
|
|||||||
#define MM_PG_PRESENT (1 << 0)
|
#define MM_PG_PRESENT (1 << 0)
|
||||||
#define MM_PG_RW (1 << 1)
|
#define MM_PG_RW (1 << 1)
|
||||||
#define MM_PG_USER (1 << 2)
|
#define MM_PG_USER (1 << 2)
|
||||||
|
#define MM_PD_RELOAD (1 << 30)
|
||||||
#define MM_PD_LOCK (1 << 31)
|
#define MM_PD_LOCK (1 << 31)
|
||||||
|
|
||||||
|
uintptr_t mm_alloc_user_pd_phys (void);
|
||||||
|
void mm_reload (void);
|
||||||
void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags);
|
void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags);
|
||||||
void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags);
|
void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags);
|
||||||
void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags);
|
void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags);
|
||||||
|
|||||||
8
kernel/sys/sched.h
Normal file
8
kernel/sys/sched.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _KERNEL_SYS_SCHED_H
|
||||||
|
#define _KERNEL_SYS_SCHED_H
|
||||||
|
|
||||||
|
#include <sys/mm.h>
|
||||||
|
|
||||||
|
void do_sched (void* regs, struct pd* pd);
|
||||||
|
|
||||||
|
#endif // _KERNEL_SYS_SCHED_H
|
||||||
26
user.mk
Normal file
26
user.mk
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
cc := clang
|
||||||
|
o :=
|
||||||
|
c :=
|
||||||
|
ldflags :=
|
||||||
|
cflags :=
|
||||||
|
|
||||||
|
include src.mk
|
||||||
|
include app.mk
|
||||||
|
include ../generic/flags.mk
|
||||||
|
include ../$(platform)/flags.mk
|
||||||
|
|
||||||
|
all: $(app)
|
||||||
|
|
||||||
|
$(app): $(o)
|
||||||
|
$(cc) -o $@ $(ldflags) -T ../$(platform)/link.ld $^
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(cc) -c -o $@ $(cflags) $<
|
||||||
|
|
||||||
|
%.o: %.S
|
||||||
|
$(cc) -c -o $@ $(cflags) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(o) $(app)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
Reference in New Issue
Block a user