Skip to content

Introduce multiprocessing #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Sep 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .gdbinit
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
set $CS_BASE = 0x20000
set $DS_BASE = 0x20000
set $SS_BASE = 0x20000
set $CS_BASE = 0x30000
set $DS_BASE = 0x30000
set $SS_BASE = 0x30000

# config
set architecture i386:x86-64
Expand Down Expand Up @@ -72,17 +72,17 @@ define view_realmode
end

define view_kernelmode
set $CS_BASE = 0xC000
set $DS_BASE = 0xC000
set $SS_BASE = 0xC000
set $CS_BASE = 0x10000
set $DS_BASE = 0x10000
set $SS_BASE = 0x10000
symbol-file build/kernel/core.elf
clayout
end

define view_usermode
set $CS_BASE = 0x20000
set $DS_BASE = 0x20000
set $SS_BASE = 0x20000
set $CS_BASE = 0x30000
set $DS_BASE = 0x30000
set $SS_BASE = 0x30000
symbol-file
clayout
end
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ SOURCE_SNAPSHOT="\"$$(git rev-parse --short HEAD)$$(git diff --quiet || echo '_u
## Integer is 4 bytes

# Debugging controller
DEBUG?=
ifdef DEBUG
NODEBUG?=
ifndef NODEBUG
CC_DEBUG=-g
NASM_DEBUG=-g
LD_DEBUG=
Expand Down Expand Up @@ -101,8 +101,8 @@ binaries: $(bt_stage1) $(bt_stage2) $(kernel_core) $(rm_static)
# Note: Relying on default value doesn't guarantee bin size.
SECTOR_COUNT_BT_STAGE1 = 1
SECTOR_COUNT_SHARED_LIBRARY = 1
SECTOR_COUNT_BT_STAGE2 = 11
SECTOR_COUNT_KERNEL = 47
SECTOR_COUNT_BT_STAGE2 = 12
SECTOR_COUNT_KERNEL = 70

SECTOR_START_BT_STAGE1 = 0
SECTOR_START_SHARED_LIBRARY = $(shell expr $(SECTOR_START_BT_STAGE1) + $(SECTOR_COUNT_BT_STAGE1) )
Expand Down
5 changes: 2 additions & 3 deletions emulator/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ QEMU_SHUT_FLAGS= -no-shutdown -no-reboot
QEMU_EXTRA_FLAGS=
QEMU_GDB_PORT=9000
QEMU_MONITOR_PORT=55555
GDB_EX='echo Use GDB_EX="<command>" to execute command on connect.\n'
GDB_EX=echo Use GDB_EX="<command>" to execute command on connect.\n

qemu: $(image_vmdk)
qemu-system-x86_64 -smp 1 -m 128M -hda $< $(QEMU_SHUT_FLAGS) $(QEMU_EXTRA_FLAGS)
Expand All @@ -17,6 +17,5 @@ qemu_debug: $(image_vmdk)
qemu-system-x86_64 -S -gdb tcp::$(QEMU_GDB_PORT) -smp 1 -m 128M -hda $< $(QEMU_SHUT_FLAGS) -d cpu,exec,in_asm

qemu_debug_connect:
gdb -x $(ROOT_DIR)/.gdbinit -ex "target remote :$(QEMU_GDB_PORT)" -ex "$(GDB_EX)" -ex 'continue'

gdb -x $(ROOT_DIR)/.gdbinit -ex "target remote :$(QEMU_GDB_PORT)" -ex '$(GDB_EX)' -ex 'continue'

11 changes: 6 additions & 5 deletions include/fuzzy/drivers/pic/pic.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#pragma once

#include <stddef.h>

#define PIC_PIT_FREQ 1193182 // hz
#define PIC_PIT_MAX_COUNTER 0xFFFF

#define PIC_IRQ_PIT 0

void interrupt_pit_enable();
void pic_init();

