summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hd.imgbin20971520 -> 20971520 bytes
-rw-r--r--include/kernel/fs.h46
-rw-r--r--include/kernel/hd.h7
-rw-r--r--include/kernel/sys.h33
-rw-r--r--include/sys/stat.h42
-rw-r--r--include/unistd.h18
-rw-r--r--kernel/boot.s4
-rw-r--r--kernel/fs/block.c10
-rw-r--r--kernel/fs/fs.c28
-rw-r--r--kernel/fs/mount.c35
-rw-r--r--kernel/hd.c207
-rw-r--r--kernel/serial.c21
-rw-r--r--kernel/sys.c58
-rw-r--r--usrbin/main.c17
14 files changed, 348 insertions, 178 deletions
diff --git a/hd.img b/hd.img
index bfdc925..3e85ed7 100644
--- a/hd.img
+++ b/hd.img
Binary files differ
diff --git a/include/kernel/fs.h b/include/kernel/fs.h
index 8f21110..a2b0086 100644
--- a/include/kernel/fs.h
+++ b/include/kernel/fs.h
@@ -4,10 +4,14 @@
#include <stdint.h>
#include <sys/types.h>
-#define BLOCK_SIZE 1024
+#define NRSUPER 8
#define NRFILE 128
#define NROPEN 32
+/* these shouldn't change */
+#define BLOCK_SIZE 1024
+#define SUPER_MAGIC 0x137F
+
struct file {
uint16_t f_mode;
uint16_t f_flags;
@@ -15,4 +19,44 @@ struct file {
off_t f_pos;
};
+struct super_block {
+ uint16_t s_ninodes;
+ uint16_t s_nzones;
+ uint16_t s_imap_blocks;
+ uint16_t s_zmap_blocks;
+ uint16_t s_firstdatazone;
+ uint16_t s_log_zone_size;
+ uint32_t s_max_size;
+ uint16_t s_magic;
+ /* loaded in memory only */
+ struct s_buff *s_imap[8];
+ struct s_buff *s_zmap[8];
+ uint16_t s_dev;
+ uint16_t s_dirt;
+ uint16_t s_start;
+ uint16_t s_super;
+ uint16_t s_imap_off;
+ uint16_t s_zmap_off;
+ uint16_t s_inode_off;
+} __attribute__((packed));
+
+struct m_inode {
+ uint16_t i_mode;
+ uint16_t i_uid;
+ uint32_t i_size;
+ uint32_t i_mtime;
+ uint8_t i_gid;
+ uint8_t i_nlinks;
+ uint16_t i_zone[9];
+} __attribute__((packed));
+
+extern struct super_block sblocks[NRSUPER];
+
+size_t block_read(void*, size_t , size_t);
+size_t block_write(void*, size_t , size_t);
+
+void mount_root(void);
+
+void fs_init(void);
+
#endif
diff --git a/include/kernel/hd.h b/include/kernel/hd.h
index 292b92e..2a2f3c6 100644
--- a/include/kernel/hd.h
+++ b/include/kernel/hd.h
@@ -2,8 +2,11 @@
#define _HD_H
#include <stdint.h>
+#include <sys/types.h>
-int hd_read(void*, uint32_t, uint8_t);
-int hd_write(void*, uint32_t, uint8_t);
+void hd_init(void);
+
+size_t hd_read_block(void*, size_t , size_t);
+size_t hd_write_block(void*, size_t , size_t);
#endif
diff --git a/include/kernel/sys.h b/include/kernel/sys.h
index 1b8be8e..95cfb79 100644
--- a/include/kernel/sys.h
+++ b/include/kernel/sys.h
@@ -1,31 +1,30 @@
typedef int (*syscall_t) (void);
-extern int sys_time(void);
-extern int sys_time(void);
-extern int sys_getpid(void);
-extern int sys_getpdir(void);
-extern int sys_signal(void);
extern int sys_alarm(void);
-extern int sys_pause(void);
extern int sys_ctty(void);
-extern int sys_read(void);
-extern int sys_write(void);
+extern int sys_getpdir(void);
+extern int sys_getpid(void);
extern int sys_kill(void);
extern int sys_panic(void);
+extern int sys_pause(void);
+extern int sys_read(void);
+extern int sys_signal(void);
+extern int sys_time(void);
+extern int sys_write(void);
extern int sys_dummy(void);
syscall_t call_table[256] = {
- [0] = &sys_time,
- [1] = &sys_getpid,
+ [0] = &sys_alarm,
+ [1] = &sys_ctty,
[2] = &sys_getpdir,
- [3] = &sys_signal,
- [4] = &sys_alarm,
- [5] = &sys_pause,
- [6] = &sys_ctty,
+ [3] = &sys_getpid,
+ [4] = &sys_kill,
+ [5] = &sys_panic,
+ [6] = &sys_pause,
[7] = &sys_read,
- [8] = &sys_write,
- [9] = &sys_kill,
- [10] = &sys_panic,
+ [8] = &sys_signal,
+ [9] = &sys_time,
+ [10] = &sys_write,
[11] = &sys_dummy,
[12] = &sys_dummy,
[13] = &sys_dummy,
diff --git a/include/sys/stat.h b/include/sys/stat.h
new file mode 100644
index 0000000..fab014c
--- /dev/null
+++ b/include/sys/stat.h
@@ -0,0 +1,42 @@
+#ifndef _SYS_STAT_H
+#define _SYS_STAT_H
+
+/* permission bits */
+
+#define S_IRWXU 0700
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+
+#define S_IRWXG 0070
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+
+#define S_IRWXO 0007
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+
+/* inode type bits */
+
+#define S_IFMT 0170000
+#define S_IFSOCK 0140000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFBLK 0060000
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFIFO 0010000
+
+/* inode type conditionals */
+
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+
+#endif
diff --git a/include/unistd.h b/include/unistd.h
index cc0f766..47e1621 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -10,17 +10,17 @@ typedef int32_t ssize_t;
typedef int16_t pid_t;
-#define __SYS_time 0
-#define __SYS_getpid 1
+#define __SYS_alarm 0
+#define __SYS_ctty 1
#define __SYS_getpdir 2
-#define __SYS_signal 3
-#define __SYS_alarm 4
-#define __SYS_pause 5
-#define __SYS_ctty 6
+#define __SYS_getpid 3
+#define __SYS_kill 4
+#define __SYS_panic 5
+#define __SYS_pause 6
#define __SYS_read 7
-#define __SYS_write 8
-#define __SYS_kill 9
-#define __SYS_panic 10
+#define __SYS_signal 8
+#define __SYS_time 9
+#define __SYS_write 10
#define _syscall0(type, name) \
type name(void) { \
diff --git a/kernel/boot.s b/kernel/boot.s
index ac7e0e3..d1f5606 100644
--- a/kernel/boot.s
+++ b/kernel/boot.s
@@ -4,7 +4,7 @@ global kboot
global register_isr
global register_trap
extern con_init
-extern hd_init
+extern fs_init
extern kmain
extern paging_init
extern printk
@@ -42,8 +42,8 @@ kboot:
call printk
add esp, 4
; initialize secondary subsystems
+ call fs_init
call tty_init
- call hd_init
; last minute setup, then transfer to kmain
call timer_init
call kmain
diff --git a/kernel/fs/block.c b/kernel/fs/block.c
new file mode 100644
index 0000000..b3f7386
--- /dev/null
+++ b/kernel/fs/block.c
@@ -0,0 +1,10 @@
+#include <kernel/hd.h>
+#include <sys/types.h>
+
+size_t block_read(void *buf, size_t block, size_t len) {
+ return hd_read_block(buf, block, len);
+}
+
+size_t block_write(void *buf, size_t block, size_t len) {
+ return hd_write_block(buf, block, len);
+}
diff --git a/kernel/fs/fs.c b/kernel/fs/fs.c
new file mode 100644
index 0000000..792668e
--- /dev/null
+++ b/kernel/fs/fs.c
@@ -0,0 +1,28 @@
+#include <kernel/con.h>
+#include <kernel/fs.h>
+#include <kernel/hd.h>
+#include <kernel/kernel.h>
+#include <kernel/sched.h>
+#include <kernel/tty.h>
+#include <string.h>
+#include <sys/types.h>
+
+/* master file table */
+static struct file ftable[NRFILE];
+
+ssize_t sys_read(void *buf, size_t len) {
+ return tty_read(ctask->ctty, buf, len);
+}
+
+ssize_t sys_write(void *buf, size_t len) {
+ return tty_write(ctask->ctty, buf, len);
+}
+
+void fs_init(void) {
+ memset(&sblocks, 0, sizeof(sblocks));
+ memset(&ftable, 0, sizeof(ftable));
+
+ hd_init();
+
+ mount_root();
+}
diff --git a/kernel/fs/mount.c b/kernel/fs/mount.c
new file mode 100644
index 0000000..47911fb
--- /dev/null
+++ b/kernel/fs/mount.c
@@ -0,0 +1,35 @@
+#include <kernel/con.h>
+#include <kernel/fs.h>
+#include <string.h>
+
+/* super blocks table */
+struct super_block sblocks[NRSUPER];
+
+void mount_root(void) {
+ size_t ret;
+ char buf[BLOCK_SIZE];
+ struct super_block *s = (void*) buf;
+
+ ret = block_read(buf, 1, 1);
+ if(ret < 1) {
+ printk("[fs] Failed to read super block\n");
+ return;
+ }
+
+ if(s->s_magic != SUPER_MAGIC) {
+ printk("[fs] Invalid magic number in super block!\n");
+ return;
+ }
+
+ printk("[fs] Found valid super-block for /\n");
+ printk(" 0x%01x inodes\n", s->s_ninodes);
+ printk(" 0x%01x zones\n", s->s_nzones);
+ printk(" 0x%01x inode block bitmaps\n", s->s_imap_blocks);
+ printk(" 0x%01x zone block bitmaps\n", s->s_zmap_blocks);
+ printk(" First data zone: 0x%01x\n", s->s_firstdatazone);
+ printk(" Log zone size: 0x%01x\n", s->s_log_zone_size);
+ printk(" Max file size: 0x%01x\n", s->s_max_size);
+
+ /* copy the super block into the table */
+ memcpy(sblocks, buf, ((unsigned) &s->s_imap - (unsigned) s));
+}
diff --git a/kernel/hd.c b/kernel/hd.c
index 65ebfd7..eab82dc 100644
--- a/kernel/hd.c
+++ b/kernel/hd.c
@@ -1,7 +1,12 @@
#include <asm/io.h>
#include <kernel/con.h>
+#include <kernel/fs.h>
#include <kernel/kernel.h>
#include <stdint.h>
+#include <sys/types.h>
+
+#define SECTS(n) ((n) * (BLOCK_SIZE / 512))
+#define BLOCKS(n) ((n) / (BLOCK_SIZE / 512))
#define ST_ERR 1
#define ST_DRQ 8
@@ -10,53 +15,23 @@
#define ST_RDY 64
#define ST_BSY 128
-/* sector buffer */
+/* status buffer */
static char sbuf[512];
-void hd_init(void) {
- int i;
- uint8_t s;
- uint16_t *buf = (uint16_t*) sbuf;
-
- /* select the master drive */
- outb(0x1F6, 0xA0);
- /* send the IDENTIFY command */
- outb(0x1F7, 0xEC);
+static uint32_t nblocks;
- while(1) {
- s = inb(0x1F7);
- if(!s) {
- printk("[hd] Master drive not detected on primary bus!\n");
- return;
- }
- if(s & ST_ERR) {
- if(!inb(0x1F4) && !inb(0x1F5))
- continue;
- printk("[hd] IDENTIFY command error!\n");
- return;
- }
- if(s & ST_DRQ && !(s & ST_ERR))
- break;
- }
-
- printk("[hd] Master drive detected on primary bus! (status: 0x%02x)\n", s);
-
- for(i = 0; i < 256; i++)
- buf[i] = inw(0x1F0);
-}
-
-int hd_read(void *buf, uint32_t lba, uint8_t c) {
+static int read_sect(void *buf, uint32_t lba) {
int n;
uint8_t s;
uint16_t *p = buf;
- if(!c)
- return 0;
+ if(lba > nblocks - 1)
+ return -1;
/* select the master disk on the primary bus */
outb(0x1F6, 0xE0 | ((lba >> 24) & 0xF));
/* set the number of sectors to be read */
- outb(0x1F2, c);
+ outb(0x1F2, 1);
/* set the LBA address for the read operation */
outb(0x1F3, lba);
outb(0x1F4, lba >> 8);
@@ -64,42 +39,40 @@ int hd_read(void *buf, uint32_t lba, uint8_t c) {
/* send the READ command */
outb(0x1F7, 0x20);
- while(c--) {
- /* wait for the drive */
- while(1) {
- /* poll the drive's status */
- s = inb(0x1F7);
- if(s & ST_DF) {
- printk("[hd] Drive failure!\n");
- panic();
- }
- if(s & ST_ERR)
- return -1;
- if(!(s & ST_BSY) && s & ST_DRQ)
- break;
+ /* wait for the drive */
+ while(1) {
+ /* poll the drive's status */
+ s = inb(0x1F7);
+ if(s & ST_DF) {
+ printk("[hd] Drive failure!\n");
+ panic();
}
-
- /* buffer is full, copy it's data */
- n = 256;
- while(n--)
- *(p++) = inw(0x1F0);
+ if(s & ST_ERR)
+ return -1;
+ if(!(s & ST_BSY) && s & ST_DRQ)
+ break;
}
+ /* buffer is full, copy it's data */
+ n = 256;
+ while(n--)
+ *(p++) = inw(0x1F0);
+
return 0;
}
-int hd_write(void *buf, uint32_t lba, uint8_t c) {
+static int write_sect(void *buf, uint32_t lba) {
int n;
uint8_t s;
uint16_t *p = buf;
- if(!c)
- return 0;
+ if(lba > nblocks - 1)
+ return -1;
/* select the master disk on the primary bus */
outb(0x1F6, 0xE0 | ((lba >> 24) & 0xF));
/* set the number of sectors to be written */
- outb(0x1F2, c);
+ outb(0x1F2, 1);
/* set the LBA address for the write operation */
outb(0x1F3, lba);
outb(0x1F4, lba >> 8);
@@ -107,26 +80,108 @@ int hd_write(void *buf, uint32_t lba, uint8_t c) {
/* send the WRITE command */
outb(0x1F7, 0x30);
- while(c--) {
- /* wait for the drive */
- while(1) {
- /* poll the drive's status */
- s = inb(0x1F7);
- if(s & ST_DF) {
- printk("[hd] Drive failure!\n");
- panic();
- }
- if(s & ST_ERR)
- return -1;
- if(!(s & ST_BSY) && s & ST_DRQ)
- break;
+ /* wait for the drive */
+ while(1) {
+ /* poll the drive's status */
+ s = inb(0x1F7);
+ if(s & ST_DF) {
+ printk("[hd] Drive failure!\n");
+ panic();
}
-
- /* refill the drive's buffer */
- n = 256;
- while(n--)
- outw(0x1F0, *(p++));
+ if(s & ST_ERR)
+ return -1;
+ if(!(s & ST_BSY) && s & ST_DRQ)
+ break;
}
+ /* refill the drive's buffer */
+ n = 256;
+ while(n--)
+ outw(0x1F0, *(p++));
+
return 0;
}
+
+size_t hd_read_block(void *buf, size_t block, size_t len) {
+ int ret;
+ size_t i;
+ uint32_t s = SECTS(block);
+ uint32_t e = SECTS(block + len);
+
+ if(s > nblocks - 1)
+ s = nblocks - 1;
+ if(e > nblocks - 1)
+ e = nblocks - 1;
+
+ for(i = 0; i < (e - s); i++) {
+ ret = read_sect(buf, i + s);
+
+ if(ret < 0)
+ return BLOCKS(i);
+
+ buf = ((char*) buf + 512);
+ }
+
+ return len;
+}
+
+size_t hd_write_block(void *buf, size_t block, size_t len) {
+ int ret;
+ size_t i;
+ uint32_t s = SECTS(block);
+ uint32_t e = SECTS(block + len);
+
+ if(s > nblocks - 1)
+ s = nblocks - 1;
+ if(e > nblocks - 1)
+ e = nblocks - 1;
+
+ for(i = 0; i < (e - s); i++) {
+ ret = write_sect(buf, i + s);
+
+ if(ret < 0)
+ return BLOCKS(i);
+
+ buf = ((char*) buf + 512);
+ }
+
+ return len;
+}
+
+void hd_init(void) {
+ int i;
+ uint8_t s;
+ uint16_t *buf = (uint16_t*) sbuf;
+
+ /* select the master drive */
+ outb(0x1F6, 0xA0);
+ /* send the IDENTIFY command */
+ outb(0x1F7, 0xEC);
+
+ while(1) {
+ s = inb(0x1F7);
+ if(!s) {
+ printk("[hd] Master drive not detected on primary bus!\n");
+ return;
+ }
+ if(s & ST_ERR) {
+ if(!inb(0x1F4) && !inb(0x1F5))
+ continue;
+ printk("[hd] IDENTIFY command error!\n");
+ return;
+ }
+ if(s & ST_DRQ && !(s & ST_ERR))
+ break;
+ }
+
+ for(i = 0; i < 256; i++)
+ buf[i] = inw(0x1F0);
+
+ nblocks = *((uint32_t*) &buf[60]);
+ if(!nblocks) {
+ printk("[hd] Drive does not support LBA28 addressing!\n");
+ return;
+ }
+
+ printk("[hd] Primary bus master drive initialized! (status: 0x%02x, nblocks: 0x%01x)\n", s, nblocks);
+}
diff --git a/kernel/serial.c b/kernel/serial.c
index e712e53..6821bdc 100644
--- a/kernel/serial.c
+++ b/kernel/serial.c
@@ -91,27 +91,6 @@ void rsint_rx(void) {
wake_up(&q->waiting);
}
-/*
- * void rsint_tx(void) {
- * int copied = 0;
- * struct tty_queue *q = &tty_rs.wqueue;
- *
- * while(q->pread != q->pwrite) {
- * [> we're done if the TX FIFO is full <]
- * if((inb(RSLINES) & 0x20) == 0)
- * break;
- *
- * outb(RSDATA, q->buf[q->pread]);
- * q->pread = (q->pread + 1) % TTY_BUF_SIZE;
- *
- * copied = 1;
- * }
- *
- * if(copied)
- * wake_up(&q->waiting);
- * }
- */
-
void rsint_tx(void) {
int i;
int copied = 0;
diff --git a/kernel/sys.c b/kernel/sys.c
index b750072..f21e35a 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -11,8 +11,19 @@
#include <time.h>
#include <unistd.h>
-time_t sys_time(void) {
- return ticks / 100;
+int sys_alarm(unsigned int seconds) {
+ if(!seconds) {
+ ctask->alarm = 0;
+ return 0;
+ }
+
+ ctask->alarm = ticks + (seconds * 100);
+}
+
+int sys_ctty(int ctty) {
+ ctask->ctty = ctty;
+
+ return 0;
}
pid_t sys_getpid(void) {
@@ -27,26 +38,8 @@ void *sys_getpdir(void) {
return (void*) pdir;
}
-void *sys_signal(int sig, void (*func)(int)) {
- if(sig < 0 || sig >= NRSIG)
- return NULL;
-
- /* SIGKILL and SIGSTOP cannot be caught */
- if(sig == SIGKILL || sig == SIGSTOP)
- return NULL;
-
- ctask->sig_handlers[sig] = func;
-
- return func;
-}
-
-int sys_alarm(unsigned int seconds) {
- if(!seconds) {
- ctask->alarm = 0;
- return 0;
- }
-
- ctask->alarm = ticks + (seconds * 100);
+void sys_panic(void) {
+ panic();
}
int sys_pause(void) {
@@ -55,22 +48,21 @@ int sys_pause(void) {
return -1;
}
-int sys_ctty(int ctty) {
- ctask->ctty = ctty;
+void *sys_signal(int sig, void (*func)(int)) {
+ if(sig < 0 || sig >= NRSIG)
+ return NULL;
- return 0;
-}
+ /* SIGKILL and SIGSTOP cannot be caught */
+ if(sig == SIGKILL || sig == SIGSTOP)
+ return NULL;
-ssize_t sys_read(void *buf, size_t len) {
- return tty_read(ctask->ctty, buf, len);
-}
+ ctask->sig_handlers[sig] = func;
-ssize_t sys_write(void *buf, size_t len) {
- return tty_write(ctask->ctty, buf, len);
+ return func;
}
-void sys_panic(void) {
- panic();
+time_t sys_time(void) {
+ return ticks / 100;
}
int sys_dummy(void) {
diff --git a/usrbin/main.c b/usrbin/main.c
index 70c0ab3..3b6dd97 100644
--- a/usrbin/main.c
+++ b/usrbin/main.c
@@ -50,23 +50,6 @@ void pid2(void) {
}
void main(void) {
- int i;
- char c = 'a';
- char buf[2048];
-
-/*
- * for(i = 0; i < 2048; i++) {
- * buf[i] = c;
- *
- * c++;
- * if(c > 'z')
- * c = 'a';
- * }
- * ctty(1);
- * write(buf, 2048);
- * while(1);
- */
-
if(getpid() == 1) {
ctty(1);
pid1();