新增libc实现

This commit is contained in:
XIAOYI12 2024-09-01 14:56:38 +08:00
parent de79713c04
commit fcecb41165
17 changed files with 683 additions and 18 deletions

18
apps/include/ctype.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef CRASHPOWEROS_CTYPE_H
#define CRASHPOWEROS_CTYPE_H
int ispunct(char ch);
char toupper(char ch);
char tolower(char ch);
int iscsymf(int ch);
int isascll(char ch);
int iscntrl(char ch);
int isxdigit(int c);
int isspace(int c);
int isdigit(int c);
int isalpha(int c);
int isupper(int c);
int isprint(int c);
int isgraph(int c);
#endif

View File

@ -1,4 +0,0 @@
#ifndef CRASHPOWEROS_LIBC_H
#define CRASHPOWEROS_LIBC_H
#endif

19
apps/include/math.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef CRASHPOWEROS_MATH_H
#define CRASHPOWEROS_MATH_H
#define MIN(i, j) (((i) < (j)) ? (i) : (j))
#define MAX(i, j) (((i) > (j)) ? (i) : (j))
#include <stdint.h>
void srandlevel(unsigned short randlevel_);
void smax(unsigned short max_b);
void srand(unsigned long long seed);
const unsigned long long rand();
int32_t abs(int32_t x);
double pow(double a,long long b);
unsigned long long ull_pow(unsigned long long a,unsigned long long b);
double sqrt(double x);
float q_sqrt(float number);
#endif

View File

@ -1,13 +1,42 @@
#ifndef CRASHPOWEROS_STDIO_H #ifndef CRASHPOWEROS_STDIO_H
#define CRASHPOWEROS_STDIO_H #define CRASHPOWEROS_STDIO_H
#define EOF -1
#define CANREAD(flag) ((flag)&READ || (flag)&PLUS)
#define CANWRITE(flag) ((flag)&WRITE || (flag)&PLUS || (flag)&APPEND)
#define READ 0x2
#define WRITE 0x4
#define APPEND 0x8
#define BIN 0x0
#define PLUS 0x10
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
typedef struct FILE {
unsigned int mode;
unsigned int fileSize;
unsigned char *buffer;
unsigned int bufferSize;
unsigned int p;
char *name;
} FILE;
void put_char(char a); void put_char(char a);
int printf(const char* fmt, ...); int printf(const char* fmt, ...);
int puts(const char *s); int puts(const char *s);
int vsprintf(char *buf, const char *fmt, va_list args); int vsprintf(char *buf, const char *fmt, va_list args);
int fgetc(FILE *stream);
FILE *fopen(char *filename, char *mode);
unsigned int fread(void *buffer, unsigned int size, unsigned int count,
FILE *stream);
int fclose(FILE *fp);
char *fgets(char *str, int n, FILE *stream);
int fputs(const char *str, FILE *stream);
int fprintf(FILE *stream, const char *format, ...);
int fputc(int ch, FILE *stream);
unsigned int fwrite(const void *ptr, unsigned int size, unsigned int nmemb,
FILE *stream);
#endif #endif

12
apps/include/stdlib.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef CRASHPOWEROS_STDLIB_H
#define CRASHPOWEROS_STDLIB_H
#include <stddef.h>
long long atoi(const char* s);
void *malloc(size_t size);
void free(void *ptr);
void exit(int code);
void *realloc(void *ptr, uint32_t size);
#endif

View File

