diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/boot.s | 4 | ||||
| -rw-r--r-- | kernel/fs/block.c | 10 | ||||
| -rw-r--r-- | kernel/fs/fs.c | 28 | ||||
| -rw-r--r-- | kernel/fs/mount.c | 35 | ||||
| -rw-r--r-- | kernel/hd.c | 207 | ||||
| -rw-r--r-- | kernel/serial.c | 21 | ||||
| -rw-r--r-- | kernel/sys.c | 58 |
7 files changed, 231 insertions, 132 deletions
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) { |
