diff options
author | Anton Kling <anton@kling.gg> | 2024-11-28 00:06:09 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-11-28 00:12:17 +0100 |
commit | 54869df7835565d0983096f65326cdd2d5f4f3d8 (patch) | |
tree | 3124d37d170bb14bfcc315442e410c0b76a05cf1 /kernel | |
parent | 5fdba54196c7171ddebb29aef597b965a1b1ead1 (diff) |
changes
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Makefile | 4 | ||||
-rw-r--r-- | kernel/arch/i386/tsc.c | 16 | ||||
-rw-r--r-- | kernel/cpu/syscall.c | 16 | ||||
-rw-r--r-- | kernel/drivers/ac97.c | 233 | ||||
-rw-r--r-- | kernel/drivers/ac97.h | 1 | ||||
-rw-r--r-- | kernel/drivers/pit.c | 1 | ||||
-rw-r--r-- | kernel/fs/ext2.c | 22 | ||||
-rw-r--r-- | kernel/init/kernel.c | 6 | ||||
-rw-r--r-- | kernel/kmalloc.c | 6 | ||||
-rw-r--r-- | kernel/network/udp.c | 1 | ||||
-rw-r--r-- | kernel/sched/scheduler.c | 1 | ||||
-rw-r--r-- | kernel/socket.c | 6 |
12 files changed, 290 insertions, 23 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 55a1ae6..bb9abff 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,8 +1,10 @@ CC="i686-sb-gcc" AS="i686-sb-as" -OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o kubsan.o drivers/serial.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o elf.o ksbrk.o sched/scheduler.o libc/string/copy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o math.o signal.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o arch/i386/interrupts.o cpu/isr.o lib/stack.o lib/buffered_write.o lib/list.o cpu/arch_inst.o cpu/int_syscall.o lib/ringbuffer.o lib/relist.o arch/i386/tsc.o arch/i386/asm_tsc.o drivers/cmos.o timer.o queue.o drivers/virtio.o fonts.o +OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o kubsan.o drivers/serial.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o elf.o ksbrk.o sched/scheduler.o libc/string/copy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o math.o signal.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o arch/i386/interrupts.o cpu/isr.o lib/stack.o lib/buffered_write.o lib/list.o cpu/arch_inst.o cpu/int_syscall.o lib/ringbuffer.o lib/relist.o arch/i386/tsc.o arch/i386/asm_tsc.o drivers/cmos.o timer.o queue.o fonts.o drivers/ac97.o CFLAGS = -std=c99 -O0 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Wextra -Wno-int-conversion -Wno-unused-parameter -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL LDFLAGS= +#CFLAGS = -std=c99 -O3 -flto -ggdb -ffreestanding -Wall -Wextra -Wno-int-conversion -Wno-unused-parameter -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL +#LDFLAGS= -O3 -flto INCLUDE=-I./includes/ -I../include/ -I./libc/include/ all: myos.iso diff --git a/kernel/arch/i386/tsc.c b/kernel/arch/i386/tsc.c new file mode 100644 index 0000000..a4f3c3f --- /dev/null +++ b/kernel/arch/i386/tsc.c @@ -0,0 +1,16 @@ +#include <arch/i386/tsc.h> + +u64 cpu_mhz = 0; +u64 tsc_get_hz(void); + +void tsc_init(void) { + cpu_mhz = tsc_get_hz() / 10000; +} + +u64 tsc_get_mhz() { + return cpu_mhz; +} + +u64 tsc_calculate_ms(u64 tsc) { + return tsc / (cpu_mhz * 1000); +} diff --git a/kernel/cpu/syscall.c b/kernel/cpu/syscall.c index c68c4fe..1c10641 100644 --- a/kernel/cpu/syscall.c +++ b/kernel/cpu/syscall.c @@ -146,8 +146,7 @@ int syscall_clock_gettime(clockid_t clock_id, struct timespec *tp) { int syscall_fstat(int fd, struct stat *buf) { if (!mmu_is_valid_userpointer(buf, sizeof(struct stat))) { - return -EPERM; // TODO: Is this correct? The spec says nothing about - // this case. + return -EFAULT; } return vfs_fstat(fd, buf); } @@ -210,15 +209,18 @@ int syscall_munmap(void *addr, size_t length) { } int syscall_open(const char *file, int flags, mode_t mode) { - const char *_file = copy_and_allocate_user_string(file); - if (!_file) { + size_t len; + if (!mmu_is_valid_user_c_string(file, &len)) { return -EFAULT; } + if (len > 256 - 1) { + return -ENAMETOOLONG; + } + char _file[256]; + strlcpy(_file, file, 256); int _flags = flags; int _mode = mode; - int rc = vfs_open(_file, _flags, _mode); - kfree((void *)_file); - return rc; + return vfs_open(_file, _flags, _mode); } int syscall_open_process(int pid) { diff --git a/kernel/drivers/ac97.c b/kernel/drivers/ac97.c new file mode 100644 index 0000000..24899dd --- /dev/null +++ b/kernel/drivers/ac97.c @@ -0,0 +1,233 @@ +#include <assert.h> +#include <cpu/io.h> +#include <drivers/ac97.h> +#include <drivers/pci.h> +#include <fcntl.h> +#include <fs/vfs.h> +#include <kmalloc.h> +#include <random.h> + +struct PCI_DEVICE ac97; +struct PCI_BaseAddressRegister nabm; +struct PCI_BaseAddressRegister nam; + +int current_pointer = 0; + +void *physical_buffer_descriptor_list; +u16 *buffer_descriptor_list; +u16 *pointer; + +struct audio_buffer { + volatile u8 *data; + uintptr_t physical; + int has_played; +}; + +struct audio_buffer buffers[32]; + +void add_buffer(void) { + u16 *pointer = buffer_descriptor_list; + for (int i = 0; i < 4; i++) { + void *physical_audio_data; + u8 *audio_data = kmalloc_align(128000, &physical_audio_data); + + buffers[i].data = audio_data; + buffers[i].physical = physical_audio_data; + buffers[i].has_played = 1; + + *((u32 *)pointer) = physical_audio_data; + pointer += 2; + *pointer = 128000 / 2; + pointer++; + *pointer = (1 << 14); + pointer++; + } +} + +void add_to_list(u8 *buffer, size_t size) { + void *physical_audio_data; + u8 *audio_data = kmalloc_align(size, &physical_audio_data); + memcpy(audio_data, buffer, size); + + // Write number of last valid buffer entry to Last Valid Entry + // register (NABM register 0x15) + outb(nabm.address + 0x10 + 0x5, 1); + + // Set bit for transfering data (NABM register 0x1B, value 0x1) + u8 s = inb(nabm.address + 0x10 + 0xB); + s |= (1 << 0); + outb(nabm.address + 0x10 + 0xB, s); + + outl(nabm.address + 0x10 + 0x0, physical_buffer_descriptor_list); +} + +int entry = 0; + +void start(void) { + // // Write number of last valid buffer entry to Last Valid Entry + // // register (NABM register 0x15) + // outb(nabm.address + 0x10 + 0x5, 1); + + // Set bit for transfering data (NABM register 0x1B, value 0x1) + u8 s = inb(nabm.address + 0x10 + 0xB); + if (s & (1 << 0)) { + return; + } + s |= (1 << 0); + outb(nabm.address + 0x10 + 0xB, s); +} + +void play_pcm(u8 *buffer, size_t size) { + if (entry >= 3) { + outb(nabm.address + 0x10 + 0x5, entry - 1); + return; + } + if (!buffers[entry].has_played) { + for (;;) { + u8 process_num = inb(nabm.address + 0x10 + 0x4); + kprintf("process_num: %d\n", process_num); + if (process_num > entry) { + buffers[entry].has_played = 1; + break; + } + } + } + memcpy((u8 *)buffers[entry].data, buffer, size); + outb(nabm.address + 0x10 + 0x5, entry); + buffers[entry].has_played = 0; + + entry++; + + /* + u8 process_num = inb(nabm.address + 0x10 + 0x4); + kprintf("process_num: %d\n", process_num); + + if (0 == process_num) + return; + */ +} + +void ac97_init(void) { + if (!pci_populate_device_struct(0x8086, 0x2415, &ac97)) { + assert(0); + return; + } + pointer = buffer_descriptor_list = + kmalloc_align(0x1000, &physical_buffer_descriptor_list); + + // Enable bus mastering + u32 register1 = pci_config_read32(&ac97, 0, 0x4); + register1 |= (1 << 0); + register1 |= (1 << 2); + pci_config_write32(&ac97, 0, 0x4, register1); + + assert(pci_get_bar(&ac97, 1, &nabm)); + assert(nabm.type == PCI_BAR_IO); + + assert(pci_get_bar(&ac97, 0, &nam)); + assert(nam.type == PCI_BAR_IO); + + /* + In initalization of sound card you must resume card from cold reset + and set power for it. It can be done by writing value 0x2 to Global + Control register if you do not want to use interrupts, or 0x3 if you + want to use interrupts. + */ + + outl(nabm.address + 0x2C, (1 << 1)); + + /* + After this, you should write any value to NAM + Reset register to reset all NAM registers. + */ + + outw(nam.address + 0x0, 0x1); + + /* + After this, you can read + card capability info from Global Status register to found out if 20 + bit audio samples are supported and also check out bit 4 in NAM + Capabilites register and value in AUX Output to find out if this sound + card support headhone output. + */ + + // 0x30 Global Status Register dword + u32 status = inl(nabm.address + 0x30); + + u8 channel_capabilities = (status >> 20) & 0x3; + u8 sample_capabilities = (status >> 22) & 0x3; + kprintf("channel: %d\n", channel_capabilities); + kprintf("sample: %d\n", sample_capabilities); + + // outw(nam.address + 0x2C, 16000 / 2); + outw(nam.address + 0x2C, 48000 / 2); + u16 sample_rate = inw(nam.address + 0x2C); + kprintf("sample_rate: %d\n", sample_rate); + sample_rate = inw(nam.address + 0x2E); + kprintf("sample_rate: %d\n", sample_rate); + sample_rate = inw(nam.address + 0x30); + kprintf("sample_rate: %d\n", sample_rate); + sample_rate = inw(nam.address + 0x32); + kprintf("sample_rate: %d\n", sample_rate); + + /* + As last thing, set maximal volume for + PCM Output by writing value 0 to this register. Now sound card is + ready to use. + */ + + // Set PCM Output Volume + outw(nam.address + 0x18, 0); + + // Playing sound + /* + Set volume of output you want to use - Master Volume register (NAM + register 0x02) for speaker and if supported, AUX Output register (NAM + register 0x04) for headphone + */ + // FIXME: Speaker but is this correct? + outw(nam.address + 0x02, 0); + outw(nam.address + 0x04, 0); + + // SETUP? + + // Set reset bit of output channel (NABM register 0x1B, value 0x2) and + // wait for card to clear it + u8 s = inb(nabm.address + 0x10 + 0xB); + s |= (1 << 1); + outb(nabm.address + 0x10 + 0xB, s); + + kprintf("wait for clear\n"); + for (; inb(nabm.address + 0x10 + 0xB) & (1 << 1);) + ; + kprintf("cleared\n"); + + add_buffer(); + + // Write physical position of BDL to Buffer Descriptor Base Address + // register (NABM register 0x10) + outl(nabm.address + 0x10 + 0x0, physical_buffer_descriptor_list); + + // END SETUP? + + int fd = vfs_open("/hq.pcm", O_RDONLY, 0); + assert(0 >= fd); + size_t offset = 0; + size_t capacity = 128000; + char *data = kmalloc(capacity); + for (;;) { + int rc = vfs_pread(fd, data, capacity, offset); + if (0 == rc) { + break; + } + if (rc < 0) { + kprintf("rc: %d\n", rc); + assert(0); + } + play_pcm(data, rc); + start(); + offset += rc; + } + for (;;) + ; +} diff --git a/kernel/drivers/ac97.h b/kernel/drivers/ac97.h new file mode 100644 index 0000000..02be9a0 --- /dev/null +++ b/kernel/drivers/ac97.h @@ -0,0 +1 @@ +void ac97_init(void); diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index 8210aa7..bed8682 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -47,6 +47,7 @@ u64 last_tsc = 0; extern u64 timer_current_uptime; extern int is_switching_tasks; +void handle_packet(); void int_clock(reg_t *regs) { kmalloc_scan(); u64 current_tsc = tsc_get(); diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index db95e33..dc56ea1 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -31,7 +31,7 @@ void get_inode_data_size(int inode_num, u64 *file_size) { read_inode(inode_num, NULL, 0, 0, file_size); } -struct BLOCK_CACHE { +struct block_cache { int is_used; u32 last_use; u32 block_num; @@ -39,15 +39,15 @@ struct BLOCK_CACHE { u8 has_write; }; -#define NUM_BLOCK_CACHE 100 -struct BLOCK_CACHE cache[NUM_BLOCK_CACHE]; +size_t num_block_cache = 4; +struct block_cache *cache; u32 cold_cache_hits = 0; void cached_read_block(u32 block, void *address, size_t size, size_t offset) { assert(offset + size <= block_byte_size); int free_found = -1; - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + for (size_t i = 0; i < num_block_cache; i++) { if (!cache[i].is_used) { free_found = i; continue; @@ -62,7 +62,7 @@ void cached_read_block(u32 block, void *address, size_t size, size_t offset) { if (-1 == free_found) { u32 min_last_used = U32_MAX; int min_index = 0; - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + for (size_t i = 0; i < num_block_cache; i++) { if (cache[i].last_use < min_last_used) { min_last_used = cache[i].last_use; min_index = i; @@ -71,7 +71,7 @@ void cached_read_block(u32 block, void *address, size_t size, size_t offset) { free_found = min_index; } - struct BLOCK_CACHE *c = &cache[free_found]; + struct block_cache *c = &cache[free_found]; if (c->is_used && c->has_write) { raw_vfs_pwrite(mount_fd, c->block, block_byte_size, c->block_num * block_byte_size); @@ -89,7 +89,7 @@ void ext2_read_block(u32 block, void *address, size_t size, size_t offset) { } void ext2_flush_writes(void) { - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + for (size_t i = 0; i < num_block_cache; i++) { if (!cache[i].is_used) { continue; } @@ -105,7 +105,7 @@ void ext2_flush_writes(void) { void ext2_write_block(u32 block, u8 *address, size_t size, size_t offset) { assert(offset + size <= block_byte_size); int cache_index = -1; - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + for (size_t i = 0; i < num_block_cache; i++) { if (!cache[i].is_used) { continue; } @@ -949,7 +949,7 @@ vfs_inode_t *ext2_mount(void) { relist_remove(¤t_task->file_descriptors, fd); parse_superblock(); - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + for (size_t i = 0; i < num_block_cache; i++) { cache[i].block = kmalloc(block_byte_size); if (!cache[i].block) { goto ext2_mount_error; @@ -967,7 +967,7 @@ vfs_inode_t *ext2_mount(void) { return inode; ext2_mount_error: vfs_close(fd); - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + for (size_t i = 0; i < num_block_cache; i++) { kfree(cache[i].block); } return NULL; @@ -991,4 +991,6 @@ void parse_superblock(void) { } inodes_per_block = block_byte_size / inode_size; + + cache = kcalloc(num_block_cache, sizeof(struct block_cache)); } diff --git a/kernel/init/kernel.c b/kernel/init/kernel.c index 2e569cb..e53aeeb 100644 --- a/kernel/init/kernel.c +++ b/kernel/init/kernel.c @@ -5,6 +5,7 @@ #include <cpu/spinlock.h> #include <cpu/syscall.h> #include <crypto/SHA1/sha1.h> +#include <drivers/ac97.h> #include <drivers/ahci.h> #include <drivers/ata.h> #include <drivers/keyboard.h> @@ -124,6 +125,11 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, enable_interrupts(); add_vbe_device(); + + // ac97_init(); + // for (;;) + // ; + int pid; if (0 == (pid = fork())) { char *argv[] = {"/init", NULL}; diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c index 19ed252..bea9431 100644 --- a/kernel/kmalloc.c +++ b/kernel/kmalloc.c @@ -123,11 +123,7 @@ void kmalloc_scan(void) { } static MallocHeader *next_close_header(MallocHeader *a) { - if (!a) { - kprintf("next close header fail\n"); - for (;;) - ; - } + assert(a); if (a->flags & IS_FINAL) { return NULL; } diff --git a/kernel/network/udp.c b/kernel/network/udp.c index 6b40c1a..e9eb87c 100644 --- a/kernel/network/udp.c +++ b/kernel/network/udp.c @@ -1,5 +1,6 @@ #include <assert.h> #include <network/bytes.h> +#include <network/ethernet.h> #include <network/ipv4.h> #include <network/udp.h> #include <socket.h> diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c index 34ea859..4f2fafa 100644 --- a/kernel/sched/scheduler.c +++ b/kernel/sched/scheduler.c @@ -660,6 +660,7 @@ int munmap(void *addr, size_t length) { continue; } if (addr == m->u_address) { + assert(m->underlying_object); assert(m->underlying_object->num_of_references > 0); m->underlying_object->num_of_references--; mmu_remove_virtual_physical_address_mapping(m->u_address, m->length); diff --git a/kernel/socket.c b/kernel/socket.c index ad24134..37a8463 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -297,6 +297,9 @@ int tcp_has_data(vfs_inode_t *inode) { if (TCP_STATE_ESTABLISHED != con->state) { inode->is_open = 0; } + if (TCP_STATE_ESTABLISHED != con->state) { + return 1; + } return !(ringbuffer_isempty(&con->incoming_buffer)); } @@ -309,6 +312,9 @@ int tcp_can_write(vfs_inode_t *inode) { if (con->no_delay) { return (0 != tcp_can_send(con)); } + if (TCP_STATE_ESTABLISHED != con->state) { + return 1; + } return (ringbuffer_unused(&con->outgoing_buffer) > 0) || (0 != tcp_can_send(con)); } |