@ -2,15 +2,23 @@
#define CRASHPOWEROS_STRING_H #define CRASHPOWEROS_STRING_H
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
int isspace(int c); const char* memchr(const char* buf,char c,unsigned long long count);
int isdigit(int c); void *memmove(void *dest, const void *src, size_t num);
int isalpha(int c); void *memset(void *s, int c, size_t n);
int isupper(int c); int memcmp(const void *a_, const void *b_, uint32_t size);
size_t strnlen(const char *s, size_t maxlen);
void* memcpy(void* s, const void* ct, size_t n);
size_t strlen(const char *str); size_t strlen(const char *str);
int strcmp(const char *s1, const char *s2); int strcmp(const char *s1, const char *s2);
char *strcpy(char *dest, const char *src); char *strcpy(char *dest, const char *src);
char *strcat(char *dest, const char *src); char *strcat(char *dest, const char *src);
const char* strstr(const char *str1,const char *str2);
char *strdup(const char *str);
char* strncat(char* dest,const char* src,unsigned long long count);
size_t strnlen(const char *s, size_t maxlen);
char* strncpy(char* dest, const char* src,unsigned long long count);
#endif #endif

View File

@ -9,6 +9,9 @@
#define SYSCALL_EXIT 6 #define SYSCALL_EXIT 6
#define SYSCALL_G_CLEAN 7 #define SYSCALL_G_CLEAN 7
#define SYSCALL_GET_CD 8 #define SYSCALL_GET_CD 8
#define SYSCALL_VFS_FILESIZE 9
#define SYSCALL_VFS_READFILE 10
#define SYSCALL_VFS_WRITEFILE 11
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
@ -21,5 +24,8 @@ void syscall_free(void *ptr);
void syscall_exit(int code); void syscall_exit(int code);
void syscall_g_clean(); void syscall_g_clean();
void syscall_get_cd(char *buffer); void syscall_get_cd(char *buffer);
int syscall_vfs_filesize(char* filename);
void syscall_vfs_readfile(char* filename,char* buffer);
void syscall_vfs_writefile(char* filename,char* buffer,unsigned int size);
#endif #endif

View File