void pic_writemask_new(uint16_t mask);
uint16_t pic_readmask_new();

void pic_irq_enable(int irq);
void pic_irq_disable(int irq);

void pic_pit_set_counter(unsigned short counter);
unsigned short pic_pit_get_counter();
void pic_pit_reset();
13 changes: 13 additions & 0 deletions include/fuzzy/drivers/pic/pit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <stddef.h>

static uint16_t frequency_dividor;

void pit_init();

void pit_set_counter(uint16_t counter);
uint16_t pit_get_counter();

void pit_reload_counter();
void pit_reset();
33 changes: 33 additions & 0 deletions include/fuzzy/drivers/port.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <stddef.h>

#define PORT_PIC1_CMD 0x20
#define PORT_PIC1_DATA 0x21
#define PORT_PIC2_CMD 0xA0
#define PORT_PIC2_DATA 0xA1

#define PORT_PIT_DATA0 0x40
#define PORT_PIT_DATA1 0x41
#define PORT_PIT_DATA2 0x42
#define PORT_PIT_CMD 0x43

static inline void outb(uint16_t port, uint8_t data) {
__asm__ volatile(
"outb %0, %1 \n"
: /* output */
: "a" (data), "ir" (port) /* input */
:
);
}

static inline uint8_t inputb(uint16_t port) {
uint8_t data;
__asm__ volatile(
"inb %1, %0 \n"
: "=a" (data) /* output */
: "ir" (port) /* input */
:
);
return data;
}
3 changes: 1 addition & 2 deletions include/fuzzy/fs/ffs.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ int resolve_abs_lba(int parition_id, int partition_relative_lba);

int partition_read_block(int block_index, void *wr_buffer);

int fetch_first_block(
union FFSMetaData *block);
int verify_partition(int partition_id);

