rtc time
This commit is contained in:
parent
ea8f6b4ce0
commit
3690b91e16
2
Makefile
2
Makefile
@ -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
10
gdt.c
@ -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
16
io.c
@ -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
3
io.h
@ -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
2
isr.c
@ -55,8 +55,10 @@ void isr_call_handler(Stack *registers)
|
||||
void (*handler)(Stack *registers);
|
||||
handler = isr_routines[registers->id];
|
||||
if (handler)
|
||||
{
|
||||
handler(registers);
|
||||
}
|
||||
}
|
||||
|
||||
void isr_install(void)
|
||||
{
|
||||
|
7
kernel.c
7
kernel.c
@ -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
79
rtc.c
Normal 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
29
rtc.h
Normal 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
14
shell.c
@ -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: '");
|
||||
|
13
string.c
13
string.c
@ -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))
|
||||
|
1
string.h
1
string.h
@ -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
|
@ -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
34
tty.c
@ -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')))
|
||||
|
Loading…
Reference in New Issue
Block a user