@ -1,13 +1,228 @@
#include "../include/stdio.h" #include "../include/stdio.h"
#include "../include/syscall.h" #include "../include/syscall.h"
#include "../include/stdlib.h"
#include "../include/string.h"
void *malloc(size_t size){
return syscall_malloc(size);
}
void free(void *ptr){
syscall_free(ptr);
}
void exit(int code){
syscall_exit(code);
}
void *realloc(void *ptr, uint32_t size) {
void *new = malloc(size);
if (ptr) {
memcpy(new, ptr, *(int *)((int)ptr - 4));
free(ptr);
}
return new;
}
long long atoi(const char* s){
long long temp = 0,sign = (*s <= '9' && *s >= '0') ;
while(*s > '9' || *s < '0')s ++ ;
if(temp == 0 && *(s - 1) == '-')sign = -1 ;
else sign = 1 ;
while(*s <= '9' && *s >= '0')temp = (temp * 10) + (*s - '0') , s ++ ;
return sign * temp ;
}
void put_char(char c){ void put_char(char c){
syscall_putchar(c); syscall_putchar(c);
} }
int fputc(int ch, FILE *stream) {
if (CANWRITE(stream->mode)) {
// printk("Current Buffer=%s\n",stream->buffer);
if (stream->p >= stream->bufferSize) {
// printk("Realloc....(%d,%d)\n",stream->p,stream->bufferSize);
stream->buffer = realloc(stream->buffer, stream->bufferSize + 100);
stream->bufferSize += 100;
}
if (stream->p >= stream->fileSize) {
stream->fileSize++;
}
// printk("Current Buffer=%s(A)\n",stream->buffer);
stream->buffer[stream->p++] = ch;
// printk("Current Buffer=%s(B)\n",stream->buffer);
return ch;
}
return EOF;
}
unsigned int fwrite(const void *ptr, unsigned int size, unsigned int nmemb,
FILE *stream) {
if (CANWRITE(stream->mode)) {
unsigned char *c_ptr = (unsigned char *)ptr;
for (int i = 0; i < size * nmemb; i++) {
fputc(c_ptr[i], stream);
}
return nmemb;
} else {
return 0;
}
}
FILE *fopen(char *filename, char *mode) {
unsigned int flag = 0;
FILE *fp = (FILE *)malloc(sizeof(FILE));
while (*mode != '\0') {
switch (*mode) {
case 'a':
flag |= APPEND;
break;
case 'b':
break;
case 'r':
flag |= READ;
break;
case 'w':
flag |= WRITE;
break;
case '+':
flag |= PLUS;
break;
default:
break;
}
mode++;
}
if (syscall_vfs_filesize(filename) == -1) {
free(fp);
return NULL; // 找不到
} else if (flag & WRITE) {
char buffe2[100];
}
if (flag & WRITE) {
fp->fileSize = 0;
} else {
fp->fileSize = syscall_vfs_filesize(filename);
}
fp->bufferSize = 0;
if (flag & READ || flag & PLUS || flag & APPEND) {
fp->bufferSize = syscall_vfs_filesize(filename);
}
if (flag & WRITE || flag & PLUS || flag & APPEND) {
fp->bufferSize += 100;
}
if (fp->bufferSize == 0) {
fp->bufferSize = 1;
}
fp->buffer = malloc(fp->bufferSize);
if (flag & PLUS || flag & APPEND || flag & READ) {
// printk("ReadFile........\n");
syscall_vfs_readfile(filename, fp->buffer);
}
fp->p = 0;
if (flag & APPEND) {
fp->p = fp->fileSize;
}
fp->name = malloc(strlen(filename) + 1);
strcpy(fp->name, filename);
fp->mode = flag;
return fp;
}
int fgetc(FILE *stream) {
if (CANREAD(stream->mode)) {
if (stream->p >= stream->fileSize) {
return EOF;
} else {
return stream->buffer[stream->p++];
}
} else {
return EOF;
}
}
unsigned int fread(void *buffer, unsigned int size, unsigned int count,
FILE *stream) {
if (CANREAD(stream->mode)) {
unsigned char *c_ptr = (unsigned char *)buffer;
for (int i = 0; i < size * count; i++) {
unsigned int ch = fgetc(stream);
if (ch == EOF) {
return i;
} else {
c_ptr[i] = ch;
}
}
return count;
} else {
return 0;
}
}
int fclose(FILE *fp) {
if (fp == NULL) {
return EOF;
}
if (CANWRITE(fp->mode)) {
syscall_vfs_writefile(fp->name, fp->buffer, fp->fileSize);
}
free(fp->buffer);
free(fp->name);
free(fp);
return 0;
}
char *fgets(char *str, int n, FILE *stream) {
if (CANREAD(stream->mode)) {
for (int i = 0; i < n; i++) {
unsigned int ch = fgetc(stream);
if (ch == EOF) {
if (i == 0) {
return NULL;
} else {
break;
}
}
if (ch == '\n') {
break;
}
str[i] = ch;
}
return str;
}
return NULL;
}
int fputs(const char *str, FILE *stream) {
if (CANWRITE(stream->mode)) {
for (int i = 0; i < strlen(str); i++) {
fputc(str[i], stream);
}
return 0;
}
return EOF;
}
int fprintf(FILE *stream, const char *format, ...) {
if (CANWRITE(stream->mode)) {
int len;
va_list ap;
va_start(ap, format);
char *buf = malloc(1024);
len = vsprintf(buf, format, ap);
fputs(buf, stream);
free(buf);
va_end(ap);
return len;
} else {
return EOF;
}
}
void _start(){ void _start(){
extern int main(); extern int main(int argc,char** argv);
int ret = main(); int ret = main(0,NULL);
syscall_exit(ret); exit(ret);
while (1); while (1);
} }

77
apps/libs/math.c Normal file
View File