int fetch_file_entry(
int partition_id,
Expand Down
1 change: 1 addition & 0 deletions include/fuzzy/kernel/panic.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
void panic_just_halt();
int panic(int err, const char *message, const char *src_file,
unsigned int line_number);
int panic_screen_init();
42 changes: 37 additions & 5 deletions include/fuzzy/kernel/process/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#include <process.h>
#include<stddef.h>

#define MAX_PROCESS 10
#define GDT_TABLE_SIZE MAX_PROCESS*2+3
#define MAX_PROCESS 127
// each process will have CS and DS, and kernel
// CS and DS is already included in GDT standard table.
#define GDT_TABLE_SIZE ((MAX_PROCESS-1)*2+GDT_STD_SIZE)

typedef char ARGV[PROCESS_MAX_ARGC][PROCESS_MAX_ARG_LEN];

Expand All @@ -13,6 +15,11 @@ enum process_state{
STATE_READY,
STATE_RUNNING,
STATE_EXIT, // should be unallocated in next scheduling cycle
STATE_BLOCK, // process is waiting on IO, process_wait, etc.
};

enum process_state_block {
STATE_BLOCK_PROCESS_WAIT, // waiting for another process termination.
};

struct Process {
Expand All @@ -22,6 +29,23 @@ struct Process {
unsigned int *e;

int status_code;

unsigned int ppid; // parent pid, 0 to root under kernel_core

enum process_state_block block_type; // valid, if state == BLOCK
union {
struct {
unsigned int blocked_on_pid;
unsigned int blocking_pid; // TODO: make list
} process_wait;
} block_data; // valid if state == BLOCK

// schedule for IRQ0
// 0 - no fork requested or last fork successful; can try fork again
// 1 - fork requested; should NOT try fork for now.
// -1 - last fork failed; can try fork again
signed char flagirq0_fork_ready;
int flagirq0_fork_newchild; // pid
};

void process_scheduler_init();
Expand All @@ -35,11 +59,12 @@ int get_gdt_number_from_entry_id(int id);
// allocation
int get_idt_cs_entry(int process_id);
int get_idt_ds_entry(int process_id);
int get_idt_reverse_pid_lookup(int cs);
int get_idt_reverse_pid_lookup_cs(int cs);
int get_idt_reverse_pid_lookup_ds(int ds);

// process create or kill
int process_create(int argc, char *argv[]);
void process_kill(int user_ds, int status);
int process_create(unsigned int ppid, int argc, char *argv[]);
void process_kill(unsigned int pid, int status);

// scheduler

Expand All @@ -50,3 +75,10 @@ void process_scheduler(int *_e_ip, int *_e_cs, int *_e_sp, int *_e_ss);
// user space <-> kernel space data transfer helper
extern void syscall_strncpy_user_to_kernel(int user_ds, char *src_es_address, char *dest_ds_address, size_t size);
extern void syscall_strncpy_kernel_to_user(int user_ds, char *dest_address, char *src_address, size_t size);
extern void kernel_memncpy_absolute(int dst_ds, char *dst_address, int src_ds, char *src_address, size_t size);

// operations
int process_waitpid(unsigned int pid, unsigned int blocked_on_pid);

int process_fork_mark_ready(int pid);
int process_fork_check_ready(int pid);
8 changes: 4 additions & 4 deletions include/fuzzy/memmgr/layout.asm
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
; constants only

; START_ENSURE_SAME_layout_h
MEMORY_APP_SIZE EQU 0x20000

MEMORY_APP_SIZE EQU 0x20000
MEMORY_KERNEL_SIZE EQU 0x64000
; END_ENSURE_SAME_layout_h

; Kernel core is app with pid 0
; Kernel event is trigged via IRQ0 or syscall,
STACKINIT_APP EQU (MEMORY_APP_SIZE-4)
STACKINIT_KERNEL_CORE EQU (STACKINIT_APP-4)
STACKINIT_KERNEL_CORE EQU (MEMORY_KERNEL_SIZE/2)

; Should be able to store
; - syscall and all internal calls
; - ISRs and all internal calls
STACKINIT_KERNEL_EVENT EQU 0x18000
STACKINIT_KERNEL_EVENT EQU (MEMORY_KERNEL_SIZE-4)

26 changes: 21 additions & 5 deletions include/fuzzy/memmgr/layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,32 @@
// START_ENSURE_SAME_layout_asm
#define MEMORY_APP_SIZE 0x20000
#define STACKINIT_APP (MEMORY_APP_SIZE-4)
#define MEMORY_REALLIBRARY_DATA_ADDRESS 0x70000
#define MEMORY_REALLIBRARY_DATA_SIZE 0x10000

// END_ENSURE_SAME_layout_asm

// Most of the memory layout relies on the fact the kernel is first app
// and kernel's pid is 0.
#define PID_KERNEL 0

#define MEMORY_APPBASE_LOCATION 0x10000
/*
* Bug:
* Bootloader stage 2 is not able to load kernel if
* memory address need 20 address lines (0x10000) in
* our case.
* It works as intended in QEMU but not in others.
* Mitigation:
* - Forcing MEMORY_KERNEL_LOCATION to be represented
* by 16 address lines. For ex 0xF000.
* Resolution:
* - I'm not sure.
*/
#define MEMORY_APPBASE_LOCATION 0x100000

#define memmgr_app_abs_location(pid) (MEMORY_APPBASE_LOCATION + (pid)*MEMORY_APP_SIZE)
#define memmgr_app_size(pid) (MEMORY_APP_SIZE)
// Keep in sync with memory_layout.md
#define memmgr_app_abs_location(pid) ((pid==PID_KERNEL)?0x0C000:(MEMORY_APPBASE_LOCATION + (pid)*MEMORY_APP_SIZE))
#define memmgr_app_size(pid) ((pid==PID_KERNEL)?0x64000:MEMORY_APP_SIZE)

#define MEMORY_KERNEL_LOCATION memmgr_app_abs_location(PID_KERNEL)
#define MEMORY_KERNEL_SIZE memmgr_app_size(PID_KERNEL)
#define MEMORY_KERNEL_LOCATION (memmgr_app_abs_location(PID_KERNEL))
#define MEMORY_KERNEL_SIZE (memmgr_app_size(PID_KERNEL))
21 changes: 21 additions & 0 deletions include/fuzzy/memmgr/tables/gdt.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
; constants only

; START_ENSURE_SAME_gdt_h

GDT_STD_SELECTOR_NULL EQU 0
GDT_STD_SELECTOR_KERNEL_CS EQU 1
GDT_STD_SELECTOR_KERNEL_DS EQU 2
GDT_STD_SELECTOR_ABS16_CS EQU 3
GDT_STD_SELECTOR_ABS16_DS EQU 4
GDT_STD_SELECTOR_ABS32_DS EQU 6
GDT_STD_SIZE EQU 7

GDT_STD_SIZEOF_ENTRY EQU 8
; END_ENSURE_SAME_gdt_h

GDT_NULL_CS EQU (GDT_STD_SELECTOR_NULL*GDT_STD_SIZEOF_ENTRY)
GDT_KERNEL_CS EQU (GDT_STD_SELECTOR_KERNEL_CS*GDT_STD_SIZEOF_ENTRY)
GDT_KERNEL_DS EQU (GDT_STD_SELECTOR_KERNEL_DS*GDT_STD_SIZEOF_ENTRY)
GDT_ABS16_CS EQU (GDT_STD_SELECTOR_ABS16_CS*GDT_STD_SIZEOF_ENTRY)
GDT_ABS16_DS EQU (GDT_STD_SELECTOR_ABS16_DS*GDT_STD_SIZEOF_ENTRY)
GDT_ABS32_DS EQU (GDT_STD_SELECTOR_ABS32_DS*GDT_STD_SIZEOF_ENTRY)
20 changes: 20 additions & 0 deletions include/fuzzy/memmgr/tables/gdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
// Min GDT_TABLE_SIZE: 5
// Max GDT_TABLE_SIZE: 8192

// START_ENSURE_SAME_gdt_asm
#define GDT_STD_SELECTOR_NULL 0
#define GDT_STD_SELECTOR_KERNEL_CS 1
#define GDT_STD_SELECTOR_KERNEL_DS 2
#define GDT_STD_SELECTOR_ABS16_CS 3
#define GDT_STD_SELECTOR_ABS16_DS 4
#define GDT_STD_SELECTOR_ABS32_DS 6
#define GDT_STD_SIZE 7
// Entries on and after GDT_STD_SIZE are reserved for applications
// and are in CS, DS order for each app.
// END_ENSURE_SAME_gdt_asm

#pragma pack(push, 1)
struct GDTReference {
unsigned short size;
Expand All @@ -18,6 +30,14 @@ struct GDTEntry {
};
#pragma pack(pop)

#define GDT_NULL_CS (GDT_STD_SELECTOR_NULL*sizeof(struct GDTEntry))
#define GDT_KERNEL_CS (GDT_STD_SELECTOR_KERNEL_CS*sizeof(struct GDTEntry))
#define GDT_KERNEL_DS (GDT_STD_SELECTOR_KERNEL_DS*sizeof(struct GDTEntry))
#define GDT_ABS16_CS (GDT_STD_SELECTOR_ABS16_CS*sizeof(struct GDTEntry))
#define GDT_ABS16_DS (GDT_STD_SELECTOR_ABS16_DS*sizeof(struct GDTEntry))
#define GDT_ABS32_DS (GDT_STD_SELECTOR_ABS32_DS*sizeof(struct GDTEntry))

int get_gdt_baseaddress(struct GDTEntry gdt_table[], unsigned int table_size, int entry_id);

void populate_gdt_entry(struct GDTEntry *entry,
unsigned int base,
Expand Down
24 changes: 15 additions & 9 deletions memory_layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

| From | To | Size | Usage |
|--------- |-------- |-------- |-------------------------------------------- |
| 0x00000 | fill | 31KB | RESERVED |
| 0x7C00 | 0x7DFF | 512B | BOOTLOADER STAGE 1 |
| 0x7E00 | 0x7FFF | 512B | SHARED STATIC CODE for real_mode library |
| 0x8000 | 0xBFFF | - | BOOT LOADER STAGE 2 + own stack |
| 0x10000 | 0x2FFFF | - | KERNEL |
| 0x30000 | 0x4FFFF | - | Application 0 |
| 0x50000 | 0x6FFFF | - | Application 1 |
...
| - | 0xFFFFF | - | 20-bit memory limit |
| 0x00000 | 0x003FF | - | IVT (standard) |
| 0x00400 | 0x07BFF | - | BIOS data area + reserve |
| 0x07C00 | 0x07DFF | 512B | Bootloader Stage 1 |
| 0x07E00 | 0x07FFF | 512B | STATIC CODE for real_mode library |
| 0x08000 | 0x0BFFF | 16KB | Bootloader Stage 2 + own stack |
| 0x0C000 | 0x6FFFF | 400KB | Kernel + (core, isr, syscall) stack |
| 0x70000 | 0x7FFFF | 64KB | Extra space for real_mode library+client |
| 0x80000 | 0x9FFFF | 128KB | Extended BIOS Data area |
| 0xA0000 | 0xBFFFF | 128KB | Video memory |
| 0xC0000 | 0xFFFFF | 256KB | BIOS stuff |
| 0x100000 | 0x1FFFFF | 1MB | pid 0; Kernel future location (not used) |
| 0x200000 | 0x2FFFFF | 1MB | App pid 1 |
| 0x300000 | 0x3FFFFF | 1MB | App pid 2 |
| ... | .... | ... | ... |
| ... | .... | 1MB | App pid 126 |
4 changes: 0 additions & 4 deletions scripts/build_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ function verify_subimage_and_push() {
echo "The ${subimage} size isn't divisible by 512" >&2
exit 2
fi
if [ "$(( $fsize / 512 ))" -lt ${min_sectors:?} ]; then
echo "The ${subimage} uses less sectors than ${min_sectors:?}" >&2
exit 2
fi
if [ "$(( $fsize / 512 ))" -gt ${max_sectors:?} ]; then
echo "The ${subimage} uses more sectors than ${max_sectors:?}" >&2
exit 2
Expand Down
2 changes: 1 addition & 1 deletion src/bootloader/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ $(bt_stage1): $(SRC_BOOTLOADER)/stage1.asm $(SRC_BOOTLOADER)/constants.asm $(SRC

$(bt_stage2).elf: $(SRC_BOOTLOADER)/stage2.asm $(SRC_BOOTLOADER)/stage2.c $(INCLUDE_DIR)/memmgr/tables/gdt.h $(SRC_MEMMGR)/tables/gdt.c $(SRC_BOOTLOADER)/io.asm $(SRC_BOOTLOADER)/constants.asm $(BUILD_LIB_UTILS)/libutils_16 $(BUILD_DRIVERS)/display/libtm_bios $(BUILD_DRIVERS)/disk/libdisk_16
mkdir -p $$(dirname $(bt_stage2))
nasm -o $(BUILD_BOOTLOADER)/stage2_asm.o -f elf32 -i $(SRC_BOOTLOADER)/ $(SRC_BOOTLOADER)/stage2.asm
$(NASM) -o $(BUILD_BOOTLOADER)/stage2_asm.o -i $(SRC_BOOTLOADER)/ $(SRC_BOOTLOADER)/stage2.asm
$(CC) -m16 -fno-pie -c -Isrc \
-Iinclude \
-D SECTOR_START_SHARED_LIBRARY=$(SECTOR_START_SHARED_LIBRARY) \
Expand Down
Loading