Skip to content

Commit

Permalink
[7]Finish advanced 1, use mbox_call get lba, and write color to it
Browse files Browse the repository at this point in the history
  • Loading branch information
JusticeLeee committed Jun 22, 2022
1 parent c6d9074 commit 9062675
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 26 deletions.
28 changes: 21 additions & 7 deletions lab7/kernel/include/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#define MAX_DEVICE_IN_DIR 16

typedef enum { DEV_ROOT, DEV_UART, DEV_NONE } DEV_TYPE;
typedef enum { DEV_ROOT, DEV_UART, DEV_NONE, DEV_FB } DEV_TYPE;

struct device_fentry {
char name[20];
Expand All @@ -18,6 +18,13 @@ struct device_fentry {
struct device_fentry* child[MAX_DEVICE_IN_DIR];
};

struct framebuffer_info {
unsigned int width;
unsigned int height;
unsigned int pitch;
unsigned int isrgb;
};

struct vnode_operations* device_v_ops;
struct file_operations* device_f_ops;

Expand All @@ -38,14 +45,21 @@ void device_list(struct vnode* dir);

void root_init();



/**********************************************/
/* uart file system */
/**********************************************/

struct vnode_operations* uartfs_v_ops;
struct file_operations* uartfs_f_ops;
void uartfs_init();
int uartfs_read(struct file* file, void* buf, size_t len);
int uartfs_write(struct file* file, const void* buf, size_t len);


struct vnode_operations* fb_v_ops;
struct file_operations* fb_f_ops;
void fb_init();
int fb_write(struct file* file, const void* buf, size_t len);


//framebuffer syscall
long lseek64(int fd, long offset, int whence);
int ioctl(int fd, unsigned long request, struct framebuffer_info* info );
unsigned char *lfb; /* raw frame buffer address */
unsigned int isrgb; /* dimensions and channel order */
131 changes: 124 additions & 7 deletions lab7/kernel/src/device.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

#include "uart.h"
#include "printf.h"
#include "gpio.h"
#include "device.h"
#include "vfs.h"
#include "alloc.h"
#include "string.h"

#include "thread.h"
#include "mbox.h"
/**********************************************/
/* uart file system */
/**********************************************/
Expand Down Expand Up @@ -35,14 +35,27 @@ void uartfs_init() {
// uartfs_f_ops->list = device_list;
}

void fb_init() {
fb_v_ops =
(struct vnode_operations*)malloc(sizeof(struct vnode_operations));
fb_v_ops->lookup = device_lookup;
fb_v_ops->create = device_create;
fb_v_ops->set_parent = device_set_parent;
fb_f_ops = (struct file_operations*)malloc(sizeof(struct file_operations));
fb_f_ops->write = fb_write;
// fb_f_ops->read = fb_read;
// uartfs_f_ops->list = device_list;
}

void device_init() {
root_init();
uartfs_init();
fb_init();
}

void device_set_fentry(struct device_fentry* fentry, const char* component_name,
struct vnode* vnode, DEV_TYPE type) {
printf("[device_set_fentry]\n");
// printf("[device_set_fentry]\n");
strcpy(fentry->name, component_name);
fentry->vnode = vnode;
fentry->type = type;
Expand Down Expand Up @@ -74,14 +87,16 @@ int device_setup_mount(struct filesystem* fs, struct mount* mount) {

// create device vnode
_device_create(mount->root, "uart", DEV_UART);
// create frame buffer
_device_create(mount->root, "framebuffer", DEV_FB);

return 1;
}

int device_lookup(struct vnode* dir_node, struct vnode** target,
const char* component_name) {

printf("[device_lookup] %s\n", component_name);
// printf("[device_lookup] %s\n", component_name);
struct device_fentry* fentry = (struct device_fentry*)dir_node->internal;
if (fentry->type != DEV_ROOT) return 0;

Expand All @@ -99,7 +114,7 @@ int device_lookup(struct vnode* dir_node, struct vnode** target,

for (int i = 0; i < MAX_DEVICE_IN_DIR; i++) {
fentry = ((struct device_fentry*)dir_node->internal)->child[i];
printf("[device_lookup] %s\n", fentry->name);
// printf("[device_lookup] %s\n", fentry->name);
if (!strcmp(fentry->name, component_name)) {
*target = fentry->vnode;
return 1;
Expand All @@ -125,6 +140,13 @@ int _device_create(struct vnode* dir_node,
device_set_fentry(fentry, component_name, vnode, type);
return 1;
}
else if(type == DEV_FB){
vnode->v_ops = fb_v_ops;
vnode->f_ops = fb_f_ops;
vnode->internal = fentry;
device_set_fentry(fentry, component_name, vnode, type);
return 1;
}
}
}
return -1;
Expand Down Expand Up @@ -165,8 +187,6 @@ int device_read(struct file* file, void* buf, size_t len) {
return -1;
}



// uart read write functions

int uartfs_read(struct file* file, void* buf, size_t len) {
Expand All @@ -187,3 +207,100 @@ int uartfs_write(struct file* file, const void* buf, size_t len) {
}
return len;
}

int fb_write(struct file* file, const void* buf, size_t len) {
// printf("[fb_write]\n");
// write to lfb
// printf("file->f_pos = %d\n",file->f_pos);
// for(int i = 0; i < len; i++) printf("0x%x, ", ((char* )buf)[i]);
// printf("\n");
if(isrgb){ //RGB
lfb[file->f_pos++] = ((char* )buf)[0];
lfb[file->f_pos++] = ((char* )buf)[1];
lfb[file->f_pos++] = ((char* )buf)[2];

lfb[file->f_pos++] = ((char* )buf)[3];
}
else{ //BGR
lfb[file->f_pos++] = ((char* )buf)[2];
lfb[file->f_pos++] = ((char* )buf)[1];
lfb[file->f_pos++] = ((char* )buf)[0];

lfb[file->f_pos++] = ((char* )buf)[3]; // 0x0
}

return len;
}

long lseek64(int fd, long offset, int whence){
struct file* file = thread_get_file(fd);
file->f_pos = offset + whence;
return file->f_pos;
}

int ioctl(int fd, unsigned long request, struct framebuffer_info * info){
#define MBOX_REQUEST 0
#define MBOX_CH_PROP 8
#define MBOX_TAG_LAST 0
unsigned int __attribute__((aligned(16))) mbox[36];
unsigned int width, height, pitch; /* dimensions and channel order */

mbox[0] = 35 * 4;
mbox[1] = MBOX_REQUEST;

mbox[2] = 0x48003; // set phy wh
mbox[3] = 8;
mbox[4] = 8;
mbox[5] = 1024; // FrameBufferInfo.width
mbox[6] = 768; // FrameBufferInfo.height

mbox[7] = 0x48004; // set virt wh
mbox[8] = 8;
mbox[9] = 8;
mbox[10] = 1024; // FrameBufferInfo.virtual_width
mbox[11] = 768; // FrameBufferInfo.virtual_height

mbox[12] = 0x48009; // set virt offset
mbox[13] = 8;
mbox[14] = 8;
mbox[15] = 0; // FrameBufferInfo.x_offset
mbox[16] = 0; // FrameBufferInfo.y.offset

mbox[17] = 0x48005; // set depth
mbox[18] = 4;
mbox[19] = 4;
mbox[20] = 32; // FrameBufferInfo.depth

mbox[21] = 0x48006; // set pixel order
mbox[22] = 4;
mbox[23] = 4;
mbox[24] = 1; // RGB, not BGR preferably

mbox[25] = 0x40001; // get framebuffer, gets alignment on request
mbox[26] = 8;
mbox[27] = 8;
mbox[28] = 4096; // FrameBufferInfo.pointer
mbox[29] = 0; // FrameBufferInfo.size

mbox[30] = 0x40008; // get pitch
mbox[31] = 4;
mbox[32] = 4;
mbox[33] = 0; // FrameBufferInfo.pitch

mbox[34] = MBOX_TAG_LAST;

// this might not return exactly what we asked for, could be
// the closest supported resolution instead
if (mbox_call(MBOX_CH_PROP, mbox) && mbox[20] == 32 && mbox[28] != 0) {
mbox[28] &= 0x3FFFFFFF; // convert GPU address to ARM address
width = mbox[5]; // get actual physical width
height = mbox[6]; // get actual physical height
pitch = mbox[33]; // get number of bytes per line
isrgb = mbox[24]; // get the actual channel order
lfb = (void *)((unsigned long)mbox[28]);
printf("width =%d, height =%d, pitch =%d, isrgb =%d\n", width, height, pitch, isrgb);
} else {
printf("Unable to set screen resolution to 1024x768x32\n");
}
return 1;
}
24 changes: 18 additions & 6 deletions lab7/kernel/src/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "printf.h"
#include "mbox.h"
#include "vfs.h"
#include "device.h"

int count = 0;

Expand Down Expand Up @@ -68,7 +69,7 @@ void sync_handler_lowerEL_64(uint64_t sp) {
} else if (iss == 5) { // exit
exit();
} else if (iss == 6) { // mbox_call
// printf("[mbox_call]\n");
printf("\n\n\n[mbox_call]\n");
trap_frame->x[0] = mbox_call(trap_frame->x[0],(unsigned int *)trap_frame->x[1]);
} else if (iss == 7) { // kill
kill((int)trap_frame->x[0]);
Expand All @@ -77,7 +78,7 @@ void sync_handler_lowerEL_64(uint64_t sp) {
printf("[open]%s\n",(const char *)trap_frame->x[0]);
struct file* file = vfs_open((const char *)trap_frame->x[0],trap_frame->x[1]);
int fd = thread_register_fd(file);
printf("[open]fd :%d\n",(const char *)trap_frame->x[0]);
printf("[open]fd :%d\n",fd);

trap_frame->x[0] = fd;

Expand All @@ -88,10 +89,10 @@ void sync_handler_lowerEL_64(uint64_t sp) {

} else if (iss == 13) { // write
// remember to return read size or error code
printf("[write]\n");
printf("[write]fd =%d\n",trap_frame->x[0]);
printf("[write]write_buf =%s\n",trap_frame->x[1]);
printf("[write]size =%d\n",trap_frame->x[2]);
// printf("[write]\n");
// printf("[write]fd =%d\n",trap_frame->x[0]);
// printf("[write]write_buf =%s\n",trap_frame->x[1]);
// printf("[write]size =%d\n",trap_frame->x[2]);
struct file* file = thread_get_file(trap_frame->x[0]);
trap_frame->x[0] = vfs_write(file, (const void *)trap_frame->x[1], trap_frame->x[2]);

Expand Down Expand Up @@ -127,6 +128,17 @@ void sync_handler_lowerEL_64(uint64_t sp) {

int result = vfs_chdir(pathname);
trap_frame->x[0] = result;
} else if (iss == 18) { // lseek64
// printf("[lseek64]\n");
// printf("[lseek64]fd = %d\n", trap_frame->x[0]);
// printf("[lseek64]offset = %ld\n", (long) trap_frame->x[1]);
// printf("[lseek64]whence = %d\n", trap_frame->x[2]);
trap_frame->x[0] = lseek64(trap_frame->x[0], trap_frame->x[1], trap_frame->x[2]);
} else if (iss == 19) { // ioctl
printf("[ioctl]\n");
printf("[ioctl]fd = %d\n", trap_frame->x[0]);
printf("[ioctl]request = %ld\n", (long) trap_frame->x[1]);
trap_frame->x[0] = ioctl(trap_frame->x[0], trap_frame->x[1], (struct framebuffer_info*)trap_frame->x[2]);
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions lab7/kernel/src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ void thread_init() {
run_queue.head = 0;
run_queue.tail = 0;
thread_cnt = 0;

stdin = vfs_open("/dev/uart", 0);
stdout = vfs_open("/dev/uart", 0);
stderr = vfs_open("/dev/uart", 0);
}

thread_info *thread_create(void (*func)()) {
Expand Down
7 changes: 5 additions & 2 deletions lab7/kernel/src/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void vfs_init() {
}
fs->setup_mount(fs, rootfs);
current_dir = rootfs->root;
cpio_populate_rootfs();
// cpio_populate_rootfs();

// init and register cpio
cpiofs_init();
Expand All @@ -78,7 +78,10 @@ void vfs_init() {

vfs_mkdir("/dev");
vfs_mount("", "/dev", "dev");

// uart
stdin = vfs_open("/dev/uart", 0);
stdout = vfs_open("/dev/uart", 0);
stderr = vfs_open("/dev/uart", 0);
}

int register_filesystem(struct filesystem* fs) {
Expand Down

0 comments on commit 9062675

Please sign in to comment.