This commit is contained in:
assada 2024-05-25 23:17:10 +03:00
parent ea8f6b4ce0
commit 3690b91e16
Signed by: assada
GPG Key ID: D4860A938E541F06
13 changed files with 197 additions and 17 deletions

View File

@ -9,7 +9,7 @@ GRUB_MKRESCUE = grub-mkrescue
KERNEL = deados.bin
ISO = deados.iso
SOURCES_C = kernel.c tty.c idt.c timer.c io.c vga.c gdt.c sys.c irq.c isr.c keyboard.c shell.c string.c user_space.c syscall.c
SOURCES_C = kernel.c tty.c idt.c timer.c io.c vga.c gdt.c sys.c irq.c isr.c keyboard.c shell.c string.c user_space.c syscall.c rtc.c
SOURCES_ASM = boot.s idt_load.s gdt_flush.s tss_flush.s irq_flush.s isr_flush.s
OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o)

10
gdt.c
View File

@ -35,7 +35,7 @@ static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp)
memset(&tss, 0, sizeof(Tss_entry));
tss.ss0 = kernel_ss;
tss.esp0 = kernel_esp;
tss.esp0 = kernel_esp + 0x1000; // SHIT
tss.cs = 0x1B;
tss.ss = 0x23;
@ -48,10 +48,10 @@ static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp)
void gdt_install()
{
gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // Kernel code segment
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // User code segment
gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // User data segment
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // 0x08 Kernel code segment
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // 0x10 Kernel Data segment
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // 0x18 User code segment
gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // 0x20 User data segment
tss_install(5, 0x10, stack_top);

16
io.c
View File

@ -12,9 +12,23 @@ uint8_t inb(uint16_t port)
return ret;
}
void wait(void)
void io_wait(void)
{
asm volatile("jmp 1f\n\t"
"1:jmp 2f\n\t"
"2:");
}
void outb_wait(uint16_t port, uint8_t val)
{
outb(port, val);
io_wait();
}
uint8_t inb_wait(uint16_t port)
{
uint8_t ret;
ret = inb(port);
io_wait();
return ret;
}

3
io.h
View File

@ -7,4 +7,7 @@ void outb(uint16_t port, uint8_t val);
uint8_t inb(uint16_t port);
void io_wait(void);
void outb_wait(uint16_t port, uint8_t val);
uint8_t inb_wait(uint16_t port);
#endif

2
isr.c
View File

@ -55,7 +55,9 @@ void isr_call_handler(Stack *registers)
void (*handler)(Stack *registers);
handler = isr_routines[registers->id];
if (handler)
{
handler(registers);
}
}
void isr_install(void)

View File