@ -0,0 +1,77 @@
#include "../include/math.h"
static unsigned long long rand_seed = 1 ;
static unsigned short max_bit = 32 ;
static unsigned short randlevel = 1 ;
const unsigned long long rand(){
unsigned short i = 0;
while(i < randlevel)
rand_seed = rand_seed * 1103515245 + 12345 , rand_seed <<= max_bit , i ++ ;
return (const unsigned long long)(rand_seed >>= max_bit) ;
}
void srand(unsigned long long seed){
rand_seed = seed ;
}
void smax(unsigned short max_b){
max_b = (sizeof(unsigned long long) * 8) - (max_b % (sizeof(unsigned long long) * 8)) ;
max_bit = (max_b == 0) ? (sizeof(unsigned long long) * 8 / 2) : (max_b) ;
}
void srandlevel(unsigned short randlevel_){
if(randlevel_ != 0)
randlevel = randlevel_ ;
}
int32_t abs(int32_t x){
return (x < 0) ? (-x) : (x) ;
}
double pow(double a,long long b){
char t = 0 ;
if(b < 0)b = -b , t = 1 ;
double ans = 1 ;
while(b){
if(b & 1)ans *= a ;
a *= a ;
b >>= 1 ;
}
if(t)return (1.0 / ans) ;
else return ans ;
}
//快速整数平方
unsigned long long ull_pow(unsigned long long a,unsigned long long b){
unsigned long long ans = 1 ;
while(b){
if(b & 1)ans *= a ;
a *= a ;
b >>= 1 ;
}
return ans ;
}
double sqrt(double x){
if(x == 0)return 0.0 ;
double xk = 1.0,xk1 = 0.0 ;
while(xk != xk1)xk1 = xk , xk = (xk + x / xk) / 2.0 ;
return xk ;
}
//快速求算数平方根(速度快,精度低)
float q_sqrt(float number){
long i ;
float x,y ;
const float f = 1.5F ;
x = number * 0.5F ;
y = number ;
i = *(long*)(&y) ;
i = 0x5f3759df - (i >> 1) ;
y = *(float*)(&i) ;
y = y * (f - (x * y * y)) ;
y = y * (f - (x * y * y)) ;
return number * y ;
}

View File

