added some useless shell commands
This commit is contained in:
@@ -79,13 +79,15 @@ void vga_putchar(char c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf) {
|
uint32_t vga_seek(vfs_node_t* node, uint32_t offset, int whence) {
|
||||||
terminal_row = offset / VGA_WIDTH;
|
terminal_row = offset / VGA_WIDTH;
|
||||||
terminal_column = offset % VGA_WIDTH;
|
terminal_column = offset % VGA_WIDTH;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf) {
|
||||||
for (uint32_t i = 0; i < size; i++) {
|
for (uint32_t i = 0; i < size; i++) {
|
||||||
vga_putchar((char)buf[i]);
|
vga_putchar((char)buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,6 @@ void vga_init();
|
|||||||
void vga_putchar(char c);
|
void vga_putchar(char c);
|
||||||
|
|
||||||
uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf);
|
uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf);
|
||||||
|
uint32_t vga_seek(vfs_node_t* node, uint32_t offset, int whence);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -79,6 +79,8 @@ void kbd_wait() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char kbd_read() {
|
uint32_t kbd_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
|
||||||
return kbd_pop();
|
if (!kbd_ready()) return -1;
|
||||||
|
buffer[0] = kbd_pop();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
char kbd_read();
|
#include <stdint.h>
|
||||||
|
#include <vfs.h>
|
||||||
|
|
||||||
|
uint32_t kbd_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
|
||||||
void kbd_push(char c);
|
void kbd_push(char c);
|
||||||
int kbd_ready();
|
int kbd_ready();
|
||||||
void kbd_wait();
|
void kbd_wait();
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
|
#include "kbd.h"
|
||||||
|
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
@@ -135,6 +136,10 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
|
|
||||||
vfs_node_t* vga_dev = devfs->create(devfs, "tvga");
|
vfs_node_t* vga_dev = devfs->create(devfs, "tvga");
|
||||||
vga_dev->write = vga_write;
|
vga_dev->write = vga_write;
|
||||||
|
vga_dev->seek = vga_seek;
|
||||||
|
|
||||||
|
vfs_node_t* kbd_dev = devfs->create(devfs, "kbd");
|
||||||
|
kbd_dev->read = kbd_read;
|
||||||
|
|
||||||
vfs_node_t* dev = vfs_find("/dev");
|
vfs_node_t* dev = vfs_find("/dev");
|
||||||
if (dev) {
|
if (dev) {
|
||||||
|
|||||||
@@ -196,6 +196,15 @@ static int32_t sys_dup2(int src, int dst) {
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t sys_lseek(int fd, size_t offset, int whence) {
|
||||||
|
if (fd < 0) return 0;
|
||||||
|
process_t* task = current_task();
|
||||||
|
file_t* file = task->fd_table[fd];
|
||||||
|
if (!file) return 0;
|
||||||
|
file->node->seek(file->node, offset, whence);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void syscall(registers_t* regs) {
|
void syscall(registers_t* regs) {
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
switch(regs->eax) {
|
switch(regs->eax) {
|
||||||
@@ -209,6 +218,7 @@ void syscall(registers_t* regs) {
|
|||||||
case 21: ret = sys_fork(regs); break;
|
case 21: ret = sys_fork(regs); break;
|
||||||
case 22: ret = sys_exec(regs, (const char*)regs->ebx); break;
|
case 22: ret = sys_exec(regs, (const char*)regs->ebx); break;
|
||||||
case 23: ret = sys_dup2(regs->ebx, regs->ecx); break;
|
case 23: ret = sys_dup2(regs->ebx, regs->ecx); break;
|
||||||
|
case 24: ret = sys_lseek(regs->ebx, regs->ecx, regs->edx); break;
|
||||||
default: ret = -1;
|
default: ret = -1;
|
||||||
}
|
}
|
||||||
regs->eax = ret;
|
regs->eax = ret;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct vfs_node;
|
|||||||
|
|
||||||
typedef uint32_t (*read_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
|
typedef uint32_t (*read_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
|
||||||
typedef uint32_t (*write_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
|
typedef uint32_t (*write_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
|
||||||
|
typedef uint32_t (*seek_type_t)(struct vfs_node* node, uint32_t offset, int whence);
|
||||||
typedef struct vfs_node* (*finddir_type_t)(struct vfs_node* node, const char* name);
|
typedef struct vfs_node* (*finddir_type_t)(struct vfs_node* node, const char* name);
|
||||||
typedef struct vfs_node* (*mkdir_type_t)(struct vfs_node* node, const char* name);
|
typedef struct vfs_node* (*mkdir_type_t)(struct vfs_node* node, const char* name);
|
||||||
typedef struct vfs_node* (*create_type_t)(struct vfs_node* node, const char* name);
|
typedef struct vfs_node* (*create_type_t)(struct vfs_node* node, const char* name);
|
||||||
@@ -31,6 +32,7 @@ typedef struct vfs_node {
|
|||||||
finddir_type_t find;
|
finddir_type_t find;
|
||||||
mkdir_type_t mkdir;
|
mkdir_type_t mkdir;
|
||||||
create_type_t create;
|
create_type_t create;
|
||||||
|
seek_type_t seek;
|
||||||
|
|
||||||
struct vfs_node* mnt;
|
struct vfs_node* mnt;
|
||||||
void* data;
|
void* data;
|
||||||
|
|||||||
Binary file not shown.
@@ -1,13 +1,46 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
const char* shell_prompt = "rocksh> ";
|
const char* shell_prompt = "rocksh> ";
|
||||||
|
|
||||||
|
char buf[256];
|
||||||
|
size_t buf_offset = 0;
|
||||||
|
|
||||||
|
void parse_cmd() {
|
||||||
|
if (strcmp(buf, "exit") == 0) {
|
||||||
|
printf("bye!\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(buf, "motd") == 0) {
|
||||||
|
printf("rockos is the best!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
memset(buf, 0, 256);
|
||||||
|
buf_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
printf(shell_prompt);
|
printf(shell_prompt);
|
||||||
|
while (1) {
|
||||||
|
char c;
|
||||||
|
int rd = read(0, &c, 1);
|
||||||
|
if (rd > 0) {
|
||||||
|
if (c == '\n') {
|
||||||
|
parse_cmd();
|
||||||
|
reset();
|
||||||
|
printf(shell_prompt);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
buf[buf_offset++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define VGA_TEXT_W 80
|
||||||
|
#define VGA_TEXT_H 25
|
||||||
|
|
||||||
void term();
|
void term();
|
||||||
|
|
||||||
int ptys;
|
int ptys;
|
||||||
@@ -30,15 +33,37 @@ int main(int argc, char *argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear(int fd) {
|
||||||
|
lseek(fd, 0, 0);
|
||||||
|
size_t bytes = VGA_TEXT_W * VGA_TEXT_H;
|
||||||
|
char c = ' ';
|
||||||
|
for (size_t i = 0; i < bytes; i++) {
|
||||||
|
write(fd, &c, 1);
|
||||||
|
}
|
||||||
|
lseek(fd, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void term() {
|
void term() {
|
||||||
int vga_fd = open("/dev/tvga");
|
int vga_fd = open("/dev/tvga");
|
||||||
if (vga_fd == -1) return;
|
if (vga_fd == -1) return;
|
||||||
|
|
||||||
while (1) {
|
int kbd_fd = open("/dev/kbd");
|
||||||
|
if (kbd_fd == -1) return;
|
||||||
|
|
||||||
|
clear(vga_fd);
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
|
while (1) {
|
||||||
|
// first, get shell output
|
||||||
int rd = read(0, &c, 1);
|
int rd = read(0, &c, 1);
|
||||||
if (rd > 0) {
|
if (rd > 0) {
|
||||||
write(vga_fd, &c, 1);
|
write(vga_fd, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// then read a byte from the kbd. If we got one, pass it to the shell
|
||||||
|
rd = read(kbd_fd, &c, 1);
|
||||||
|
if (rd > 0) {
|
||||||
|
write(1, &c, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,13 +13,14 @@
|
|||||||
#define SYS_FORK 21
|
#define SYS_FORK 21
|
||||||
#define SYS_EXEC 22
|
#define SYS_EXEC 22
|
||||||
#define SYS_DUP2 23
|
#define SYS_DUP2 23
|
||||||
|
#define SYS_LSEEK 24
|
||||||
|
|
||||||
int open(const char* path);
|
int open(const char* path);
|
||||||
int write(int fd, const void *buf, size_t count);
|
int write(int fd, const void *buf, size_t count);
|
||||||
int read(int fd, void *buf, size_t count);
|
int read(int fd, void *buf, size_t count);
|
||||||
int close(int fd);
|
int close(int fd);
|
||||||
|
|
||||||
size_t lseek(int fd, size_t offset, int whence);
|
int lseek(int fd, size_t offset, int whence);
|
||||||
|
|
||||||
void exit(int status) __attribute__((noreturn));
|
void exit(int status) __attribute__((noreturn));
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ int read(int fd, void* buf, size_t cnt) {
|
|||||||
return syscall3(SYS_READ, (uint32_t)fd, (uint32_t)buf, (uint32_t)cnt);
|
return syscall3(SYS_READ, (uint32_t)fd, (uint32_t)buf, (uint32_t)cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lseek(int fd, size_t offset, int whence) {
|
||||||
|
return syscall3(SYS_LSEEK, (uint32_t)fd, offset, whence);
|
||||||
|
}
|
||||||
|
|
||||||
int close(int fd) {
|
int close(int fd) {
|
||||||
return syscall1(SYS_CLOSE, fd);
|
return syscall1(SYS_CLOSE, fd);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user