summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/kernel/con.h2
-rw-r--r--include/kernel/sys.h3
-rw-r--r--include/stdio.h4
-rw-r--r--include/unistd.h1
-rw-r--r--kernel/boot.s4
-rw-r--r--kernel/con.c6
-rw-r--r--kernel/kmain.c3
-rw-r--r--kernel/serial.c52
-rw-r--r--lib/stdio.c14
9 files changed, 80 insertions, 9 deletions
diff --git a/include/kernel/con.h b/include/kernel/con.h
index 178a0d3..9dd9dbe 100644
--- a/include/kernel/con.h
+++ b/include/kernel/con.h
@@ -1,7 +1,7 @@
/*
* con.h
*
- * Basic VGA text console. Implements printk() and puts().
+ * Basic VGA text console. Implements printk().
*/
#ifndef _CON_H
diff --git a/include/kernel/sys.h b/include/kernel/sys.h
index b2c1b3b..2ec4490 100644
--- a/include/kernel/sys.h
+++ b/include/kernel/sys.h
@@ -5,6 +5,7 @@ extern int sys_time(void);
extern int sys_getpid(void);
extern int sys_getpdir(void);
extern int sys_signal(void);
+extern int sys_rsputs(void);
extern int sys_dummy(void);
syscall_t call_table[256] = {
@@ -13,7 +14,7 @@ syscall_t call_table[256] = {
[2] = &sys_getpid,
[3] = &sys_getpdir,
[4] = &sys_signal,
- [5] = &sys_dummy,
+ [5] = &sys_rsputs,
[6] = &sys_dummy,
[7] = &sys_dummy,
[8] = &sys_dummy,
diff --git a/include/stdio.h b/include/stdio.h
index d37699a..94cf227 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -3,7 +3,11 @@
#include <stdarg.h>
+int puts(char*);
+int rsputs(char*);
+
int printf(char*, ...);
+int rsprintf(char*, ...);
int vsprintf(char*, char*, va_list);
diff --git a/include/unistd.h b/include/unistd.h
index 3b144f6..a784e22 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -10,6 +10,7 @@ typedef uint16_t pid_t;
#define __SYS_getpid 2
#define __SYS_getpdir 3
#define __SYS_signal 4
+#define __SYS_rsputs 5
#define _syscall0(type, name) \
type name(void) { \
diff --git a/kernel/boot.s b/kernel/boot.s
index 21b248c..db846c9 100644
--- a/kernel/boot.s
+++ b/kernel/boot.s
@@ -7,6 +7,7 @@ extern hd_init
extern kmain
extern paging_init
extern printk
+extern serial_init
extern syscall_init
extern timer_init
extern traps_init
@@ -39,7 +40,8 @@ kboot:
push .msg
call printk
add esp, 4
- ; initialize the disk interface
+ ; initialize secondary subsystems
+ call serial_init
call hd_init
; last minute setup, then transfer to kmain
call timer_init
diff --git a/kernel/con.c b/kernel/con.c
index c8be80b..2000fbc 100644
--- a/kernel/con.c
+++ b/kernel/con.c
@@ -1,7 +1,7 @@
/*
* con.c
*
- * Basic VGA text console. Implements printk() and puts().
+ * Basic VGA text console. Implements printk().
*/
#include <asm/io.h>
@@ -64,7 +64,7 @@ void con_init(void) {
}
/* write a zero-terminated string to console */
-static int puts(char *s) {
+static int con_puts(char *s) {
uint8_t *p = &vram[pos];
while(*s) {
@@ -100,6 +100,6 @@ int printk(char *fmt, ...) {
ret = vsprintf(buf, fmt, ap);
va_end(ap);
- puts(buf);
+ con_puts(buf);
return ret;
}
diff --git a/kernel/kmain.c b/kernel/kmain.c
index 7c8a72d..e9430ba 100644
--- a/kernel/kmain.c
+++ b/kernel/kmain.c
@@ -4,9 +4,6 @@
#include <stdint.h>
void kmain(void) {
- int i;
- int ret;
-
printk("Kernel booted!\n\n");
sched_init();
diff --git a/kernel/serial.c b/kernel/serial.c
new file mode 100644
index 0000000..7f23298
--- /dev/null
+++ b/kernel/serial.c
@@ -0,0 +1,52 @@
+#include <asm/io.h>
+#include <kernel/con.h>
+
+/* 115200 baud */
+#define DIVISOR 1
+
+#define RSBASE 0x3F8
+
+#define RSDATA RSBASE
+#define RSINTEN (RSBASE + 1)
+#define RSFIFOC (RSBASE + 2)
+#define RSLINEC (RSBASE + 3)
+#define RSMODEMC (RSBASE + 4)
+#define RSLINES (RSBASE + 5)
+#define RSMODEMS (RSBASE + 6)
+#define RSSCRATCH (RSBASE + 7)
+
+static int rsputs(char *s) {
+ while(*s) {
+ while((inb(RSLINES) & 0x20) == 0);
+ outb(RSDATA, *s++);
+ }
+
+ return 0;
+}
+
+void serial_init(void) {
+ outb(RSSCRATCH, 0x00);
+ outb(RSSCRATCH, 0xAA);
+ if(inb(RSSCRATCH) != 0xAA) {
+ printk("[rs] COM0 not detected!\n");
+ return;
+ }
+
+ /* enable access to the divisor */
+ outb(RSLINEC, inb(RSLINEC) | 0x80);
+ /* write the divisor */
+ outb(RSBASE, DIVISOR);
+ outb(RSBASE + 1, DIVISOR >> 8);
+ /* restore access to the divisor */
+ outb(RSLINEC, inb(RSLINEC) & 0x7F);
+ /* configure port parameters */
+ outb(RSLINEC, 0x03);
+ outb(RSINTEN, 0x00);
+
+ rsputs("[kernel] Serial monitor initialized!\n\r");
+ printk("[rs] Serial port COM0 initialized!\n");
+}
+
+int sys_rsputs(char *s) {
+ return rsputs(s);
+}
diff --git a/lib/stdio.c b/lib/stdio.c
index 912fd17..a718ee4 100644
--- a/lib/stdio.c
+++ b/lib/stdio.c
@@ -3,6 +3,7 @@
#include <unistd.h>
_syscall1(int, puts, char*, s);
+_syscall1(int, rsputs, char*, s);
int printf(char *fmt, ...) {
int ret;
@@ -16,3 +17,16 @@ int printf(char *fmt, ...) {
puts(buf);
return ret;
}
+
+int rsprintf(char *fmt, ...) {
+ int ret;
+ char buf[1024];
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vsprintf(buf, fmt, ap);
+ va_end(ap);
+
+ rsputs(buf);
+ return ret;
+}