@ -12,9 +12,11 @@
#include "shell.h"
#include "user_space.h"
#include "syscall.h"
#include "rtc.h"
void kernel_main(void)
{
terminal_initialize();
gdt_install();
idt_install();
@ -24,17 +26,18 @@ void kernel_main(void)
timer_install();
keyboard_install();
rtc_init();
syscall_init();
enter_user_space();
}
void main(void)
{
terminal_initialize();
for (int i = 1; i < 4; i++)
{
terminal_printf("&cTest &7%d\n", i);
delay(500);
delay(200);
}
terminal_clear();

79
rtc.c Normal file
View File

@ -0,0 +1,79 @@
#include <stdint.h>
#include "io.h"
#include "interrupts.h"
#include "rtc.h"
uint8_t read_cmos(uint16_t reg)
{
outb_wait(CMOS_ADDRESS, reg);
return inb_wait(CMOS_DATA);
}
uint8_t get_update_in_progress_flag()
{
outb_wait(CMOS_ADDRESS, 0x0A);
return inb_wait(CMOS_DATA) & 0x80;
}
void rtc_handler()
{
outb_wait(CMOS_ADDRESS, 0x0C);
inb_wait(CMOS_DATA);
}
uint8_t bcd_to_bin(uint8_t val)
{
return ((val / 16) * 10) + (val & 0x0F);
}
struct Rtc_time get_rtc_time()
{
struct Rtc_time time;
while (get_update_in_progress_flag())
;
time.sec = read_cmos(REG_SECONDS);
time.min = read_cmos(REG_MINUTES);
time.hour = read_cmos(REG_HOURS);
time.mday = read_cmos(REG_DAY);
time.mon = read_cmos(REG_MONTH);
time.year = read_cmos(REG_YEAR);
uint8_t registerB = read_cmos(0x0B);
if (!(registerB & 0x04))
{
time.sec = bcd_to_bin(time.sec);
time.min = bcd_to_bin(time.min);
time.hour = bcd_to_bin(time.hour);
time.mday = bcd_to_bin(time.mday);
time.mon = bcd_to_bin(time.mon);
time.year = bcd_to_bin(time.year);
}
if (time.year < 70)
{
time.year += 100;
}
else if (time.year >= 100)
{
time.year -= 100;
}
time.year += 1900;
return time;
}
void rtc_init()
{
outb_wait(CMOS_ADDRESS, 0x8A);
uint8_t prev = inb_wait(CMOS_DATA);
outb_wait(CMOS_ADDRESS, 0x8A);
outb_wait(CMOS_DATA, (prev & 0xF0) | 0x0F);
irq_install_handler(8, rtc_handler);
}

29
rtc.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef RTC_H
#define RTC_H
#include <stdint.h>
#define CMOS_ADDRESS 0x70
#define CMOS_DATA 0x71
#define REG_SECONDS 0x00
#define REG_MINUTES 0x02
#define REG_HOURS 0x04
#define REG_DAY 0x07
#define REG_MONTH 0x08
#define REG_YEAR 0x09
struct Rtc_time
{
uint8_t sec;
uint8_t min;
uint8_t hour;
uint8_t mday;
uint8_t mon;
uint16_t year;
};
void rtc_init();
struct Rtc_time get_rtc_time();
#endif

14
shell.c
View File

@ -3,6 +3,7 @@
#include "shell.h"
#include "tty.h"
#include "string.h"
#include "rtc.h"
void shell_init(void)
{
@ -53,6 +54,7 @@ void shell_help_command(void)
terminal_printf("exit - Exit the shell.\n");
terminal_printf("echo - Print out the message. &eWITH colors!&7\n");
terminal_printf("clear - Clear the terminal.\n");
terminal_printf("time - Print out the current time. (UTC)\n");
}
void shell_exit_command(void)
@ -63,6 +65,14 @@ void shell_exit_command(void)
;
}
void shell_time_command(void)
{
struct Rtc_time current_time = get_rtc_time();
terminal_printf("Current time: %02d:%02d:%02d %02d.%02d.%d\n",
current_time.hour, current_time.min, current_time.sec,
current_time.mday, current_time.mon, current_time.year);
}
void shell_echo_command(char *input)
{
char *message = input;
@ -102,6 +112,10 @@ void shell_parse_input(char *input)
{
terminal_clear();
}
else if (strcmp(command, "time") == 0)
{
shell_time_command();
}
else
{
terminal_printf("Unknown command: '");

View File

@ -21,6 +21,19 @@ void *memset(void *ptr, int value, size_t size)
return ptr;
}
void memcpy(void *vd, const void *vs, unsigned length)
{
char *d = vd;
const char *s = vs;
while (length)
{
*d = *s;
d++;
s++;
length--;
}
}
int strcmp(const char *str1, const char *str2)
{
while (*str1 && (*str1 == *str2))

View File

@ -10,5 +10,6 @@ size_t strlen(const char *str);
void itoa(int value, char *str, int base);
void *memset(void *ptr, int value, size_t size);
void memcpy(void *vd, const void *vs, unsigned length);
#endif

View File

@ -6,11 +6,13 @@
#include "syscall.h"
#include "tty.h"
#include "timer.h"
#include "rtc.h"
#define NB_SYSCALL 2
#define NB_SYSCALL 3
void *syscalls[NB_SYSCALL] = {
keyboard_getchar,
get_rtc_time,
sys_halt};

34
tty.c
View File

@ -129,6 +129,21 @@ void terminal_print(const char *data)
terminal_write(data, strlen(data));
}
static void print_number(int value, int base, int padding)
{
char buffer[32];
itoa(value, buffer, base);
int len = strlen(buffer);
while (padding > len)
{
terminal_putchar('0');
padding--;
}
terminal_print(buffer);
}
void terminal_printf(const char *format, ...)
{
va_list args;
@ -137,24 +152,29 @@ void terminal_printf(const char *format, ...)
const char *p = format;
while (*p)
{
if (*p == '%' && (*(p + 1) == 's' || *(p + 1) == 'd' || *(p + 1) == 'x'))
if (*p == '%' && (*(p + 1) == 's' || *(p + 1) == 'd' || *(p + 1) == 'x' || *(p + 1) == '0'))
{
p++;
int padding = 0;
if (*p == '0')
{
p++;
padding = *p - '0';
p++;
}
if (*p == 's')
{
terminal_print(va_arg(args, const char *));
}
else if (*p == 'd')
{
char buffer[12];
itoa(va_arg(args, int), buffer, 10);
terminal_print(buffer);
print_number(va_arg(args, int), 10, padding);
}
else if (*p == 'x')
{
char buffer[12];
itoa(va_arg(args, unsigned int), buffer, 16);
terminal_print(buffer);
print_number(va_arg(args, unsigned int), 16, padding);
}
}
else if (*p == '&' && ((*(p + 1) >= '0' && *(p + 1) <= '9') || (*(p + 1) >= 'a' && *(p + 1) <= 'f')))