working on exposing vga to userspace
This commit is contained in:
@@ -48,6 +48,9 @@ static uint32_t cpio_read(struct vfs_node* node, uint32_t offset, uint32_t size,
|
||||
}
|
||||
|
||||
static vfs_node_t* cpio_find_or_create(vfs_node_t* root_node, const char* path) {
|
||||
if (strcmp(path, "fonts") == 0) {
|
||||
kprintf("found fonts folder\n");
|
||||
}
|
||||
vfs_node_t* current = root_node;
|
||||
|
||||
char path_cpy[256];
|
||||
|
||||
@@ -9,6 +9,7 @@ int is_transmit_empty() {
|
||||
|
||||
void write_serial(char a) {
|
||||
while (is_transmit_empty() == 0);
|
||||
if (a == '\n') outb(COM1, '\r');
|
||||
outb(COM1, a);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "vfs.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -9,6 +10,8 @@
|
||||
#include <common.h>
|
||||
#include <memory/mm.h>
|
||||
|
||||
#include <user/video.h>
|
||||
|
||||
static uint32_t framebuffer_address;
|
||||
static uint32_t framebuffer_width;
|
||||
static uint32_t framebuffer_height;
|
||||
@@ -34,36 +37,45 @@ vga_color_t VGA_COLOR_RED = {0, 0, 255, 255};
|
||||
vga_color_t VGA_COLOR_GREEN = {0, 255, 0, 255};
|
||||
vga_color_t VGA_COLOR_BLUE = {255, 0, 0, 255};
|
||||
|
||||
|
||||
uint32_t vga_mmap(vfs_node_t* node, uint32_t address) {
|
||||
uint32_t fb_size_bytes = framebuffer_height * framebuffer_pitch;
|
||||
uint32_t num_pages = (fb_size_bytes + 4095) / 4096;
|
||||
for (uint32_t i = 0; i < num_pages; i++) {
|
||||
uint32_t phys_addr = framebuffer_address + (i * 4096);
|
||||
uint32_t virt_addr = address + (i * 4096);
|
||||
map_page(virt_addr, phys_addr, PAGE_PRESENT | PAGE_WRITABLE);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
uint32_t vga_ioctl(vfs_node_t* node, uint32_t request, void* arg) {
|
||||
if (request == FBIOGET_INFO) {
|
||||
fb_info_t* info = (fb_info_t*)arg;
|
||||
info->width = framebuffer_width;
|
||||
info->height = framebuffer_height;
|
||||
info->pitch = framebuffer_pitch;
|
||||
info->fb_size = framebuffer_total_pixels;
|
||||
info->bpp = framebuffer_bpp;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vga_init(
|
||||
vfs_node_t* dev,
|
||||
uint32_t fb_paddr,
|
||||
uint32_t fb_width,
|
||||
uint32_t fb_height,
|
||||
uint32_t fb_pitch,
|
||||
uint8_t fb_bpp,
|
||||
uint8_t _red_mask_sz,
|
||||
uint8_t _red_field_pos,
|
||||
uint8_t _green_mask_sz,
|
||||
uint8_t _green_field_pos,
|
||||
uint8_t _blue_mask_sz,
|
||||
uint8_t _blue_field_pos
|
||||
uint8_t fb_bpp
|
||||
) {
|
||||
framebuffer_address = VGA_FRAMEBUFFER;
|
||||
|
||||
red_mask_sz = _red_mask_sz;
|
||||
red_field_pos = _red_field_pos;
|
||||
green_mask_sz = _green_mask_sz;
|
||||
green_field_pos = _green_field_pos;
|
||||
blue_mask_sz = _blue_mask_sz;
|
||||
blue_field_pos = _blue_field_pos;
|
||||
|
||||
print_serial("initializing vga.\r\n");
|
||||
print_serial_hex(fb_paddr);
|
||||
print_serial("\r\n");
|
||||
print_serial_hex(framebuffer_address);
|
||||
print_serial("\r\n");
|
||||
print_serial("BPP: ");
|
||||
print_serial_hex(fb_bpp);
|
||||
print_serial("\r\n");
|
||||
framebuffer_address = fb_paddr;
|
||||
framebuffer_width = fb_width;
|
||||
framebuffer_height = fb_height;
|
||||
framebuffer_total_pixels = framebuffer_width * framebuffer_height;
|
||||
framebuffer_pitch = fb_pitch;
|
||||
framebuffer_bpp = fb_bpp;
|
||||
|
||||
uint32_t fb_size_bytes = fb_height * fb_pitch;
|
||||
uint32_t num_pages = (fb_size_bytes + 4095) / 4096;
|
||||
@@ -73,18 +85,15 @@ void vga_init(
|
||||
map_page(virt_addr, phys_addr, PAGE_PRESENT | PAGE_WRITABLE);
|
||||
}
|
||||
|
||||
framebuffer_width = fb_width;
|
||||
framebuffer_height = fb_height;
|
||||
framebuffer_total_pixels = framebuffer_width * framebuffer_height;
|
||||
|
||||
framebuffer_pitch = fb_pitch;
|
||||
framebuffer_bpp = fb_bpp;
|
||||
|
||||
vga_clear_scrn(0x00000000);
|
||||
|
||||
dev->flags = VFS_CHARDEVICE;
|
||||
dev->mmap = vga_mmap;
|
||||
dev->ioctl = vga_ioctl;
|
||||
}
|
||||
|
||||
uint32_t vga_get_framebuffer() {
|
||||
return framebuffer_address;
|
||||
return VGA_FRAMEBUFFER;
|
||||
}
|
||||
|
||||
uint32_t vga_get_width() {
|
||||
@@ -124,25 +133,3 @@ void vga_clear_scrn(uint32_t color) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf) {
|
||||
return size;
|
||||
}
|
||||
|
||||
void test_draw_vertical_line(uint32_t x, uint32_t y_start, uint32_t y_end, uint32_t color) {
|
||||
if (framebuffer_address == 0) return;
|
||||
|
||||
uint8_t* fb_bytes = (uint8_t*)framebuffer_address;
|
||||
|
||||
for (uint32_t y = y_start; y < y_end; y++) {
|
||||
if (y >= framebuffer_height) break;
|
||||
|
||||
uint8_t* row = fb_bytes + (y * framebuffer_pitch);
|
||||
|
||||
uint32_t* pixel_row = (uint32_t*)row;
|
||||
|
||||
if (x < framebuffer_width) {
|
||||
pixel_row[x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,19 +17,15 @@ extern vga_color_t VGA_COLOR_BLACK;
|
||||
extern vga_color_t VGA_COLOR_RED;
|
||||
extern vga_color_t VGA_COLOR_GREEN;
|
||||
extern vga_color_t VGA_COLOR_BLUE;
|
||||
extern vga_color_t VGA_COLOR_ROCKOS;
|
||||
|
||||
void vga_init(
|
||||
vfs_node_t* dev,
|
||||
uint32_t fb_paddr,
|
||||
uint32_t fb_width,
|
||||
uint32_t fb_height,
|
||||
uint32_t fb_pitch,
|
||||
uint8_t fb_bpp,
|
||||
uint8_t red_mask_sz,
|
||||
uint8_t red_field_pos,
|
||||
uint8_t green_mask_sz,
|
||||
uint8_t green_field_pos,
|
||||
uint8_t blue_mask_sz,
|
||||
uint8_t blue_field_pos
|
||||
uint8_t fb_bpp
|
||||
);
|
||||
|
||||
uint32_t vga_get_framebuffer();
|
||||
@@ -42,6 +38,4 @@ void vga_clear_scrn(uint32_t color);
|
||||
|
||||
uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf);
|
||||
|
||||
void test_draw_vertical_line(uint32_t x, uint32_t y_start, uint32_t y_end, uint32_t color);
|
||||
|
||||
#endif
|
||||
@@ -125,26 +125,9 @@ void kmain(multiboot_info* mbi) {
|
||||
init_pmm((void*)mmap_virtual_addr, mbi->mmap_length);
|
||||
init_page_tables();
|
||||
|
||||
vga_init(vga_fb_address,
|
||||
vga_fb_width,
|
||||
vga_fb_height,
|
||||
vga_fb_pitch,
|
||||
vga_fb_bpp,
|
||||
0, 0, 0, 0, 0, 0);
|
||||
|
||||
console_init();
|
||||
|
||||
int font_loaded = set_console_font("/fonts/cp850-8x16.psf");
|
||||
if (!font_loaded) {
|
||||
#ifdef SERIAL_DBG
|
||||
print_serial("failed to load console font");
|
||||
#endif
|
||||
}
|
||||
|
||||
test_draw_vertical_line(100, 100, 150, 0xFFFFFFFF);
|
||||
return;
|
||||
|
||||
kprintf("basic initializations complete\n");
|
||||
disable_interrupts();
|
||||
init_scheduler();
|
||||
enable_interrupts();
|
||||
|
||||
vfs_node_t* vfs_root = vfs_create_root();
|
||||
vfs_node_t* initrd_root = load_initrd();
|
||||
@@ -162,22 +145,40 @@ void kmain(multiboot_info* mbi) {
|
||||
return;
|
||||
}
|
||||
|
||||
vfs_node_t* vga_dev = devfs->create(devfs, "tvga");
|
||||
vga_dev->write = vga_write;
|
||||
|
||||
vfs_node_t* kbd_dev = devfs->create(devfs, "kbd");
|
||||
kbd_dev->read = kbd_read;
|
||||
|
||||
vfs_node_t* vga_dev = devfs->create(devfs, "vga");
|
||||
vga_init(vga_dev,
|
||||
vga_fb_address,
|
||||
vga_fb_width,
|
||||
vga_fb_height,
|
||||
vga_fb_pitch,
|
||||
vga_fb_bpp);
|
||||
|
||||
kprintf("vga initialized\n");
|
||||
|
||||
vfs_node_t* dev = vfs_find("/dev");
|
||||
if (dev) {
|
||||
dev->mnt = devfs;
|
||||
if (!dev) {
|
||||
kprintf("failed to find dev mnt point\n");
|
||||
return;
|
||||
}
|
||||
|
||||
disable_interrupts();
|
||||
init_scheduler();
|
||||
enable_interrupts();
|
||||
dev->mnt = devfs;
|
||||
kprintf("mounted devfs\n");
|
||||
|
||||
console_init();
|
||||
kprintf("kernel console initialized\n");
|
||||
|
||||
kprintf("loading terminal program\n");
|
||||
int font_loaded = set_console_font("/fonts/kernel_font.psf");
|
||||
if (!font_loaded) {
|
||||
kprintf("failed to load console font\n");
|
||||
}
|
||||
|
||||
kprintf("console font set\n");
|
||||
kprintf("basic initializations complete. check serial for details\n");
|
||||
|
||||
kprintf("starting rockos\n");
|
||||
load_root_program("/bin/vga_text_term.elf");
|
||||
|
||||
kprintf("kernel going to sleep...\n");
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "drivers/serial/serial.h"
|
||||
|
||||
#include <lib/console.h>
|
||||
#include <lib/font.h>
|
||||
#include <lib/print.h>
|
||||
|
||||
#include <drivers/vga/vga.h>
|
||||
|
||||
@@ -7,10 +10,13 @@ static psf_font_t* font;
|
||||
|
||||
static uint32_t console_row;
|
||||
static uint32_t console_col;
|
||||
static uint32_t console_width;
|
||||
static uint32_t console_height;
|
||||
static uint32_t console_text_color;
|
||||
static uint32_t console_backgrnd_color;
|
||||
|
||||
static void write_vga_char(char c) {
|
||||
print_serial("write_vga_char invoked\r\n");
|
||||
uint32_t vga_pitch = vga_get_pitch();
|
||||
uint8_t* glyph = (uint8_t*)font->glyphs + (c * font->hdr->charsz);
|
||||
|
||||
@@ -34,7 +40,14 @@ static void write_vga_char(char c) {
|
||||
|
||||
int set_console_font(const char* path) {
|
||||
font = load_font(path);
|
||||
return font != NULL;
|
||||
if (!font) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
console_width = vga_get_width() / 8;
|
||||
console_height = vga_get_height() / font->hdr->charsz;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void set_console_fg(uint32_t color) {
|
||||
@@ -48,10 +61,35 @@ void set_console_bg(uint32_t color) {
|
||||
void console_init() {
|
||||
console_row = 0;
|
||||
console_col = 0;
|
||||
|
||||
set_console_fg(0xFFFFFFFF);
|
||||
vga_clear_scrn(0x000000FF);
|
||||
set_console_bg(0xFF6c7482);
|
||||
vga_clear_scrn(console_backgrnd_color);
|
||||
}
|
||||
|
||||
void console_putchar(char c) {
|
||||
if (!font) return;
|
||||
|
||||
if (c == '\n') {
|
||||
print_serial("\r\n");
|
||||
console_col = 0;
|
||||
console_row++;
|
||||
if (console_row >= console_height) {
|
||||
console_row = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
write_serial(c);
|
||||
write_vga_char(c);
|
||||
|
||||
console_col++;
|
||||
if (console_col >= console_width) {
|
||||
console_col = 0;
|
||||
console_row++;
|
||||
}
|
||||
|
||||
if (console_row >= console_height) {
|
||||
console_row = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,22 @@
|
||||
#include "drivers/serial/serial.h"
|
||||
#include "vfs.h"
|
||||
#include <lib/font.h>
|
||||
#include <lib/memory.h>
|
||||
#include <lib/print.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
psf_font_t* load_font(const char* path) {
|
||||
int fd = vfs_open(path, 0);
|
||||
if (fd == -1) {
|
||||
kprintf("failed to open font file %s\n", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
psf_hdr_t* header = kalloc(sizeof(psf_hdr_t));
|
||||
int rd = vfs_read(fd, header, sizeof(psf_hdr_t));
|
||||
if (rd <= 0) {
|
||||
kprintf("failed to read font header\n");
|
||||
kfree(header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "print.h"
|
||||
#include "drivers/serial/serial.h"
|
||||
#include "stream.h"
|
||||
#include "tasks.h"
|
||||
|
||||
@@ -13,16 +14,21 @@ extern psf_font_t* kfont;
|
||||
|
||||
static char* hex_chars = "0123456789abcdef";
|
||||
|
||||
static void kwrite(char c) {
|
||||
write_serial(c);
|
||||
console_putchar(c);
|
||||
}
|
||||
|
||||
static void kprint(const char *str) {
|
||||
while (*str) {
|
||||
console_putchar(*str);
|
||||
kwrite(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
static void kputd(int d) {
|
||||
if (d == 0) {
|
||||
console_putchar('0');
|
||||
kwrite('0');
|
||||
return;
|
||||
}
|
||||
char buffer[12];
|
||||
@@ -32,13 +38,13 @@ static void kputd(int d) {
|
||||
d /= 10;
|
||||
}
|
||||
for (int j = i - 1; j >= 0; j--) {
|
||||
console_putchar(buffer[j]);
|
||||
kwrite(buffer[j]);
|
||||
}
|
||||
}
|
||||
|
||||
static void kputx(unsigned int x) {
|
||||
if (x == 0) {
|
||||
console_putchar('0');
|
||||
kwrite('0');
|
||||
return;
|
||||
}
|
||||
char buffer[8];
|
||||
@@ -49,13 +55,13 @@ static void kputx(unsigned int x) {
|
||||
x >>= 4;
|
||||
}
|
||||
for (int j = i - 1; j >= 0; j--) {
|
||||
console_putchar(buffer[j]);
|
||||
kwrite(buffer[j]);
|
||||
}
|
||||
}
|
||||
|
||||
void kputc(const char c) {
|
||||
spin_lock(&kwrite_lock);
|
||||
console_putchar(c);
|
||||
kwrite(c);
|
||||
spin_unlock(&kwrite_lock);
|
||||
}
|
||||
|
||||
@@ -85,20 +91,20 @@ void kprintf(const char* fmt, ...) {
|
||||
}
|
||||
case 'c': {
|
||||
int c = va_arg(args, int);
|
||||
console_putchar((char)c);
|
||||
kwrite((char)c);
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
console_putchar('%');
|
||||
kwrite('%');
|
||||
break;
|
||||
default:
|
||||
console_putchar('%');
|
||||
console_putchar(*fmt);
|
||||
kwrite('%');
|
||||
kwrite(*fmt);
|
||||
break;
|
||||
}
|
||||
fmt++;
|
||||
} else {
|
||||
console_putchar(*fmt);
|
||||
kwrite(*fmt);
|
||||
fmt++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +240,39 @@ static int32_t sys_waitpid(int pid, int* exit_status) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int32_t sys_mmap(int fd) {
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
process_t* current = current_task();
|
||||
if (!current) return 0;
|
||||
|
||||
file_t* file = current->fd_table[fd];
|
||||
if (!file) return 0;
|
||||
|
||||
if (!(file->node->flags & VFS_CHARDEVICE)) return 0;
|
||||
|
||||
uint32_t map_vaddr = 0x3FF00000;
|
||||
return file->node->mmap(file->node, map_vaddr);
|
||||
}
|
||||
|
||||
static int32_t sys_ioctl(int fd, uint32_t request, void* args) {
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
process_t* current = current_task();
|
||||
if (!current) return 0;
|
||||
|
||||
file_t* file = current->fd_table[fd];
|
||||
if (!file) return 0;
|
||||
|
||||
if (!file->node->ioctl) return 0;
|
||||
|
||||
return file->node->ioctl(file->node, request, args);
|
||||
}
|
||||
|
||||
void syscall(registers_t* regs) {
|
||||
int32_t ret;
|
||||
switch(regs->eax) {
|
||||
@@ -256,6 +289,8 @@ void syscall(registers_t* regs) {
|
||||
case 23: ret = sys_dup2(regs->ebx, regs->ecx); break;
|
||||
case 24: ret = sys_lseek(regs->ebx, regs->ecx, regs->edx); break;
|
||||
case 25: ret = sys_waitpid(regs->ebx, (int*)regs->ecx); break;
|
||||
case 26: ret = sys_mmap(regs->ebx); break;
|
||||
case 27: ret = sys_ioctl(regs->ebx, regs->ecx, (void*)regs->edx); break;
|
||||
default: ret = -1;
|
||||
}
|
||||
regs->eax = ret;
|
||||
|
||||
17
kernel/user/video.h
Normal file
17
kernel/user/video.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef USER_VIDEO_H
|
||||
#define USER_VIDEO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FBIOGET_INFO 0x1
|
||||
|
||||
typedef struct {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pitch;
|
||||
uint32_t bpp;
|
||||
uint32_t fb_size;
|
||||
} fb_info_t;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,9 @@ 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 (*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 uint32_t (*mmap_type_t)(struct vfs_node* node, uint32_t address);
|
||||
typedef uint32_t (*ioctl_type_t)(struct vfs_node* node, uint32_t request, void* arg);
|
||||
|
||||
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* (*create_type_t)(struct vfs_node* node, const char* name);
|
||||
@@ -33,6 +36,8 @@ typedef struct vfs_node {
|
||||
mkdir_type_t mkdir;
|
||||
create_type_t create;
|
||||
seek_type_t seek;
|
||||
mmap_type_t mmap;
|
||||
ioctl_type_t ioctl;
|
||||
|
||||
struct vfs_node* mnt;
|
||||
void* data;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "syscall.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/video.h>
|
||||
|
||||
#define VGA_TEXT_W 80
|
||||
#define VGA_TEXT_H 25
|
||||
|
||||
@@ -8,6 +11,16 @@ void term();
|
||||
int ptys;
|
||||
int ptym;
|
||||
|
||||
fb_info_t fb_info;
|
||||
void* framebuffer_address;
|
||||
|
||||
int terminal_col = 0;
|
||||
int terminal_row = 0;
|
||||
|
||||
void term_write_char(char c) {
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
@@ -28,42 +41,20 @@ int main(int argc, char *argv[]) {
|
||||
dup2(0, 1);
|
||||
dup2(0, 2);
|
||||
|
||||
term();
|
||||
|
||||
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() {
|
||||
int vga_fd = open("/dev/tvga");
|
||||
if (vga_fd == -1) return;
|
||||
int vga_fd = open("/dev/vga");
|
||||
if (vga_fd == -1) return 1;
|
||||
|
||||
int kbd_fd = open("/dev/kbd");
|
||||
if (kbd_fd == -1) return;
|
||||
if (kbd_fd == -1) return 1;
|
||||
|
||||
clear(vga_fd);
|
||||
|
||||
char c;
|
||||
while (1) {
|
||||
// first, get shell output
|
||||
int rd = read(0, &c, 1);
|
||||
if (rd > 0) {
|
||||
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);
|
||||
}
|
||||
int res = ioctl(vga_fd, FBIOGET_INFO, &fb_info);
|
||||
if (!res) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
framebuffer_address = mmap(vga_fd);
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
16
rocklibc/include/sys/video.h
Normal file
16
rocklibc/include/sys/video.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef USER_VIDEO_H
|
||||
#define USER_VIDEO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FBIOGET_INFO 0x1
|
||||
|
||||
typedef struct {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pitch;
|
||||
uint32_t bpp;
|
||||
uint32_t fb_size;
|
||||
} fb_info_t;
|
||||
|
||||
#endif
|
||||
@@ -17,6 +17,8 @@
|
||||
#define SYS_DUP2 23
|
||||
#define SYS_LSEEK 24
|
||||
#define SYS_WAIT 25
|
||||
#define SYS_MMAP 26
|
||||
#define SYS_IOCTL 27
|
||||
|
||||
int open(const char* path);
|
||||
int write(int fd, const void *buf, size_t count);
|
||||
@@ -25,6 +27,8 @@ int close(int fd);
|
||||
|
||||
int lseek(int fd, size_t offset, int whence);
|
||||
|
||||
void* mmap(int fd);
|
||||
|
||||
void exit(int status) __attribute__((noreturn));
|
||||
|
||||
void* sbrk(int32_t increment);
|
||||
@@ -37,4 +41,6 @@ int exec(const char* path);
|
||||
int dup2(int src, int dst);
|
||||
int waitpid(int pid, int* status);
|
||||
|
||||
int ioctl(int fd, uint32_t request, void* arg);
|
||||
|
||||
#endif
|
||||
@@ -73,4 +73,12 @@ void* sbrk(int32_t increment) {
|
||||
|
||||
int brk(void *addr) {
|
||||
return syscall1(SYS_BRK, (uint32_t)addr);
|
||||
}
|
||||
|
||||
void* mmap(int fd) {
|
||||
return (void*)syscall1(SYS_MMAP, fd);
|
||||
}
|
||||
|
||||
int ioctl(int fd, uint32_t request, void* arg) {
|
||||
return syscall3(SYS_IOCTL, fd, request, arg);
|
||||
}
|
||||
Reference in New Issue
Block a user