⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscalls.c

📁 一个类linux的dos下开发的操作系统.
💻 C
字号:
/*****************************************************************************
SYSCALLS

EXPORTS:
void sys_exit(task_t *curr_task, int exit_code);
bool syscall(task_t *curr_task, volatile regs_t *regs);
*****************************************************************************/
#include <string.h> /* NULL */
#include <krnl.h>
#include <_sys.h> /* SYS_... */

/* IMPORTS
from MAIN.C */
extern task_t _tasks[];

int sleep_on(task_t *curr_task, wait_queue_t *queue, unsigned *timeout);
void kprintf(const char *fmt, ...);

/* from VIDEO.C */
void putch(console_t *con, unsigned char c);

/* from TIME.C */
unsigned long sys_time(void);
/*****************************************************************************
*****************************************************************************/
static unsigned long sys_sbrk(task_t *curr_task, long delta)
{
	sect_t *sect;

	sect = curr_task->sect + HEAP_SECT;
/* shrink heap */
	if(delta < 0)
	{
/* don't lower break value if delta is too large */
		if((unsigned long)(-delta) < sect->size)
			sect->size += delta;
	}
/* grow heap */
	else if(delta > 0)
	{
/* don't increase break value if delta is too large */
		if(delta + sect->size < MAX_HEAP_SIZE)
			sect->size += delta;
	}
/* return new or current break value */
	return sect->adr + sect->size;
}
/*****************************************************************************
*****************************************************************************/
void sys_exit(task_t *curr_task, int exit_code)
{
	curr_task->exit_code = exit_code;
	curr_task->status = TS_ZOMBIE;
}
/*****************************************************************************
*****************************************************************************/
static bool sys_sleep(task_t *curr_task, unsigned timeout)
{
/* 'dummy' because wake_up() is not used; only the timeout */
	static wait_queue_t dummy;
/**/

	if(timeout != 0)
	{
		sleep_on(curr_task, &dummy, &timeout);
		return false;
	}
	return true;
}
/*****************************************************************************
*****************************************************************************/
static int sys_write(task_t *curr_task, unsigned handle, void *bufp,
		unsigned len)
{
	char *buf = (char *)bufp;
	unsigned pos;

	for(pos = 0; pos < len; pos++)
	{
		putch(curr_task->vc, *buf);
		buf++;
	}
	return len;
}
/*****************************************************************************
	name:	deq
	action:	tries to get byte from queue
	returns:-1 if queue empty
		0  if success (data set to value read from queue)
*****************************************************************************/
static int deq(queue_t *q, unsigned char *data)
{
/* if out_ptr reaches in_base, the queue is empty */
	if(q->out_ptr == q->in_base)
		return -1;
	*data = q->data[q->out_ptr++];
	if(q->out_ptr >= q->size)
		q->out_ptr = 0;
	return 0;
}
/*****************************************************************************
*****************************************************************************/
static int empty(queue_t *q)
{
	return q->out_ptr == q->in_base;
}
/*****************************************************************************
*****************************************************************************/
static int sys_read(task_t *curr_task, unsigned handle, unsigned char *buf,
		unsigned want)
{
	console_t *con;
	unsigned got;
	queue_t *q;

	con = curr_task->vc;
	q = &con->keystrokes;
if(con->unbuffered)
 want = 1;
	for(got = 0; got < want; got++)
	{
		do
		{
			while(empty(q))
				sleep_on(curr_task, &con->wait_queue, NULL);
		} while(deq(q, buf) != 0);
		if(*buf == '\0')
			break;
		buf++;
	}
	return got;
}
/*****************************************************************************
*****************************************************************************/
static int sys_ioctl(task_t *curr_task, unsigned handle,
		unsigned char opcode, unsigned arg)
{
	switch(opcode)
	{
/* turn keyboard unbuffered on/off */
		case 0:
			switch(arg)
			{
				case 0:
				case 1:
					curr_task->vc->unbuffered = arg;
					break;
				default:
					return -1;
			}
			break;
		default:
			return -1;
	}
	return 0;
}
/*****************************************************************************
returns nonzero if timeout while waiting for input
*****************************************************************************/
static int sys_select(task_t *curr_task, unsigned handle, unsigned timeout)
{
	console_t *con;
	queue_t *q;

	con = curr_task->vc;
	q = &con->keystrokes;
	if(!empty(q))
		return 0;
	sleep_on(curr_task, &con->wait_queue, &timeout);
	return timeout == 0;
}
/*****************************************************************************
*****************************************************************************/
bool syscall(task_t *curr_task, volatile regs_t *regs)
{
	bool must_call_schedule = false;

	switch(regs->eax)
	{
		case SYS_WRITE:
			regs->eax = sys_write(curr_task, regs->edx,
				(unsigned char *)regs->ebx,
				regs->ecx);
			break;
		case SYS_READ:
			regs->eax = sys_read(curr_task, regs->edx,
				(unsigned char *)regs->ebx,
				regs->ecx);
			break;
		case SYS_IOCTL:
			regs->eax = sys_ioctl(curr_task, regs->edx,
				regs->ebx, regs->ecx);
			break;
		case SYS_SELECT:
			regs->eax = sys_select(curr_task, regs->edx,
				regs->ebx);
			break;
		case SYS_SBRK:
			regs->eax = sys_sbrk(curr_task, regs->ebx);
			break;
		case SYS_TIME:
			regs->eax = sys_time();
			break;
		case SYS_EXIT:
			sys_exit(curr_task, regs->ebx);
			must_call_schedule = true;
			break;
		case SYS_SLEEP:
			must_call_schedule = sys_sleep(curr_task, regs->ebx);
			break;
		default:
			kprintf("Illegal syscall 0x%X; task %u killed\n",
				regs->eax, curr_task - _tasks);
			sys_exit(curr_task, -1);
			must_call_schedule = true;
			break;
	}
	return must_call_schedule;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -