diff options
-rw-r--r-- | kernel/arch/i386/mmu.c | 103 | ||||
-rw-r--r-- | kernel/drivers/pit.c | 12 | ||||
-rw-r--r-- | kernel/includes/mmu.h | 4 | ||||
-rw-r--r-- | kernel/init/kernel.c | 4 | ||||
-rw-r--r-- | kernel/network/tcp.c | 9 | ||||
-rw-r--r-- | kernel/process.s | 10 | ||||
-rwxr-xr-x | meta/run.sh | 3 | ||||
-rw-r--r-- | userland/irc/irc.c | 49 |
8 files changed, 125 insertions, 69 deletions
diff --git a/kernel/arch/i386/mmu.c b/kernel/arch/i386/mmu.c index ad415a6..8761dd8 100644 --- a/kernel/arch/i386/mmu.c +++ b/kernel/arch/i386/mmu.c @@ -17,16 +17,20 @@ PageDirectory *kernel_directory; PageDirectory real_kernel_directory; PageDirectory *active_directory = 0; +u32 num_allocated_frames = 0; + #define END_OF_MEMORY 0x8000000 * 15 -u64 num_of_frames; -u32 *frames; u64 available_memory_kb; -u32 num_allocated_frames = 0; + +u32 num_array_frames = 1024; +u32 tmp_array[1024]; +u32 *tmp_small_frames = tmp_array; #define KERNEL_START 0xc0000000 extern uintptr_t data_end; -void write_to_frame(u32 frame_address, u8 on); +void change_frame(u32 frame, int on); +u32 get_free_frame(void); void *ksbrk(size_t s) { uintptr_t rc = (uintptr_t)align_page((void *)data_end); @@ -37,7 +41,6 @@ void *ksbrk(size_t s) { // If there is no active pagedirectory we // just assume that the memory is // already mapped. - get_fast_insecure_random((void *)rc, data_end - rc); return (void *)rc; } // Determine whether we are approaching a unallocated table @@ -59,7 +62,6 @@ void *ksbrk(size_t s) { mmu_allocate_shared_kernel_region((void *)rc, (data_end - (uintptr_t)rc)); assert(((uintptr_t)rc % PAGE_SIZE) == 0); - get_fast_insecure_random((void *)rc, data_end - rc); return (void *)rc; } @@ -132,20 +134,18 @@ void *align_page(void *a) { } u32 first_free_frame(void) { - for (u32 i = 1; i < INDEX_FROM_BIT(num_of_frames); i++) { - if (frames[i] == 0xFFFFFFFF) { + u32 i = 1; + for (; i < INDEX_FROM_BIT(num_array_frames * 32); i++) { + if (tmp_small_frames[i] == 0xFFFFFFFF) { continue; } for (u32 c = 0; c < 32; c++) { - if (!(frames[i] & ((u32)1 << c))) { + if (!(tmp_small_frames[i] & ((u32)1 << c))) { return i * 32 + c; } } } - - kprintf("ERROR Num frames: %x\n", mmu_get_number_of_allocated_frames()); - klog("No free frames, uh oh.", LOG_ERROR); assert(0); return 0; } @@ -154,11 +154,13 @@ void write_to_frame(u32 frame_address, u8 on) { u32 frame = frame_address / 0x1000; if (on) { num_allocated_frames++; - frames[INDEX_FROM_BIT(frame)] |= ((u32)0x1 << OFFSET_FROM_BIT(frame)); + tmp_small_frames[INDEX_FROM_BIT(frame)] |= + ((u32)0x1 << OFFSET_FROM_BIT(frame)); return; } num_allocated_frames--; - frames[INDEX_FROM_BIT(frame)] &= ~((u32)0x1 << OFFSET_FROM_BIT(frame)); + tmp_small_frames[INDEX_FROM_BIT(frame)] &= + ~((u32)0x1 << OFFSET_FROM_BIT(frame)); } PageDirectory *get_active_pagedirectory(void) { @@ -441,7 +443,6 @@ void mmu_map_physical(void *dst, PageDirectory *d, void *physical, p->frame = (uintptr_t)physical / PAGE_SIZE; write_to_frame((uintptr_t)physical, 1); } - flush_tlb(); } struct PhysVirtMap { @@ -591,12 +592,33 @@ void create_table(int table_index) { kernel_directory->physical_tables[table_index] = (u32)physical | 0x3; } -void paging_init(u64 memsize) { +void paging_init(u64 memsize, multiboot_info_t *mb) { u32 *cr3 = (void *)get_cr3(); u32 *virtual = (u32 *)((u32)cr3 + 0xC0000000); - frames = ksbrk(1024 * sizeof(u32)); - memset(frames, 0, 1024 * sizeof(u32)); - num_of_frames = 1024 * 32; + + u32 num_of_frames = 0; + + memset(tmp_small_frames, 0xFF, num_array_frames * sizeof(u32)); + { + multiboot_memory_map_t *map = + (multiboot_memory_map_t *)(mb->mmap_addr + 0xc0000000); + for (int length = 0; length < mb->mmap_length;) { + if (MULTIBOOT_MEMORY_AVAILABLE == map->type) { + num_of_frames = max(num_of_frames, map->addr + map->len); + for (size_t i = 0; i < map->len; i += 0x20000) { + u32 frame = (map->addr + i) / 0x1000; + if (frame < (num_array_frames * 32)) { + tmp_small_frames[INDEX_FROM_BIT(frame)] = 0; + } + } + } + u32 delta = (uintptr_t)map->size + sizeof(map->size); + map = (multiboot_memory_map_t *)((uintptr_t)map + delta); + length += delta; + } + } + num_of_frames /= 0x1000; + num_of_frames /= 32; kernel_directory = &real_kernel_directory; kernel_directory->physical_address = (u32)cr3; @@ -636,24 +658,29 @@ void paging_init(u64 memsize) { switch_page_directory(clone_directory(kernel_directory)); move_stack(0xA0000000, 0x80000); - u64 buffer_size = (memsize / 32) * sizeof(u32); - // TODO: Very hacky solution since we have to memcpy the old allocation. This - // places a strict requierment on how much RAM the system can have(altough it - // is very small). Ideally the number of frames required would be dynamically - // calculated. - assert(buffer_size >= 1024 * sizeof(u32)); - - // TODO Do this better - // NOTE: - // There are some addresses that point to devices rather than RAM. - // Therefore we need frames for these to exist - u64 min_buffer_required = 0xFD000 + 0x100000; - buffer_size = max(min_buffer_required, buffer_size); - available_memory_kb = memsize; - num_of_frames = available_memory_kb / 4; - u32 *new_frames = ksbrk(buffer_size); - memset(new_frames, 0, buffer_size); - memcpy(new_frames, frames, 1024 * sizeof(u32)); - frames = new_frames; + + void *new = kmalloc(num_of_frames * sizeof(u32)); + memset(new, 0xFF, num_of_frames * sizeof(u32)); + memcpy(new, tmp_small_frames, num_array_frames * sizeof(u32)); + tmp_small_frames = new; + { + multiboot_memory_map_t *map = + (multiboot_memory_map_t *)(mb->mmap_addr + 0xc0000000); + for (int length = 0; length < mb->mmap_length;) { + if (MULTIBOOT_MEMORY_AVAILABLE == map->type) { + for (size_t i = 0; i < map->len - 0x1000; i += 0x20000) { + u32 frame = (map->addr + i) / 0x1000; + if (frame > (num_array_frames * 32)) { + assert(INDEX_FROM_BIT(frame) <= num_of_frames); + tmp_small_frames[INDEX_FROM_BIT(frame)] = 0; + } + } + } + u32 delta = (uintptr_t)map->size + sizeof(map->size); + map = (multiboot_memory_map_t *)((uintptr_t)map + delta); + length += delta; + } + } + num_array_frames = num_of_frames; } diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index 30fd3ed..41c0d2a 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -44,16 +44,14 @@ void set_pit_count(u16 _hertz) { } void int_clock(reg_t *regs) { - EOI(0x20); - pit_counter++; - if (pit_counter * 1000 >= hertz) { - pit_counter = 0; - clock_num_ms_ticks += 1000 / hertz; - } + clock_num_ms_ticks++; switch_counter++; - if (switch_counter * 500 >= hertz) { + if (switch_counter >= hertz) { + EOI(0x20); switch_counter = 0; switch_task(); + } else { + EOI(0x20); } } diff --git a/kernel/includes/mmu.h b/kernel/includes/mmu.h index 68fd134..1a3f7c9 100644 --- a/kernel/includes/mmu.h +++ b/kernel/includes/mmu.h @@ -1,6 +1,7 @@ #ifndef PAGING_H #define PAGING_H #include "kmalloc.h" +#include <multiboot.h> #include <typedefs.h> typedef u8 mmu_flags; @@ -49,7 +50,7 @@ void *mmu_is_valid_userpointer(const void *ptr, size_t s); void *mmu_is_valid_user_c_string(const char *ptr, size_t *size); void flush_tlb(void); -void paging_init(u64 memsize); +void paging_init(u64 memsize, multiboot_info_t *mb); PageDirectory *get_active_pagedirectory(void); void move_stack(u32 new_stack_address, u32 size); void switch_page_directory(PageDirectory *directory); @@ -58,6 +59,7 @@ PageDirectory *clone_directory(PageDirectory *original); void *virtual_to_physical(void *address, PageDirectory *directory); void *ksbrk(size_t s); void *ksbrk_physical(size_t s, void **physical); +void write_to_frame(u32 frame_address, u8 on); Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, int set_user); diff --git a/kernel/init/kernel.c b/kernel/init/kernel.c index ef7cdae..180aaa8 100644 --- a/kernel/init/kernel.c +++ b/kernel/init/kernel.c @@ -43,7 +43,6 @@ uintptr_t data_end; void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, u32 inital_stack) { - (void)kernel_end; data_end = 0xc0400000; inital_esp = inital_stack; @@ -55,7 +54,8 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, u32 mem_kb = mb->mem_lower; u32 mem_mb = (mb->mem_upper - 1000) / 1000; u64 memsize_kb = mem_mb * 1000 + mem_kb; - paging_init(memsize_kb); + + paging_init(memsize_kb, mb); klog("Paging Initalized", LOG_SUCCESS); mb = mmu_map_frames((multiboot_info_t *)addr, sizeof(multiboot_info_t)); diff --git a/kernel/network/tcp.c b/kernel/network/tcp.c index b929005..dd6e6a8 100644 --- a/kernel/network/tcp.c +++ b/kernel/network/tcp.c @@ -162,12 +162,11 @@ void send_tcp_packet(struct TcpConnection *con, const u8 *payload, void handle_tcp(ipv4_t src_ip, const u8 *payload, u32 payload_length) { const struct TCP_HEADER *header = (const struct TCP_HEADER *)payload; (void)header; - u16 n_src_port = *(u16 *)(payload); - u16 n_dst_port = *(u16 *)(payload + 2); - u32 n_seq_num = *(u32 *)(payload + 4); - u32 n_ack_num = *(u32 *)(payload + 8); + u16 n_src_port = header->src_port; + u16 n_dst_port = header->dst_port; + u32 n_seq_num = header->seq_num; + u32 n_ack_num = header->ack_num; - // u8 flags = *(payload + 13); u8 flags = header->flags; u16 src_port = htons(n_src_port); diff --git a/kernel/process.s b/kernel/process.s index caef941..934d627 100644 --- a/kernel/process.s +++ b/kernel/process.s @@ -128,15 +128,13 @@ switch_to_task: mov eax,[esi+TCB.CR3] # eax = address of page directory for next task mov ebx,[esi+TCB.ESP0] # ebx = address for the top of the next task's kernel stack # mov [TSS.ESP0],ebx # Adjust the ESP0 field in the TSS (used by CPU for for CPL=3 -> CPL=0 privilege level changes) -# mov ecx,cr3 # ecx = previous task's virtual address space + mov ecx,cr3 # ecx = previous task's virtual address space -# FIXME: This branch gets a from the assembler, something about "relaxed branches". -# this branch would probably not be used anyway but should be checked on later anyway. -# cmp eax,ecx # Does the virtual address space need to being changed? + cmp eax,ecx # Does the virtual address space need to being changed? -# je .doneVAS # no, virtual address space is the same, so don't reload it and cause TLB flushes + je .doneVAS # no, virtual address space is the same, so don't reload it and cause TLB flushes mov cr3,eax # yes, load the next task's virtual address space -#.doneVAS: +.doneVAS: pop ebp pop edi diff --git a/meta/run.sh b/meta/run.sh index 01ec924..44fc40c 100755 --- a/meta/run.sh +++ b/meta/run.sh @@ -3,7 +3,8 @@ scriptdir="$(dirname "$0")" cd "$scriptdir" cd .. #qemu-system-i386 -netdev user,id=n0,hostfwd=tcp:127.0.0.1:6001-:6000 -device rtl8139,netdev=n0 -object filter-dump,id=id,netdev=n0,file=./logs/netout -d int -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=./logs/serial.log,signal=off -serial chardev:char0 -drive id=disk,file=./meta/ext2.img,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -m 512M -cdrom ./kernel/myos.iso -s -qemu-system-i386 -d int -netdev user,id=n0,hostfwd=tcp:127.0.0.1:6001-:6000 -device rtl8139,netdev=n0 -object filter-dump,id=id,netdev=n0,file=./logs/netout -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=./logs/serial.log,signal=off -serial chardev:char0 -drive id=disk,file=./meta/ext2.img,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -m 512M -cdrom ./kernel/myos.iso -s +#qemu-system-i386 -d int -netdev user,id=n0,hostfwd=tcp:127.0.0.1:6001-:6000 -device rtl8139,netdev=n0 -object filter-dump,id=id,netdev=n0,file=./logs/netout -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=./logs/serial.log,signal=off -serial chardev:char0 -drive id=disk,file=./meta/ext2.img,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -m 512M -cdrom ./kernel/myos.iso -s +qemu-system-i386 -d int -netdev user,id=n0,hostfwd=tcp:127.0.0.1:6001-:6000 -device rtl8139,netdev=n0 -object filter-dump,id=id,netdev=n0,file=./logs/netout -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=./logs/serial.log,signal=off -serial chardev:char0 -drive id=disk,file=./meta/ext2.img,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -m 1G -cdrom ./kernel/myos.iso -s # Sync the sysroot cd ./meta/ mkdir ./mount diff --git a/userland/irc/irc.c b/userland/irc/irc.c index b69e1dd..297c332 100644 --- a/userland/irc/irc.c +++ b/userland/irc/irc.c @@ -129,20 +129,26 @@ void msg_sv_println(struct sv s) { } void msg_sv_print(struct sv s) { + char buffer[4096]; + int buffer_pos = 0; + mvcursor(message_pos_x, message_pos_y); for (size_t i = 0; i < s.length; i++) { - mvcursor(message_pos_x, message_pos_y); - if ('\n' == s.s[i]) { - message_pos_x = 0; - message_pos_y++; - continue; - } - printf("%c", s.s[i]); + buffer[buffer_pos] = s.s[i]; + buffer_pos++; message_pos_x++; - if (message_pos_x > TERMINAL_WIDTH) { + if ('\n' == s.s[i] || message_pos_x > TERMINAL_WIDTH) { + buffer[buffer_pos] = '\0'; + printf("%s", buffer); + buffer_pos = 0; message_pos_x = 0; message_pos_y++; + mvcursor(message_pos_x, message_pos_y); } } + if (0 != buffer_pos) { + buffer[buffer_pos] = '\0'; + printf("%s", buffer); + } mvcursor(prompt_x, prompt_y); } @@ -154,8 +160,10 @@ void msg_sv_print(struct sv s) { #define RPL_LUSERCLIENT C_TO_SV("251") #define RPL_NOTOPIC C_TO_SV("331") #define RPL_TOPIC C_TO_SV("332") -#define ERR_NOMOTD C_TO_SV("422") +#define RPL_NAMREPLY C_TO_SV("353") +#define RPL_ENDOFNAMES C_TO_SV("366") +#define ERR_NOMOTD C_TO_SV("422") #define RPL_MOTDSTART C_TO_SV("375") #define RPL_MOTD C_TO_SV("372") #define RPL_ENDOFMOTD C_TO_SV("376") @@ -234,6 +242,29 @@ void handle_msg(struct irc_server *server, struct sv msg) { msg = sv_trim_left(msg, 1); irc_add_message(server, channel, nick, msg); } + HANDLE_CMD(RPL_NAMREPLY) { + struct sv intended_recipient = + sv_split_delim(command_parameters, &command_parameters, ' '); + struct sv channel_status = + sv_split_delim(command_parameters, &command_parameters, ' '); + (void)channel_status; + struct sv channel = + sv_split_delim(command_parameters, &command_parameters, ' '); + // Remove the ':' + command_parameters = sv_trim_left(command_parameters, 1); + if (sv_eq(intended_recipient, server_nick)) { + struct sb user_list_message; + sb_init(&user_list_message); + sb_append(&user_list_message, "Users on "); + sb_append_sv(&user_list_message, channel); + sb_append(&user_list_message, ": "); + sb_append_sv(&user_list_message, command_parameters); + irc_add_message(server, channel, C_TO_SV("*"), SB_TO_SV(user_list_message)); + sb_free(&user_list_message); + } + } + PASSTHROUGH_CHANNEL_CMD(RPL_ENDOFNAMES) + PASSTHROUGH_CHANNEL_CMD(RPL_NOTOPIC) PASSTHROUGH_CHANNEL_CMD(RPL_TOPIC) |