@ -1,25 +1,76 @@
#include "../include/string.h" #include "../include/string.h"
#include "../include/ctype.h"
#include "../include/stdlib.h"
int ispunct(char ch) {
return ch == '!' || ch == '@' || ch == '#' || ch == '$' || ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '/' || ch == '?' || ch == '"' || ch == '\'' ||
ch == ':' || ch == ';' || ch == '{' || ch == '[' || ch == ']' || ch == '}' || ch == '|' || ch == '\\' ||
ch == '~' || ch == '`' || ch == '<' || ch == '>' || ch == ',' || ch == '.';
}
char toupper(char ch) {
return (ch & 0xDF);
}
char tolower(char ch) {
return (ch | 0x20);
}
int iscsymf(int ch) {
return ch == '_' || isdigit(ch) || isalpha(ch);
}
int isascll(char ch) {
return ((ch & 0x80) == 0);
}
int iscntrl(char ch) {
return ((ch == 0x7F) || (ch >= 0x00 && ch <= 0x1F));
}
int isprint(int c) {
return (c > 0x1F && c < 0x7F);
}
int isgraph(int c) {
return (c > 0x20 && c < 0x7F);
}
int isxdigit(int c) {
if (!((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
if (!isdigit(c)) return 0;
}
return 1;
}
int isspace(int c) { int isspace(int c) {
return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
c == '\v'); c == '\v');
} }
// isdigit
int isdigit(int c) { int isdigit(int c) {
return (c >= '0' && c <= '9'); return (c >= '0' && c <= '9');
} }
// isalpha
int isalpha(int c) { int isalpha(int c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
} }
// isupper
int isupper(int c) { int isupper(int c) {
return (c >= 'A' && c <= 'Z'); return (c >= 'A' && c <= 'Z');
} }
const char *memchr(const char *buf, char c, unsigned long long count) {
while (count) {
if (*buf == c)
return buf;
++count;
++buf;
}
return 0;
}
size_t strnlen(const char *s, size_t maxlen) { size_t strnlen(const char *s, size_t maxlen) {
const char *es = s; const char *es = s;
while (*es && maxlen) { while (*es && maxlen) {
@ -73,3 +124,91 @@ char *strcat(char *dest, const char *src) {
temp++; temp++;
while ((*temp++ = *src++) != '\0'); while ((*temp++ = *src++) != '\0');
} }
void *memcpy(void *s, const void *ct, size_t n) {
if (NULL == s || NULL == ct || n <= 0)
return NULL;
while (n--)
*(char *) s++ = *(char *) ct++;
return s;
}
int memcmp(const void *a_, const void *b_, uint32_t size) {
const char *a = a_;
const char *b = b_;
while (size-- > 0) {
if (*a != *b) return *a > *b ? 1 : -1;
a++, b++;
}
return 0;
}
void *memset(void *s, int c, size_t n) {
unsigned char *p = s;
while (n-- > 0)
*p++ = c;
return s;
}
void *memmove(void *dest, const void *src, size_t num) {
void *ret = dest;
if (dest < src) {
while (num--)//前->后
{
*(char *) dest = *(char *) src;
dest = (char *) dest + 1;
src = (char *) src + 1;
}
} else {
while (num--)//后->前
{
*((char *) dest + num) = *((char *) src + num);
}
}
return ret;
}
char *strncat(char *dest, const char *src, unsigned long long count) {
if (dest == 0 || src == 0)return 0;
char *ret = dest;
while (*dest != '\0')dest++;
for (unsigned long long i = 0; i < count; ++i)dest[i] = src[i];
dest[count] = '\0';
return ret;
}
char *strncpy(char *dest, const char *src, unsigned long long count) {
if (dest == 0 || src == 0)return 0;
char *ret = dest;
while (count)*dest = *src, ++dest, ++src, --count;
return ret;
}
const char *strstr(const char *str1, const char *str2) {
if (str1 == 0 || str2 == 0)return 0;
const char *temp = 0;
const char *res = 0;
while (*str1 != '\0') {
temp = str1;
res = str2;
while (*temp == *res)++temp, ++res;
if (*res == '\0')return str1;
++str1;
}
return 0;
}
char *strdup(const char *str) {
if (str == NULL)
return NULL;
char *strat = (char *) str;
int len = 0;
while (*str++ != '\0')
len++;
char *ret = (char *) malloc(len + 1);
while ((*ret++ = *strat++) != '\0') {}
return ret - (len + 1);
}

View File

@ -53,3 +53,31 @@ void syscall_get_cd(char *buffer){
register uint32_t ebx asm("ebx") = __arg1; register uint32_t ebx asm("ebx") = __arg1;
asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_GET_CD), "r"(ebx) : "memory", "cc"); asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_GET_CD), "r"(ebx) : "memory", "cc");
} }
int syscall_vfs_filesize(char* filename){
uint32_t rets;
uint32_t __arg1 = (uint32_t)(filename);
register uint32_t ebx asm("ebx") = __arg1;
asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_VFS_FILESIZE), "r"(ebx) : "memory", "cc");
return rets;
}
void syscall_vfs_readfile(char* filename,char* buffer){
uint32_t rets;
uint32_t __arg1 = (uint32_t)(filename);
uint32_t __arg2 = (uint32_t)(buffer);
register uint32_t ebx asm("ebx") = __arg1;
register uint32_t ecx asm("ecx") = __arg2;
asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_VFS_READFILE), "r"(ebx), "r"(ecx) : "memory", "cc");
}
void syscall_vfs_writefile(char* filename,char* buffer,unsigned int size){
uint32_t rets;
uint32_t __arg1 = (uint32_t)(filename);
uint32_t __arg2 = (uint32_t)(buffer);
uint32_t __arg3 = (uint32_t)(size);
register uint32_t ebx asm("ebx") = __arg1;
register uint32_t ecx asm("ecx") = __arg2;
register uint32_t edx asm("edx") = __arg3;
asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_VFS_FILESIZE), "r"(ebx), "r"(ecx), "r"(edx) : "memory", "cc");
}

View File

