提交 03e631dc 编写于 作者: R rain

make a file-operations of text VGA mode

上级 855dd27b
......@@ -24,3 +24,5 @@
2021-2-25 0.790: 790 lines, 10 files, rain
2021-3-12 1.384: 1384 lines, 20 files, rain
......@@ -5,11 +5,14 @@ all:
make cunix.img
clear:
rm *.bin boot/x86/*.bin kernel/*.o kernel/*.bin kernel/init/*.o kernel/hal/*.o cunix.img -rf
make -C kernel/ clear
make -C boot/x86/ clear
rm cunix.img boot.bin
lines:
wc boot/x86/boot.asm boot/x86/loader.asm kernel/init/*.c kernel/hal/*.c include/arch/x86/* include/kernel/* -l
wc boot/x86/boot.asm boot/x86/loader.asm kernel/init/*.c kernel/lib/*.c kernel/hal/vgatext/*.c include/arch/x86/* include/arch/*.h include/kernel/* include/lib/* -l
cunix.img: boot/x86/bootloader.bin kernel/kernel.bin
......
......@@ -9,7 +9,7 @@ Cunix kernel
&nbsp;&nbsp;&nbsp;&nbsp;it uses `2MB` page to make 0-12 MB memory to `0x0000 - 0xc0000`. <br/>
`0.385s-boot`:
`0.385s-boot`:
&nbsp;&nbsp;&nbsp;&nbsp;rebuild `boot` and `loader`. <br/>
......@@ -36,21 +36,25 @@ Cunix kernel
&nbsp;&nbsp;&nbsp;&nbsp;protect-mode. <br/>
`0.484s-boot`:
`0.484s-boot`:
&nbsp;&nbsp;&nbsp;&nbsp;let `readdisk.inc` smaller, but we just can use CHS or LBA, not both. <br/>
`0.509s-kernel`:
`0.509s-kernel`:
&nbsp;&nbsp;&nbsp;&nbsp;load kernel to 0x8200-0x9200 for 4KB, kernel.asm display 'K' to screen. <br/>
`0.556s-int`:
`0.556s-int`:
&nbsp;&nbsp;&nbsp;&nbsp;init IDT at 0x0000-0x1000, and set all handler at `ignore_int`, but it do nothing. <br/>
`0.619s-boot`:
`0.619s-boot`:
&nbsp;&nbsp;&nbsp;&nbsp;load 180KB of disk, not 4KB <br/>
`0.566s-kernel`:
`0.566s-kernel`:
&nbsp;&nbsp;&nbsp;&nbsp;write in C. <br/>
`0.790s-kernel`:
`0.790s-kernel`:
&nbsp;&nbsp;&nbsp;&nbsp;make some structs <br/>
`1.384s-hal`:
&nbsp;&nbsp;&nbsp;&nbsp;use text VGA mode, and make a file-operations of it.
......@@ -18,3 +18,4 @@ bootloader.bin: boot.bin loader.bin
clear:
rm *.bin
......@@ -28,8 +28,6 @@ jmp _start
bits 16
_start:
call set_vga_mode
; enable A20 address 20 line
.open_a20:
in al, 0x92
......@@ -65,12 +63,6 @@ print:
.do_ret:
ret
set_vga_mode:
mov al, 0x13
mov ah, 0x00
int 0x10
ret
bits 32
......
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_IO_H
#define INCLUDED_IO_H
#include <kernel/types.h>
typedef __uint16_t port_t;
#define inb(port) ({ \
__uint8_t _r; \
__asm__ volatile ("inb %%dx, %%al" : "=a" (_r) : "d" (port)); \
_r; \
})
#define inw(port) ({ \
__uint16_t _r; \
__asm__ volatile ("inw %%dx, %%ax" : "=a" (_r) : "d" (port)); \
_r; \
})
#define inl(port) ({ \
__uint32_t _r; \
__asm__ volatile ("inl %%dx, %%eax" : "=a" (_r) : "d" (port)); \
_r; \
})
#define outb(value, port) \
__asm__ volatile ("outb %%al, %%dx" :: "a" (value), "d" (port));
#define outw(value, port) \
__asm__ volatile ("outw %%ax, %%dx" :: "a" (value), "d" (port));
#define outl(value, port) \
__asm__ volatile ("outl %%eax, %%dx" :: "a" (value), "d" (port));
#endif
......@@ -24,6 +24,9 @@
#ifndef INCLUDED_ERRNO_H
#define INCLUDED_ERRNO_H
typedef __uint32_t errno_t;
......@@ -31,36 +34,45 @@ typedef __uint32_t errno_t;
#define E_KERROR 0x20000000
/* error io port */
#define E_IOERROR 0x00000001
#define E_IOERROR 0x00000001 | E_KERROR
/* no enough memory for this call */
#define E_NOMEM 0x00000002
#define E_NOMEM 0x00000002 | E_KERROR
/* call interrupted by signal */
#define E_SIGNAL 0x00000003
#define E_SIGNAL 0x00000003 | E_KERROR
/* kernel not supported */
#define E_NOSUPP 0x00000004 | E_KERROR
/* no permision */
#define E_DENIED 0x40000000
/* need root to call this */
#define E_NDROOT 0x00000001
#define E_NDROOT 0x00000001 | E_DENIED
/* no io passport */
#define E_IODND 0x00000002
#define E_IODND 0x00000002 | E_DENIED
/* need hardware super 0 */
#define E_HARDSP 0x00000003
#define E_HARDSP 0x00000003 | E_DENIED
/* hardware no support */
#define E_HNOSUP 0x00000004 | E_DENIED
/* user error (caller) */
#define E_UERROR 0x80000000
#define E_UERROR 0x80000000 | E_UERROR
/* syntax error for this call (invalid argument) */
#define E_SYNERR 0x00000001
#define E_SYNERR 0x00000001 | E_UERROR
/* error because address is invalid */
#define E_ADDRE 0x00000002
#define E_ADDRE 0x00000002 | E_UERROR
/* call out of range */
#define E_OUTRAG 0x000000003
#define E_OUTRAG 0x00000003 | E_UERROR
#endif
......@@ -24,19 +24,13 @@
#include <kernel/types.h>
#include <kernel/errno.h>
#ifndef INCLUDED_INIT_H
#define INCLUDED_INIT_H
#include <kernel/types.h>
#include <kernel/errno.h>
#define MAKE_MODULE(name) struct file_operations name##_fop = { \
.open = name##_open; \
.creat = name##_create; \
.read = name##_read; \
.write = name##_write; \
.lseek = name##_lseek; \
.close = name##_close; \
};
struct inode_desc {
......@@ -48,7 +42,7 @@ struct inode_desc {
/* file descriptor */
__uint32_t fd;
/* this is optional */
/* this is optional (offset) */
__uint32_t off;
/* this is optional too */
......@@ -56,16 +50,18 @@ struct inode_desc {
};
struct file_oprerations {
struct file_operations {
/* open a file */
struct inode_desc * (* open) (char *name, __uint32_t type, __uint32_t mode, __uint32_t *errno);
struct inode_desc * (* open) (__uint32_t type, __uint32_t mode, __uint32_t *errno);
/* or create one */
/* `creat` doesn't return file-descriptor, it returns errno */
errno_t (* creat) (char *name, __uint32_t type, __uint32_t mode);
errno_t (* creat) (__uint32_t type, __uint32_t mode);
/* `fill` fills a inode descriptor */
errno_t (* fill) (char *name, __uint32_t type, __uint32_t mode, struct inode_desc *i);
/* read from file-descriptor */
errno_t (* read) (struct inode_desc *i, char *buffer, __uint64_t l);
......@@ -76,6 +72,11 @@ struct file_oprerations {
/* change position */
/* 'seg' = whence */
#define SEEK_SET 0x0001
#define SEEK_CUR 0x0002
#define SEEK_END 0x0003
__uint32_t (* lseek) (struct inode_desc *i, __uint32_t off, __uint32_t seg);
/* close a file-descriptor */
......@@ -83,3 +84,5 @@ struct file_oprerations {
};
#endif
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_MODULE_H
#define INCLUDED_MODULE_H
#include <kernel/init.h>
#include <kernel/types.h>
#include <kernel/errno.h>
#define INIT_MODULE(modn) { \
.open = modn##_open, \
.creat = modn##_creat, \
.fill = modn##_fill, \
.read = modn##_read, \
.write = modn##_write, \
.lseek = modn##_lseek, \
.close = modn##_close \
};
#endif
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_PRINT_H
#define INCLUDED_PRINT_H
#include <kernel/types.h>
#include <kernel/errno.h>
#include <kernel/vgatext.h>
__uint32_t print(struct vga_inode *inode, char *s);
#endif
......@@ -24,6 +24,9 @@
#ifndef INCLUDED_TYPES_H
#define INCLUDED_TYPES_H
#define NULL (void *) 0
......@@ -45,3 +48,5 @@ typedef __uint_t __uint32_t;
typedef __ulong_t __uint64_t;
#endif
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_VGA_H
#define INCLUDED_VGA_H
#include <kernel/init.h>
#include <kernel/errno.h>
#include <kernel/types.h>
#include <kernel/module.h>
#define TEXT_VGA_X 80
extern struct file_operations vga;
struct vga_inode {
struct inode_desc inode;
/* frame buffer start address */
/* frame buffer in text mode:
char ASCII | char COLOR
*/
/* but use char is easier */
__uint8_t *fb;
__uint32_t x, y;
};
#endif
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
struct bitmap_manager {
unsigned char *bitmap;
unsigned int next_free;
};
unsigned int bitman_alloc(struct bitmap_manager *bm);
void bitman_free(struct bitmap_manager *bm, unsigned int pos);
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
extern char *bitmap_init(unsigned int size);
extern void bitmap_set(unsigned char *bitmap, unsigned int pos, unsigned char value);
extern char bitmap_read(unsigned char *bitmap, unsigned int pos);
......@@ -24,3 +24,7 @@
#include <lib/bitmap.h>
#include <lib/bitman.h>
default:
make -C init/
make -C hal/
make -C lib/
make kernel.bin
kernel.o: init/main.o hal/terminal.o
ld -b elf64-x86-64 -o kernel.o init/main.o hal/terminal.o -T kernel.lds
kernel.o: init/main.o hal/vgatext/vgatext.o lib/bitmap.o lib/bitman.o init/print.o
ld -b elf64-x86-64 -o kernel.o init/main.o init/print.o hal/vgatext/vgatext.o lib/bitmap.o lib/bitman.o -T kernel.lds
kernel.bin: kernel.o
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary kernel.o kernel.bin
clear:
make -C init/ clear
make -C hal/ clear
make -C lib/ clear
rm kernel.o kernel.bin
C_FLAGS = -mcmodel=large -fno-builtin -m64
all: terminal.c
%.o: %.c
gcc -c $*.c $(C_FLAGS)
all: vgatext/vgatext.c
make -C vgatext/
clear:
make -C vgatext/ clear
C_FLAGS = -mcmodel=large -fno-builtin -m64 -I ../../../include
all: vgatext.o
%.o: %.c
gcc -c *$.c $(C_FLAGS)
clear:
rm *.o
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#include <kernel/init.h>
#include <kernel/types.h>
#include <kernel/errno.h>
#include <kernel/module.h>
#include <lib/rlib.h>
#include <arch/io.h>
#include <kernel/vgatext.h>
__uint32_t next_fd = 1;
struct inode_desc *vga_open(char *name, __uint32_t type, __uint32_t mode, errno_t *errno) {
*errno = -E_NOSUPP;
}
errno_t vga_creat(char *name, __uint32_t type, __uint32_t mode) {
return -E_NOSUPP;
}
errno_t vga_read(struct inode_desc *inode, char *buffer, __uint64_t l) {
return -E_HNOSUP;
}
void update_cursor(__uint32_t x, __uint32_t y) {
__uint16_t pos = y * TEXT_VGA_X + x;
outb(0x0f, 0x03d4);
outb((__uint8_t) (pos & 0xff), 0x03d5);
outb(0x0e, 0x03d4);
outb((__uint8_t) ((pos >> 8) & 0xff), 0x03d5);
return;
}
__uint16_t read_cursor(void) {
__uint16_t pos = 0;
outb(0x0f, 0x03d4);
pos |= inb(0x03d5);
outb(0x0e, 0x03d4);
pos |= ((__uint16_t) inb(0x03d5)) << 8;
return pos;
}
errno_t vga_fill(char *name, __uint32_t type, __uint32_t mode, struct vga_inode *inode) {
inode->inode.size = sizeof(struct vga_inode);
inode->inode.fd = next_fd;
inode->inode.off = 1 * TEXT_VGA_X + 0;
inode->fb = (__uint8_t *) 0xb8000;
inode->x = 0;
/* first line is in use */
inode->y = 1;
next_fd++;
update_cursor(0, 0);
return 0;
}
errno_t vga_write(struct vga_inode *inode, char *buffer, __uint64_t l) {
/* for safety, we re-calc offset */
inode->inode.off = (inode->y * TEXT_VGA_X + inode->x) * 2;
if (*buffer == '\n') {
/* we use LF to line feed, not CRLF in Windows */
inode->x = 0;
inode->y++;
update_cursor(inode->x, inode->y);
return 0;
}
if (*buffer == '\r') {
inode->x = 0;
update_cursor(inode->x, inode->y);
}
/* put it */
inode->fb[inode->inode.off] = *buffer;
/* color white */
inode->fb[inode->inode.off + 1] = 0x0f;
inode->inode.off += 2;
inode->x++;
if (inode->x == TEXT_VGA_X) {
inode->x = 0;
inode->y++;
}
update_cursor(inode->x, inode->y);
return 0;
}
errno_t vga_lseek(struct inode_desc *inode, __uint32_t off, __uint32_t seg) {
return -E_HNOSUP;
}
void vga_close(struct inode_desc *inode) {
/* disable cursor */
outb(0x3d4, 0x0a);
outb(0x3d5, 0x20);
return;
}
struct file_operations vga = INIT_MODULE(vga);
C_FLAGS = -mcmodel=large -fno-builtin -m64
C_FLAGS = -mcmodel=large -fno-builtin -m64 -I ../../include/
all: main.o
all: main.o print.o
%.o: %.c
gcc -c $*.c $(C_FLAGS)
clear:
rm *.o
......@@ -24,12 +24,17 @@
void init(void) {
unsigned long i;
#include <kernel/init.h>
#include <kernel/types.h>
#include <kernel/errno.h>
#include <kernel/vgatext.h>
#include <kernel/print.h>
for (i = 0xa0000; i < 0xaffff; i++) {
*((char *) i) = 0x0f;
}
void init(void) {
struct vga_inode vi;
vga.fill(NULL, 0, 0, &vi);
print(&vi, "kernel starting\n");
for (;;);
}
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#include <kernel/init.h>
#include <kernel/types.h>
#include <kernel/errno.h>
#include <kernel/vgatext.h>
errno_t print(struct vga_inode *inode, char *s) {
for (; *s; s++) {
vga.write(inode, s, 1);
}
return 0;
}
C_FLAGS = -mcmodel=large -m64 -fno-builtin -nostdlib -I ../../include/
all: bitmap.c bitman.c bitmap.o bitman.o
%.o: %.c
gcc -c $*.c $(C_FLAGS)
clear:
rm *.o
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#include <lib/rlib.h>
/*
find a new bit in bm->bitmap.
STEPS:
1. save free position.
2. find a new free position.
3. save new free position.
*/
unsigned int bitman_alloc(struct bitmap_manager *bm) {
unsigned int p = bm->next_free;
bitmap_set(bm->bitmap, bm->next_free, 1);
for (; bitmap_read(bm->bitmap, bm->next_free) == 1; bm->next_free++);
return p;
}
/*
free a bit.
STEPS:
1. free bit pos.
2. if pos is lowwer than bm->next_free
2a. set bm->next_free = pos.
*/
void bitman_free(struct bitmap_manager *bm, unsigned int pos) {
bitmap_set(bm->bitmap, pos, 0);
if (pos < bm->next_free) {
bm->next_free = pos;
}
return;
}
/* Copyright (C) 2021 Rain */
/* This file is part of Cunix. */
/*
Cunix is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) and later version.
*/
/*
Cunix is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
You should have received a copy of the GNU General Public License
along with Cunix. If not, see <https://www.gnu.org/licenses/>.
*/
#include <kernel/types.h>
void bitmap_set(unsigned char *bitmap, unsigned int pos, unsigned char value) {
unsigned char mask = 0x80 >> (pos & 0x7);
if (value) {
bitmap[pos >> 3] |= mask;
}
else {
bitmap[pos >> 3] &= ~mask;
}
}
char bitmap_read(unsigned char *bitmap, unsigned int pos) {
unsigned char mask = 0x80 >> (pos & 0x7);
return (mask & bitmap[pos >> 3]) == mask ? 1 : 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册