Skip to content

Commit

Permalink
kernel+userland: refactor initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
mosmeh committed Jun 16, 2024
1 parent d360519 commit 739dfa2
Show file tree
Hide file tree
Showing 29 changed files with 350 additions and 306 deletions.
20 changes: 11 additions & 9 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@ CFLAGS += -isystem..
TARGET := kernel

OBJS := \
ac97.o \
boot.o \
cmdline.o \
console/console.o \
console/fb_console.o \
console/psf.o \
console/serial_console.o \
console/system_console.o \
console/tty.o \
drivers/ac97.o \
drivers/drivers.o \
drivers/graphics/bochs.o \
drivers/graphics/fb.o \
drivers/graphics/multiboot.o \
drivers/hid/keyboard.o \
drivers/hid/mouse.o \
drivers/hid/ps2.o \
drivers/pseudo_device.o \
drivers/serial/serial.o \
exec.o \
fs/dentry.o \
fs/fifo.o \
Expand All @@ -22,13 +32,7 @@ OBJS := \
fs/tmpfs.o \
fs/vfs.o \
gdt.o \
graphics/bochs.o \
graphics/fb.o \
graphics/multiboot.o \
growable_buf.o \
hid/keyboard.o \
hid/mouse.o \
hid/ps2.o \
idt.o \
interrupt.o \
irq.o \
Expand All @@ -42,12 +46,10 @@ OBJS := \
pci.o \
pit.o \
process.o \
pseudo_device.o \
random.o \
ring_buf.o \
safe_string.o \
scheduler.o \
serial.o \
syscall/clock.o \
syscall/fs.o \
syscall/mmap.o \
Expand Down
11 changes: 11 additions & 0 deletions kernel/console/console.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "console.h"

void serial_console_init(void);
void fb_console_init(void);
void system_console_init(void);

void console_init(void) {
serial_console_init();
fb_console_init();
system_console_init();
}
10 changes: 1 addition & 9 deletions kernel/console/console.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
#pragma once

#include <kernel/api/hid.h>
#include <kernel/api/sys/types.h>
#include <stddef.h>

void fb_console_init(void);
struct inode* fb_console_device_get(void);
void console_init(void);

void serial_console_init(void);
void serial_console_on_char(uint16_t port, char);
struct inode* serial_console_device_create(uint16_t port);

void system_console_init(void);
struct inode* system_console_device_get(void);

void tty_maybe_send_signal(pid_t pgid, char ch);
75 changes: 39 additions & 36 deletions kernel/console/fb_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
#include <kernel/api/sys/poll.h>
#include <kernel/api/sys/sysmacros.h>
#include <kernel/api/sys/types.h>
#include <kernel/graphics/graphics.h>
#include <kernel/hid/hid.h>
#include <kernel/drivers/graphics/graphics.h>
#include <kernel/drivers/hid/hid.h>
#include <kernel/fs/fs.h>
#include <kernel/interrupts.h>
#include <kernel/lock.h>
#include <kernel/memory/memory.h>
Expand Down Expand Up @@ -490,39 +491,6 @@ static void on_key_event(const key_event* event) {
pop_cli(int_flag);
}

static bool initialized = false;
static mutex lock;

void fb_console_init(void) {
font = load_psf("/usr/share/fonts/ter-u16n.psf");
ASSERT_OK(font);

ASSERT_OK(fb_get_info(&fb_info));
ASSERT(fb_info.bpp == 32);

num_columns = fb_info.width / font->glyph_width;
num_rows = fb_info.height / font->glyph_height;

cells = kmalloc(num_columns * num_rows * sizeof(struct cell));
ASSERT(cells);
line_is_dirty = kmalloc(num_rows * sizeof(bool));
ASSERT(line_is_dirty);

size_t fb_size = fb_info.pitch * fb_info.height;
fb_addr = range_allocator_alloc(&kernel_vaddr_allocator, fb_size);
ASSERT_OK(fb_addr);
ASSERT_OK(
fb_mmap(fb_addr, fb_size, 0, PAGE_WRITE | PAGE_SHARED | PAGE_GLOBAL));

clear_screen();
flush();

ASSERT_OK(ring_buf_init(&input_buf));
ps2_set_key_event_handler(on_key_event);

initialized = true;
}

static bool can_read(void) {
bool int_flag = push_cli();
bool ret = !ring_buf_is_empty(&input_buf);
Expand Down Expand Up @@ -556,6 +524,8 @@ static ssize_t fb_console_device_read(file_description* desc, void* buffer,
}
}

static mutex lock;

static ssize_t fb_console_device_write(file_description* desc,
const void* buffer, size_t count) {
(void)desc;
Expand Down Expand Up @@ -610,7 +580,7 @@ static short fb_console_device_poll(file_description* desc, short events) {
return revents;
}

struct inode* fb_console_device_get(void) {
static struct inode* fb_console_device_get(void) {
static file_ops fops = {.read = fb_console_device_read,
.write = fb_console_device_write,
.ioctl = fb_console_device_ioctl,
Expand All @@ -621,3 +591,36 @@ struct inode* fb_console_device_get(void) {
.ref_count = 1};
return &inode;
}

void fb_console_init(void) {
if (!fb_get())
return;

font = load_psf("/usr/share/fonts/ter-u16n.psf");
ASSERT_OK(font);

ASSERT_OK(fb_get()->get_info(&fb_info));
ASSERT(fb_info.bpp == 32);

num_columns = fb_info.width / font->glyph_width;
num_rows = fb_info.height / font->glyph_height;

cells = kmalloc(num_columns * num_rows * sizeof(struct cell));
ASSERT(cells);
line_is_dirty = kmalloc(num_rows * sizeof(bool));
ASSERT(line_is_dirty);

size_t fb_size = fb_info.pitch * fb_info.height;
fb_addr = range_allocator_alloc(&kernel_vaddr_allocator, fb_size);
ASSERT_OK(fb_addr);
ASSERT_OK(fb_get()->mmap(fb_addr, fb_size, 0,
PAGE_WRITE | PAGE_SHARED | PAGE_GLOBAL));

clear_screen();
flush();

ASSERT_OK(ring_buf_init(&input_buf));
ps2_set_key_event_handler(on_key_event);

ASSERT_OK(vfs_register_device(fb_console_device_get()));
}
24 changes: 17 additions & 7 deletions kernel/console/serial_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,17 @@
#include <kernel/api/sys/ioctl.h>
#include <kernel/api/sys/poll.h>
#include <kernel/api/sys/sysmacros.h>
#include <kernel/drivers/serial/serial.h>
#include <kernel/interrupts.h>
#include <kernel/panic.h>
#include <kernel/process.h>
#include <kernel/ring_buf.h>
#include <kernel/safe_string.h>
#include <kernel/scheduler.h>
#include <kernel/serial.h>

static ring_buf input_bufs[4];
static pid_t pgid;

void serial_console_init(void) {
for (size_t i = 0; i < 4; ++i)
ASSERT_OK(ring_buf_init(input_bufs + i));
}

static ring_buf* get_input_buf_for_port(uint16_t port) {
uint8_t com_number = serial_port_to_com_number(port);
if (com_number)
Expand Down Expand Up @@ -111,7 +106,7 @@ static short serial_console_device_poll(file_description* desc, short events) {
return revents;
}

struct inode* serial_console_device_create(uint16_t port) {
static struct inode* serial_console_device_create(uint16_t port) {
if (!serial_is_valid_port(port))
return NULL;

Expand All @@ -134,3 +129,18 @@ struct inode* serial_console_device_create(uint16_t port) {

return inode;
}

void serial_console_init(void) {
for (size_t i = 0; i < 4; ++i)
ASSERT_OK(ring_buf_init(input_bufs + i));

const uint16_t ports[] = {SERIAL_COM1, SERIAL_COM2, SERIAL_COM3,
SERIAL_COM4};
for (size_t i = 0; i < ARRAY_SIZE(ports); ++i) {
if (serial_is_port_enabled(ports[i])) {
struct inode* device = serial_console_device_create(ports[i]);
ASSERT_OK(device);
ASSERT_OK(vfs_register_device(device));
}
}
}
29 changes: 19 additions & 10 deletions kernel/console/system_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
#include <kernel/memory/memory.h>
#include <kernel/panic.h>

static file_description* active_console = NULL;

void system_console_init(void) {
active_console = vfs_open("/dev/tty", O_RDWR, 0);
if (IS_OK(active_console))
return;
static struct inode* get_tty_device(void) {
struct inode* device = vfs_get_device(makedev(5, 0)); // /dev/tty
if (device)
return device;

active_console = vfs_open("/dev/ttyS0", O_RDWR, 0);
if (IS_OK(active_console))
return;
device = vfs_get_device(makedev(4, 64)); // /dev/ttyS0
if (device)
return device;

UNIMPLEMENTED();
return NULL;
}

static file_description* active_console = NULL;

static ssize_t system_console_device_read(file_description* desc, void* buffer,
size_t count) {
(void)desc;
Expand Down Expand Up @@ -49,3 +49,12 @@ struct inode* system_console_device_get(void) {
.ref_count = 1};
return &inode;
}

void system_console_init(void) {
struct inode* device = get_tty_device();
ASSERT_OK(device);
active_console = inode_open(device, O_RDWR, 0);
ASSERT_OK(active_console);

ASSERT_OK(vfs_register_device(system_console_device_get()));
}
91 changes: 46 additions & 45 deletions kernel/ac97.c → kernel/drivers/ac97.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#include "api/err.h"
#include "api/sound.h"
#include "api/sys/poll.h"
#include "api/sys/sysmacros.h"
#include "boot_defs.h"
#include "fs/fs.h"
#include "interrupts.h"
#include "memory/memory.h"
#include "pci.h"
#include "safe_string.h"
#include "system.h"
#include <kernel/api/err.h>
#include <kernel/api/sound.h>
#include <kernel/api/sys/poll.h>
#include <kernel/api/sys/sysmacros.h>
#include <kernel/boot_defs.h>
#include <kernel/fs/fs.h>
#include <kernel/interrupts.h>
#include <kernel/memory/memory.h>
#include <kernel/panic.h>
#include <kernel/pci.h>
#include <kernel/safe_string.h>
#include <kernel/system.h>
#include <string.h>

#define PCI_CLASS_MULTIMEDIA 4
Expand Down Expand Up @@ -83,39 +84,6 @@ static void irq_handler(registers* regs) {
buffer_descriptor_list_is_full = false;
}

bool ac97_init(void) {
pci_enumerate(pci_enumeration_callback);
if (!device_detected)
return false;

pci_set_interrupt_line_enabled(&device_addr, true);
pci_set_bus_mastering_enabled(&device_addr, true);

uint32_t control = in32(bus_base + BUS_GLOBAL_CONTROL);
control |= GLOBAL_CONTROL_GLOBAL_INTERRUPT_ENABLE;
control |= GLOBAL_CONTROL_COLD_RESET;
out32(bus_base + BUS_GLOBAL_CONTROL, control);

out16(mixer_base + MIXER_RESET_REGISTER, 1);

out16(mixer_base + MIXER_SAMPLE_RATE, 48000);

// zero attenuation i.e. full volume
out16(mixer_base + MIXER_MASTER_OUTPUT_VOLUME, 0);
out16(mixer_base + MIXER_PCM_OUTPUT_VOLUME, 0);

pcm_out_channel = bus_base + BUS_PCM_OUT;
out8(pcm_out_channel + CHANNEL_TRANSFTER_CONTROL, TRANSFER_CONTROL_RESET);
while (in8(pcm_out_channel + CHANNEL_TRANSFTER_CONTROL) &
TRANSFER_CONTROL_RESET)
delay(50);

uint8_t irq_num = pci_get_interrupt_line(&device_addr);
idt_set_interrupt_handler(IRQ(irq_num), irq_handler);

return true;
}

#define OUTPUT_BUF_NUM_PAGES 4

alignas(PAGE_SIZE) static unsigned char output_buf[OUTPUT_BUF_NUM_PAGES *
Expand Down Expand Up @@ -273,7 +241,7 @@ static short ac97_device_poll(file_description* desc, short events) {
return revents;
}

struct inode* ac97_device_get(void) {
static struct inode* ac97_device_get(void) {
static file_ops fops = {.write = ac97_device_write,
.ioctl = ac97_device_ioctl,
.poll = ac97_device_poll};
Expand All @@ -283,3 +251,36 @@ struct inode* ac97_device_get(void) {
.ref_count = 1};
return &inode;
}

void ac97_init(void) {
pci_enumerate(pci_enumeration_callback);
if (!device_detected)
return;

pci_set_interrupt_line_enabled(&device_addr, true);
pci_set_bus_mastering_enabled(&device_addr, true);

uint32_t control = in32(bus_base + BUS_GLOBAL_CONTROL);
control |= GLOBAL_CONTROL_GLOBAL_INTERRUPT_ENABLE;
control |= GLOBAL_CONTROL_COLD_RESET;
out32(bus_base + BUS_GLOBAL_CONTROL, control);

out16(mixer_base + MIXER_RESET_REGISTER, 1);

out16(mixer_base + MIXER_SAMPLE_RATE, 48000);

// zero attenuation i.e. full volume
out16(mixer_base + MIXER_MASTER_OUTPUT_VOLUME, 0);
out16(mixer_base + MIXER_PCM_OUTPUT_VOLUME, 0);

pcm_out_channel = bus_base + BUS_PCM_OUT;
out8(pcm_out_channel + CHANNEL_TRANSFTER_CONTROL, TRANSFER_CONTROL_RESET);
while (in8(pcm_out_channel + CHANNEL_TRANSFTER_CONTROL) &
TRANSFER_CONTROL_RESET)
delay(50);

uint8_t irq_num = pci_get_interrupt_line(&device_addr);
idt_set_interrupt_handler(IRQ(irq_num), irq_handler);

ASSERT_OK(vfs_register_device(ac97_device_get()));
}
Loading

0 comments on commit 739dfa2

Please sign in to comment.