@ -9,7 +9,7 @@ static int gets(char *buf, int buf_size) {
if (c == '\b') { if (c == '\b') {
if (index > 0) { if (index > 0) {
index--; index--;
syscall_print("\b \b"); printf("\b \b");
} }
} else { } else {
buf[index++] = c; buf[index++] = c;
@ -72,7 +72,7 @@ int main(){
printf("mkdir <name> Make a directory.\n"); printf("mkdir <name> Make a directory.\n");
printf("del rm <name> Delete a file.\n"); printf("del rm <name> Delete a file.\n");
printf("sysinfo Print system info.\n"); printf("sysinfo Print system info.\n");
printf("proc [kill<pid>|list] Lists all running processes.\n"); printf("proc [kill<pid>|list] List all running processes.\n");
printf("reset Reset OS.\n"); printf("reset Reset OS.\n");
printf("shutdown exit Shutdown OS.\n"); printf("shutdown exit Shutdown OS.\n");
printf("debug Print os debug info.\n"); printf("debug Print os debug info.\n");

12
src/include/pagehead.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef CRASHPOWEROS_PAGEHEAD_H
#define CRASHPOWEROS_PAGEHEAD_H
#include <stdint.h>
#include <stddef.h>
void *page_sbrk(int incr);
void *page_alloc(size_t size);
void page_free(void *block);
void *page_malloc(size_t size,uint32_t *phys);
#endif

View File

@ -13,6 +13,9 @@
#define SYSCALL_EXIT 6 #define SYSCALL_EXIT 6
#define SYSCALL_G_CLEAN 7 #define SYSCALL_G_CLEAN 7
#define SYSCALL_GET_CD 8 #define SYSCALL_GET_CD 8
#define SYSCALL_VFS_FILESIZE 9
#define SYSCALL_VFS_READFILE 10
#define SYSCALL_VFS_WRITEFILE 11
void syscall_install(); void syscall_install();

View File

@ -3,6 +3,7 @@
#include "../include/io.h" #include "../include/io.h"
#include "../include/task.h" #include "../include/task.h"
#include "../include/timer.h" #include "../include/timer.h"
#include "../include/pagehead.h"
page_directory_t *kernel_directory = 0; // 内核用页目录 page_directory_t *kernel_directory = 0; // 内核用页目录
page_directory_t *current_directory = 0; // 当前页目录 page_directory_t *current_directory = 0; // 当前页目录
@ -14,6 +15,7 @@ extern struct task_struct *current;
extern uint32_t placement_address; extern uint32_t placement_address;
extern void *program_break, *program_break_end; extern void *program_break, *program_break_end;
extern void *page_break, *page_end;
static void set_frame(uint32_t frame_addr) { static void set_frame(uint32_t frame_addr) {
uint32_t frame = frame_addr / 0x1000; uint32_t frame = frame_addr / 0x1000;
@ -169,6 +171,7 @@ void page_fault(registers_t *regs) {
static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) { static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) {
page_table_t *table = (page_table_t *) kmalloc_i_ap(sizeof(page_table_t), physAddr); page_table_t *table = (page_table_t *) kmalloc_i_ap(sizeof(page_table_t), physAddr);
memset(table, 0, sizeof(page_directory_t)); memset(table, 0, sizeof(page_directory_t));
int i; int i;
@ -210,8 +213,11 @@ page_directory_t *clone_directory(page_directory_t *src) {
} }
void init_page(multiboot_t *mboot) { void init_page(multiboot_t *mboot) {
uint32_t mem_end_page = 0xFFFFFFFF; // 4GB Page
page_break = placement_address;
page_end = placement_address + 0x50000;
uint32_t mem_end_page = 0xFFFFFFFF; // 4GB Page
nframes = mem_end_page / 0x1000; nframes = mem_end_page / 0x1000;
frames = (uint32_t *) kmalloc(INDEX_FROM_BIT(nframes)); frames = (uint32_t *) kmalloc(INDEX_FROM_BIT(nframes));
memset(frames, 0, INDEX_FROM_BIT(nframes)); memset(frames, 0, INDEX_FROM_BIT(nframes));

81
src/kernel/pagehead.c Normal file
View File

@ -0,0 +1,81 @@
#include "../include/pagehead.h"
#include "../include/memory.h"
void *page_break, *page_end;
header_t *page_head;
header_t *page_tail;
extern void *program_break;
extern page_directory_t *kernel_directory;
static header_t *page_get_free_block(size_t size) {
header_t *curr = page_head;
while (curr) {
if (curr->s.is_free && curr->s.size >= size) return curr;
curr = curr->s.next;
}
return NULL;
}
void *page_sbrk(int incr) {
if (page_break + incr >= (page_end)) return (void *) -1;
void *prev_break = page_break;
page_break += incr;
return prev_break;
}
void *page_malloc(size_t size,uint32_t *phys){
void *addr = page_alloc(size);
*phys = addr;
if (program_break) {
if (phys) {
page_t *page = get_page((uint32_t) addr, 0, kernel_directory,false);
*phys = page->frame * 0x1000 + ((uint32_t) addr & 0x00000FFF);
}
}
return (uint32_t) addr;
}
void *page_alloc(size_t size) {
uint32_t total_size;
void *block;
header_t *header;
if (!size) return NULL;
header = page_get_free_block(size);
if (header) {
header->s.is_free = 0;
return (void *) (header + 1);
}
total_size = sizeof(header_t) + size;
block = page_sbrk(total_size);
if (block == (void *) -1) return NULL;
header = block;
header->s.size = size;
header->s.is_free = 0;
header->s.next = NULL;
if (!page_head) page_head = header;
if (page_tail) page_tail->s.next = header;
page_tail = header;
return (void *) (header + 1);
}
void page_free(void *block) {
header_t *header, *tmp;
if (!block) return;
header = (header_t *) block - 1;
if ((char *) block + header->s.size == page_break) {
if (page_head == page_tail)page_head = page_tail = NULL;
else {
tmp = page_head;
while (tmp) {
if (tmp->s.next == page_tail) {
tmp->s.next = NULL;
page_tail = tmp;
}
tmp = tmp->s.next;
}
}
page_sbrk(0 - sizeof(header_t) - header->s.size);
return;
}
header->s.is_free = 1;
}

View File

@ -7,6 +7,7 @@
#include "../include/shell.h" #include "../include/shell.h"
#include "../include/heap.h" #include "../include/heap.h"
#include "../include/keyboard.h" #include "../include/keyboard.h"
#include "../include/vfs.h"
static void syscall_puchar(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){ static void syscall_puchar(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
printf("%c",ebx); printf("%c",ebx);
@ -47,6 +48,18 @@ static void syscall_get_cd(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,u
else buf = "nofs"; else buf = "nofs";
} }
static int syscall_vfs_filesize(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
return vfs_filesize(ebx);
}
static void syscall_vfs_readfile(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
vfs_readfile(ebx,ecx);
}
static void syscall_vfs_writefile(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
vfs_writefile(ebx,ecx,edx);
}
void *sycall_handlers[MAX_SYSCALLS] = { void *sycall_handlers[MAX_SYSCALLS] = {
[SYSCALL_PUTC] = syscall_puchar, [SYSCALL_PUTC] = syscall_puchar,
[SYSCALL_PRINT] = syscall_print, [SYSCALL_PRINT] = syscall_print,
@ -56,6 +69,9 @@ void *sycall_handlers[MAX_SYSCALLS] = {
[SYSCALL_EXIT] = syscall_exit, [SYSCALL_EXIT] = syscall_exit,
[SYSCALL_G_CLEAN] = syscall_g_clean, [SYSCALL_G_CLEAN] = syscall_g_clean,
[SYSCALL_GET_CD] = syscall_get_cd, [SYSCALL_GET_CD] = syscall_get_cd,
[SYSCALL_VFS_FILESIZE] = syscall_vfs_filesize,
[SYSCALL_VFS_READFILE] = syscall_vfs_readfile,
[SYSCALL_VFS_WRITEFILE] = syscall_vfs_writefile,
}; };
typedef size_t (*syscall_t)(size_t, size_t, size_t, size_t, size_t); typedef size_t (*syscall_t)(size_t, size_t, size_t, size_t, size_t);