From 5aa4387923e615cc10d3c16a2b9224cfdd736a98 Mon Sep 17 00:00:00 2001 From: ChenZhenHua Date: Thu, 10 Jun 2021 09:20:48 +0800 Subject: [PATCH 1/3] clean folder --- kernel/Makefile | 2 +- kernel/command.c | 8 ++++---- kernel/{ => exception}/exception.c | 4 ++-- kernel/{ => exception}/exception.h | 2 +- kernel/{ => exception}/time.c | 4 ++-- kernel/{ => exception}/time.h | 0 kernel/fs/fat32.c | 0 kernel/fs/fat32.h | 0 kernel/{ => fs}/tmpfs.c | 6 +++--- kernel/{ => fs}/tmpfs.h | 0 kernel/{ => fs}/vfs.c | 8 ++++---- kernel/{ => fs}/vfs.h | 2 +- kernel/{ => mm}/allocator.c | 8 ++++---- kernel/{ => mm}/allocator.h | 0 kernel/{reader.c => mm/cpio.c} | 14 +++++++------- kernel/{reader.h => mm/cpio.h} | 6 ++++-- kernel/{ => process}/fd.c | 0 kernel/{ => process}/fd.h | 2 +- kernel/{ => process}/process.c | 8 ++++---- kernel/{ => process}/process.h | 2 +- kernel/{ => process}/thread.c | 6 +++--- kernel/{ => process}/thread.h | 2 +- 22 files changed, 43 insertions(+), 41 deletions(-) rename kernel/{ => exception}/exception.c (97%) rename kernel/{ => exception}/exception.h (84%) rename kernel/{ => exception}/time.c (87%) rename kernel/{ => exception}/time.h (100%) create mode 100644 kernel/fs/fat32.c create mode 100644 kernel/fs/fat32.h rename kernel/{ => fs}/tmpfs.c (97%) rename kernel/{ => fs}/tmpfs.h (100%) rename kernel/{ => fs}/vfs.c (93%) rename kernel/{ => fs}/vfs.h (97%) rename kernel/{ => mm}/allocator.c (99%) rename kernel/{ => mm}/allocator.h (100%) rename kernel/{reader.c => mm/cpio.c} (97%) rename kernel/{reader.h => mm/cpio.h} (94%) rename kernel/{ => process}/fd.c (100%) rename kernel/{ => process}/fd.h (92%) rename kernel/{ => process}/process.c (92%) rename kernel/{ => process}/process.h (94%) rename kernel/{ => process}/thread.c (98%) rename kernel/{ => process}/thread.h (97%) diff --git a/kernel/Makefile b/kernel/Makefile index 95481e98a..6dfb908f8 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -23,7 +23,7 @@ # # -SRCS = $(wildcard *.c) $(wildcard ../lib/*.c) +SRCS = $(wildcard *.c) $(wildcard exception/*.c) $(wildcard fs/*.c) $(wildcard mm/*.c) $(wildcard process/*.c) $(wildcard ../lib/*.c) OBJS = $(SRCS:.c=.o) CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles CC = aarch64-linux-gnu-gcc diff --git a/kernel/command.c b/kernel/command.c index cc5510425..aeedcabe8 100644 --- a/kernel/command.c +++ b/kernel/command.c @@ -1,8 +1,8 @@ #include "command.h" -#include "thread.h" -#include "reader.h" -#include "allocator.h" -#include "vfs.h" +#include "process/thread.h" +#include "mm/cpio.h" +#include "mm/allocator.h" +#include "fs/vfs.h" #include "../lib/uart.h" #include "../lib/string.h" diff --git a/kernel/exception.c b/kernel/exception/exception.c similarity index 97% rename from kernel/exception.c rename to kernel/exception/exception.c index a53347673..1974075e3 100644 --- a/kernel/exception.c +++ b/kernel/exception/exception.c @@ -1,7 +1,7 @@ #include "exception.h" -#include "process.h" #include "time.h" -#include "../lib/uart.h" +#include "../process/process.h" +#include "../../lib/uart.h" void log_state() { diff --git a/kernel/exception.h b/kernel/exception/exception.h similarity index 84% rename from kernel/exception.h rename to kernel/exception/exception.h index 4e460002a..50737edcc 100644 --- a/kernel/exception.h +++ b/kernel/exception/exception.h @@ -1,7 +1,7 @@ #ifndef EXCEPTION_H #define EXCEPTION_H -#include "thread.h" +#include "../process/thread.h" void log_state(); diff --git a/kernel/time.c b/kernel/exception/time.c similarity index 87% rename from kernel/time.c rename to kernel/exception/time.c index 5d05f31b3..9a1f1b263 100644 --- a/kernel/time.c +++ b/kernel/exception/time.c @@ -1,6 +1,6 @@ #include "time.h" -#include "../lib/uart.h" -#include "../lib/string.h" +#include "../../lib/uart.h" +#include "../../lib/string.h" void timer_handler() { diff --git a/kernel/time.h b/kernel/exception/time.h similarity index 100% rename from kernel/time.h rename to kernel/exception/time.h diff --git a/kernel/fs/fat32.c b/kernel/fs/fat32.c new file mode 100644 index 000000000..e69de29bb diff --git a/kernel/fs/fat32.h b/kernel/fs/fat32.h new file mode 100644 index 000000000..e69de29bb diff --git a/kernel/tmpfs.c b/kernel/fs/tmpfs.c similarity index 97% rename from kernel/tmpfs.c rename to kernel/fs/tmpfs.c index 56209da21..63cdd1aad 100644 --- a/kernel/tmpfs.c +++ b/kernel/fs/tmpfs.c @@ -1,7 +1,7 @@ #include "tmpfs.h" -#include "allocator.h" -#include "../lib/string.h" -#include "../lib/uart.h" +#include "../mm/allocator.h" +#include "../../lib/string.h" +#include "../../lib/uart.h" struct filesystem tmpfs = { .name = "tmpfs", diff --git a/kernel/tmpfs.h b/kernel/fs/tmpfs.h similarity index 100% rename from kernel/tmpfs.h rename to kernel/fs/tmpfs.h diff --git a/kernel/vfs.c b/kernel/fs/vfs.c similarity index 93% rename from kernel/vfs.c rename to kernel/fs/vfs.c index bcbb09653..031151f89 100644 --- a/kernel/vfs.c +++ b/kernel/fs/vfs.c @@ -1,9 +1,9 @@ #include "vfs.h" #include "tmpfs.h" -#include "allocator.h" -#include "thread.h" -#include "process.h" -#include "reader.h" +#include "../mm/allocator.h" +#include "../mm/cpio.h" +#include "../process/thread.h" +#include "../process/process.h" struct mount * rootfs; extern struct filesystem tmpfs; diff --git a/kernel/vfs.h b/kernel/fs/vfs.h similarity index 97% rename from kernel/vfs.h rename to kernel/fs/vfs.h index f270a8eaf..a09064faa 100644 --- a/kernel/vfs.h +++ b/kernel/fs/vfs.h @@ -1,7 +1,7 @@ #ifndef VFS_H #define VFS_H -#include "../lib/type.h" +#include "../../lib/type.h" struct vnode { struct mount * mount; diff --git a/kernel/allocator.c b/kernel/mm/allocator.c similarity index 99% rename from kernel/allocator.c rename to kernel/mm/allocator.c index f38428fc5..1af3d9c99 100644 --- a/kernel/allocator.c +++ b/kernel/mm/allocator.c @@ -1,8 +1,8 @@ #include "allocator.h" -#include "../lib/type.h" -#include "../lib/math.h" -#include "../lib/uart.h" -#include "../lib/string.h" +#include "../../lib/type.h" +#include "../../lib/math.h" +#include "../../lib/uart.h" +#include "../../lib/string.h" #define BUDDY_START_ADDR 0x10000000 #define BUDDY_END_ADDR 0x1f000000 diff --git a/kernel/allocator.h b/kernel/mm/allocator.h similarity index 100% rename from kernel/allocator.h rename to kernel/mm/allocator.h diff --git a/kernel/reader.c b/kernel/mm/cpio.c similarity index 97% rename from kernel/reader.c rename to kernel/mm/cpio.c index 31cdd2fae..a283f6941 100644 --- a/kernel/reader.c +++ b/kernel/mm/cpio.c @@ -1,11 +1,11 @@ -#include "reader.h" -#include "process.h" +#include "cpio.h" #include "allocator.h" -#include "thread.h" -#include "vfs.h" -#include "tmpfs.h" -#include "../lib/uart.h" -#include "../lib/string.h" +#include "../process/process.h" +#include "../process/thread.h" +#include "../fs/vfs.h" +#include "../fs/tmpfs.h" +#include "../../lib/uart.h" +#include "../../lib/string.h" const int FILE_NUM_LIMITED = 100; char * address_cpio = (char*)0x2000; diff --git a/kernel/reader.h b/kernel/mm/cpio.h similarity index 94% rename from kernel/reader.h rename to kernel/mm/cpio.h index e3fbde90d..83e6c46a4 100644 --- a/kernel/reader.h +++ b/kernel/mm/cpio.h @@ -1,6 +1,7 @@ -#pragma once +#ifndef CPIO_H +#define CPIO_H -#include "vfs.h" +#include "../fs/vfs.h" struct cpio_newc_header { char c_magic[6]; @@ -49,3 +50,4 @@ void EnableInterrupt(); void PrintCpio(); void PrintFileContent(char arg[]); +#endif \ No newline at end of file diff --git a/kernel/fd.c b/kernel/process/fd.c similarity index 100% rename from kernel/fd.c rename to kernel/process/fd.c diff --git a/kernel/fd.h b/kernel/process/fd.h similarity index 92% rename from kernel/fd.h rename to kernel/process/fd.h index 0fd32811e..56f22b967 100644 --- a/kernel/fd.h +++ b/kernel/process/fd.h @@ -1,7 +1,7 @@ #ifndef FD_H #define FD_H -#include "vfs.h" +#include "../fs/vfs.h" #define FD_TABLE_SIZE 100 diff --git a/kernel/process.c b/kernel/process/process.c similarity index 92% rename from kernel/process.c rename to kernel/process/process.c index f96c90faa..15438fc3d 100644 --- a/kernel/process.c +++ b/kernel/process/process.c @@ -1,10 +1,10 @@ -#include "../lib/uart.h" -#include "../lib/string.h" #include "process.h" -#include "reader.h" #include "thread.h" -#include "vfs.h" #include "fd.h" +#include "../../lib/uart.h" +#include "../../lib/string.h" +#include "../mm/cpio.h" +#include "../fs/vfs.h" int do_getpid() { diff --git a/kernel/process.h b/kernel/process/process.h similarity index 94% rename from kernel/process.h rename to kernel/process/process.h index 3c5da4b54..45baa82ef 100644 --- a/kernel/process.h +++ b/kernel/process/process.h @@ -1,7 +1,7 @@ #ifndef PROCESS_H #define PROCESS_H -#include "../lib/type.h" +#include "../../lib/type.h" #define PROCESS_SIZE 4096 diff --git a/kernel/thread.c b/kernel/process/thread.c similarity index 98% rename from kernel/thread.c rename to kernel/process/thread.c index c8ef39172..d82d3fdab 100644 --- a/kernel/thread.c +++ b/kernel/process/thread.c @@ -1,8 +1,8 @@ #include "thread.h" -#include "allocator.h" -#include "reader.h" #include "process.h" -#include "../lib/uart.h" +#include "../mm/allocator.h" +#include "../mm/cpio.h" +#include "../../lib/uart.h" #define THREAD_MAX 5 diff --git a/kernel/thread.h b/kernel/process/thread.h similarity index 97% rename from kernel/thread.h rename to kernel/process/thread.h index 5d2616386..05c189a2e 100644 --- a/kernel/thread.h +++ b/kernel/process/thread.h @@ -2,7 +2,7 @@ #define THREAD_H #include "fd.h" -#include "../lib/type.h" +#include "../../lib/type.h" #define THREAD_SIZE 4096 From 26c937d0d235566f79d0a3fb6071a63a43c2df4f Mon Sep 17 00:00:00 2001 From: ChenZhenHua Date: Thu, 10 Jun 2021 19:06:06 +0800 Subject: [PATCH 2/3] add sd, fatfs --- kernel/fs/fat32.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/fs/fat32.h | 32 ++++++ kernel/fs/sd.c | 243 +++++++++++++++++++++++++++++++++++++++++++ kernel/fs/sd.h | 9 ++ kernel/fs/tmpfs.c | 5 +- kernel/fs/tmpfs.h | 2 +- kernel/fs/vfs.c | 2 + 7 files changed, 548 insertions(+), 4 deletions(-) create mode 100644 kernel/fs/sd.c create mode 100644 kernel/fs/sd.h diff --git a/kernel/fs/fat32.c b/kernel/fs/fat32.c index e69de29bb..57a8407e9 100644 --- a/kernel/fs/fat32.c +++ b/kernel/fs/fat32.c @@ -0,0 +1,259 @@ +#include "fat32.h" +#include "sd.h" +#include "../../lib/uart.h" +#include "../../lib/string.h" + +#define BASE_PARTITION_BLOCK_SIZE 2048 + +int FAT_BASE_BLOCK; +int DATA_BASE_BLOCK; +int ROOT_CLUSTER; + +struct filesystem fatfs = { + .name = "fat32", + .setup_mount = fat32_setup +}; + +struct file_operations fat_f_ops = { + .write = fat32_write, + .read = fat32_read +}; + +struct vnode_operations fat_v_ops = { + .lookup = fat32_lookup, + .create = fat32_create +}; + +int fat32_setup(struct filesystem * fs, struct mount * mount) +{ + mount->fs = fs; + mount->root->mount = mount; + mount->root->v_ops = &fat_v_ops; + mount->root->f_ops = &fat_f_ops; + mount->root->internel = fat32_create_internel("/", 0, 0, 0); + + int bytes_per_logical_sector, + sectors_per_cluster, + n_fat_tables, + root_start_cluster, + sectors_per_fat, + n_reserved_sectors; + + char buffer[FAT_BLOCK_SIZE]; + + readblock(BASE_PARTITION_BLOCK_SIZE, buffer); + + bytes_per_logical_sector = *((short*)&buffer[0x00B]); + sectors_per_cluster = buffer[0x00D]; + n_fat_tables = buffer[0x010]; + root_start_cluster = *((int*)buffer[0x02C]); + sectors_per_fat = *((int*)buffer[0x024]); + n_reserved_sectors = *((short*)buffer[0x00E]); + + ROOT_CLUSTER = root_start_cluster; + FAT_BASE_BLOCK = BASE_PARTITION_BLOCK_SIZE + n_reserved_sectors; + DATA_BASE_BLOCK = FAT_BASE_BLOCK + n_fat_tables * sectors_per_fat; + + uart_puts("FAT32 :\n"); + uart_puts("\tBytes per logical sector:"); + uart_puts_i(bytes_per_logical_sector); + uart_puts("\n\tSectors per cluster:"); + uart_puts_i(sectors_per_cluster); + uart_puts("\n\tNumber of FAT tables:"); + uart_puts_i(n_fat_tables); + uart_puts("\n\tRoot cluster number:"); + uart_puts_i(root_start_cluster); + uart_puts("\n\tSectors per FAT table:"); + uart_puts_i(sectors_per_fat); + uart_puts("\n\tReserved sectors number:"); + uart_puts_i(n_reserved_sectors); + uart_puts("\n==============================\n"); + + sd_init_fs(mount->root); + + return 0; +} + +int fat32_lookup(struct vnode * dir_node, struct vnode ** target, const char * component_name) +{ + struct vnode * fat_node = dir_node; + + while(dir_node->internel != NULL && ((struct fat32_internel *)(fat_node->internel))->next_sibling != NULL) + { + if (!strcmp(component_name, ((struct fat32_internel *)(fat_node->internel))->name)) + { + break; + } + fat_node = ((struct fat32_internel *)(fat_node->internel))->next_sibling; + } + + if (fat_node->internel == NULL || strcmp(component_name, ((struct fat32_internel *)(fat_node->internel))->name)) + { + return -1; + } + else + { + *target = fat_node; + return 0; + } +} + +int fat32_create(struct vnode * dir_node, struct vnode ** target, const char * component_name) +{ + return -1; +} + +int fat32_read(struct file * file, void * buf, size_t len) +{ + struct fat32_internel * internel = file->vnode->internel; + int start_cluster = internel->start_cluster; + + int target_block = DATA_BASE_BLOCK + start_cluster + (file->f_pos / FAT_BLOCK_SIZE); + int offset = file->f_pos % FAT_BLOCK_SIZE; + + char * buf_addr = (char *)buf; + char buffer[FAT_BLOCK_SIZE]; + readblock(target_block, buffer); + + for(int i = 0; i < len; ++i) + { + buf_addr[i] = buffer[offset + i]; + } + + file->f_pos += len; + + return len; +} + +int fat32_write(struct file * file, const void * buf, size_t len) +{ + struct fat32_internel * internel = file->vnode->internel; + int start_cluster = internel->start_cluster; + + int target_block = DATA_BASE_BLOCK + start_cluster + (file->f_pos / FAT_BLOCK_SIZE); + int offset = file->f_pos % FAT_BLOCK_SIZE; + + char * buf_addr = (char *)buf; + char buffer[FAT_BLOCK_SIZE]; + readblock(target_block, buffer); + + for (int i = 0; i < len; ++i) + { + buffer[offset + i] = buf_addr[i]; + } + writeblock(target_block, buffer); + + file->f_pos += len; + + if (file->f_pos > internel->size) + { + internel->size = file->f_pos; + fat32_update_filesize(file->vnode, internel->size); + } + + return len; +} + +struct vnode * fat32_create_vnode(struct vnode * src, const char * name, int size, int start_cluster, int entry_index) +{ + struct vnode * node = (struct vnode *)buddy_alloc(sizeof(struct vnode)); + + node->mount = src->mount; + node->v_ops = src->v_ops; + node->f_ops = src->f_ops; + node->internel = (void *)fat32_create_internel(name, size, start_cluster, entry_index); + + return node; +} + +struct fat32_internel * fat32_create_internel(const char * name, int size, int start_cluster, int entry_index) +{ + struct fat32_internel * internel = (struct fat32_internel *)buddy_alloc((sizeof(struct fat32_internel))); + + strcpy(name, internel->name); + internel->size = size; + internel->start_cluster = start_cluster; + internel->entry_index = entry_index; + internel->next_sibling = NULL; + + return internel; +} + +void fat32_append_child(struct vnode * parent, struct vnode * child) +{ + struct fat32_internel * internel = (struct fat32_internel *)(parent->internel); + + if (internel == NULL) + { + *parent = *child; + } + else + { + while(internel->next_sibling != NULL) + { + if (internel->next_sibling->internel != NULL) + { + internel = (struct fat32_internel *)(internel->next_sibling->internel); + } + else + { + break; + } + } + internel->next_sibling = child; + } +} + +void sd_init_fs(struct vnode * root) +{ + char buffer[FAT_BLOCK_SIZE]; + + readblock(DATA_BASE_BLOCK, buffer); + + int offset = 0, entry_index = 0; + while (buffer[offset] != 0 && buffer[offset] != 0xE5) + { + // filename + int i; + char filename[13] = { 0 }; + // name + for (i = 0; i < 8; ++i) + { + filename[i] = buffer[offset + i]; + if (filename[i] == ' ') break; + } + filename[i] = '.'; + // ext + for (int j = 0; j < 3; ++i, ++j) + { + filename[i] = buffer[offset + 8 + j]; + if (filename[i] == ' ') break; + } + filename[i] = '\0'; + + int filesize = *((int *)&buffer[offset + 0x1C]); + + int cluster_index; + cluster_index = *((short *)&buffer[offset + 0x14]); + cluster_index = (cluster_index << 16) + *((short *)&buffer[offset + 0x1A]); + + struct vnode * node = fat32_create_vnode(root, filename, filesize, cluster_index, entry_index); + + fat32_append_child(root, node); + + offset += 32; + entry_index++; + } +} + +void fat32_update_filesize(struct vnode * node, int size) +{ + struct fat32_internel * internel = node->internel; + char buffer[512]; + readblock(DATA_BASE_BLOCK, buffer); + + int * size_addr = (int *)&(buffer[32 * internel->entry_index + 0x1C]); + *size_addr = size; + + writeblock(DATA_BASE_BLOCK, buffer); +} \ No newline at end of file diff --git a/kernel/fs/fat32.h b/kernel/fs/fat32.h index e69de29bb..3da68b524 100644 --- a/kernel/fs/fat32.h +++ b/kernel/fs/fat32.h @@ -0,0 +1,32 @@ +#ifndef FAT32_H +#define FAT32_H + +#include "vfs.h" + +#define FAT_BLOCK_SIZE 512 + +struct fat32_internel { + char name[12]; + int size; + + int start_cluster; + int entry_index; + + struct vnode * next_sibling; +}; + +int fat32_setup(struct filesystem * fs, struct mount * mount); +int fat32_lookup(struct vnode * dir_node, struct vnode ** target, const char * component_name); +int fat32_create(struct vnode * dir_node, struct vnode ** target, const char * component_name); +int fat32_read(struct file * file, void * buf, size_t len); +int fat32_write(struct file * file, const void * buf, size_t len); + +struct vnode * fat32_create_vnode(struct vnode * src, const char * name, int size, int start_cluster, int entry_index); +struct fat32_internel * fat32_create_internel(const char * name, int size, int start_cluster, int entry_index); + +void fat32_append_child(struct vnode * parent, struct vnode * child); +void fat32_update_filesize(struct vnode * node, int size); + +void sd_init_fs(struct vnode * root); + +#endif \ No newline at end of file diff --git a/kernel/fs/sd.c b/kernel/fs/sd.c new file mode 100644 index 000000000..ba0ed32b8 --- /dev/null +++ b/kernel/fs/sd.c @@ -0,0 +1,243 @@ +// mmio +#define KVA 0xffff000000000000 +#define MMIO_BASE (KVA + 0x3f000000) + +// SD card command +#define GO_IDLE_STATE 0 +#define SEND_OP_CMD 1 +#define ALL_SEND_CID 2 +#define SEND_RELATIVE_ADDR 3 +#define SELECT_CARD 7 +#define SEND_IF_COND 8 + #define VOLTAGE_CHECK_PATTERN 0x1aa +#define STOP_TRANSMISSION 12 +#define SET_BLOCKLEN 16 +#define READ_SINGLE_BLOCK 17 +#define WRITE_SINGLE_BLOCK 24 +#define SD_APP_OP_COND 41 + #define SDCARD_3_3V (1 << 21) + #define SDCARD_ISHCS (1 << 30) + #define SDCARD_READY (1 << 31) +#define APP_CMD 55 + +// gpio +#define GPIO_BASE (MMIO_BASE + 0x200000) +#define GPIO_GPFSEL4 (GPIO_BASE + 0x10) +#define GPIO_GPFSEL5 (GPIO_BASE + 0x14) +#define GPIO_GPPUD (GPIO_BASE + 0x94) +#define GPIO_GPPUDCLK1 (GPIO_BASE + 0x9c) + +// sdhost +#define SDHOST_BASE (MMIO_BASE + 0x202000) +#define SDHOST_CMD (SDHOST_BASE + 0) + #define SDHOST_READ 0x40 + #define SDHOST_WRITE 0x80 + #define SDHOST_LONG_RESPONSE 0x200 + #define SDHOST_NO_REPONSE 0x400 + #define SDHOST_BUSY 0x800 + #define SDHOST_NEW_CMD 0x8000 +#define SDHOST_ARG (SDHOST_BASE + 0x4) +#define SDHOST_TOUT (SDHOST_BASE + 0x8) + #define SDHOST_TOUT_DEFAULT 0xf00000 +#define SDHOST_CDIV (SDHOST_BASE + 0xc) + #define SDHOST_CDIV_MAXDIV 0x7ff + #define SDHOST_CDIV_DEFAULT 0x148 +#define SDHOST_RESP0 (SDHOST_BASE + 0x10) +#define SDHOST_RESP1 (SDHOST_BASE + 0x14) +#define SDHOST_RESP2 (SDHOST_BASE + 0x18) +#define SDHOST_RESP3 (SDHOST_BASE + 0x1c) +#define SDHOST_HSTS (SDHOST_BASE + 0x20) + #define SDHOST_HSTS_MASK (0x7f8) + #define SDHOST_HSTS_ERR_MASK (0xf8) + #define SDHOST_HSTS_DATA (1 << 0) +#define SDHOST_PWR (SDHOST_BASE + 0x30) +#define SDHOST_DBG (SDHOST_BASE + 0x34) + #define SDHOST_DBG_FSM_DATA 1 + #define SDHOST_DBG_FSM_MASK 0xf + #define SDHOST_DBG_MASK (0x1f << 14 | 0x1f << 9) + #define SDHOST_DBG_FIFO (0x4 << 14 | 0x4 << 9) +#define SDHOST_CFG (SDHOST_BASE + 0x38) + #define SDHOST_CFG_DATA_EN (1 << 4) + #define SDHOST_CFG_SLOW (1 << 3) + #define SDHOST_CFG_INTBUS (1 << 1) +#define SDHOST_SIZE (SDHOST_BASE + 0x3c) +#define SDHOST_DATA (SDHOST_BASE + 0x40) +#define SDHOST_CNT (SDHOST_BASE + 0x50) + +// helper +#define set(io_addr, val) \ + asm volatile("str %w1, [%0]" ::"r"(io_addr), "r"(val) : "memory"); + +#define get(io_addr, val) \ + asm volatile("ldr %w0, [%1]" : "=r"(val) : "r"(io_addr) : "memory"); + +static inline void delay(unsigned long tick) { + while (tick--) { + asm volatile("nop"); + } +} + +static int is_hcs; // high capcacity(SDHC) + +static void pin_setup() { + set(GPIO_GPFSEL4, 0x24000000); + set(GPIO_GPFSEL5, 0x924); + set(GPIO_GPPUD, 0); + delay(15000); + set(GPIO_GPPUDCLK1, 0xffffffff); + delay(15000); + set(GPIO_GPPUDCLK1, 0); +} + +static void sdhost_setup() { + unsigned int tmp; + set(SDHOST_PWR, 0); + set(SDHOST_CMD, 0); + set(SDHOST_ARG, 0); + set(SDHOST_TOUT, SDHOST_TOUT_DEFAULT); + set(SDHOST_CDIV, 0); + set(SDHOST_HSTS, SDHOST_HSTS_MASK); + set(SDHOST_CFG, 0); + set(SDHOST_CNT, 0); + set(SDHOST_SIZE, 0); + get(SDHOST_DBG, tmp); + tmp &= ~SDHOST_DBG_MASK; + tmp |= SDHOST_DBG_FIFO; + set(SDHOST_DBG, tmp); + delay(250000); + set(SDHOST_PWR, 1); + delay(250000); + set(SDHOST_CFG, SDHOST_CFG_SLOW | SDHOST_CFG_INTBUS | SDHOST_CFG_DATA_EN); + set(SDHOST_CDIV, SDHOST_CDIV_DEFAULT); +} + +static int wait_sd() { + int cnt = 1000000; + unsigned int cmd; + do { + if (cnt == 0) { + return -1; + } + get(SDHOST_CMD, cmd); + --cnt; + } while (cmd & SDHOST_NEW_CMD); + return 0; +} + +static int sd_cmd(unsigned cmd, unsigned int arg) { + set(SDHOST_ARG, arg); + set(SDHOST_CMD, cmd | SDHOST_NEW_CMD); + return wait_sd(); +} + +static int sdcard_setup() { + unsigned int tmp; + sd_cmd(GO_IDLE_STATE | SDHOST_NO_REPONSE, 0); + sd_cmd(SEND_IF_COND, VOLTAGE_CHECK_PATTERN); + get(SDHOST_RESP0, tmp); + if (tmp != VOLTAGE_CHECK_PATTERN) { + return -1; + } + while (1) { + if (sd_cmd(APP_CMD, 0) == -1) { + // MMC card or invalid card status + // currently not support + continue; + } + sd_cmd(SD_APP_OP_COND, SDCARD_3_3V | SDCARD_ISHCS); + get(SDHOST_RESP0, tmp); + if (tmp & SDCARD_READY) { + break; + } + delay(1000000); + } + + is_hcs = tmp & SDCARD_ISHCS; + sd_cmd(ALL_SEND_CID | SDHOST_LONG_RESPONSE, 0); + sd_cmd(SEND_RELATIVE_ADDR, 0); + get(SDHOST_RESP0, tmp); + sd_cmd(SELECT_CARD, tmp); + sd_cmd(SET_BLOCKLEN, 512); + return 0; +} + +static int wait_fifo() { + int cnt = 1000000; + unsigned int hsts; + do { + if (cnt == 0) { + return -1; + } + get(SDHOST_HSTS, hsts); + --cnt; + } while ((hsts & SDHOST_HSTS_DATA) == 0); + return 0; +} + +static void set_block(int size, int cnt) { + set(SDHOST_SIZE, size); + set(SDHOST_CNT, cnt); +} + +static void wait_finish() { + unsigned int dbg; + do { + get(SDHOST_DBG, dbg); + } while ((dbg & SDHOST_DBG_FSM_MASK) != SDHOST_HSTS_DATA); +} + +void readblock(int block_idx, void* buf) { + unsigned int* buf_u = (unsigned int*)buf; + int succ = 0; + if (!is_hcs) { + block_idx <<= 9; + } + do{ + set_block(512, 1); + sd_cmd(READ_SINGLE_BLOCK | SDHOST_READ, block_idx); + for (int i = 0; i < 128; ++i) { + wait_fifo(); + get(SDHOST_DATA, buf_u[i]); + } + unsigned int hsts; + get(SDHOST_HSTS, hsts); + if (hsts & SDHOST_HSTS_ERR_MASK) { + set(SDHOST_HSTS, SDHOST_HSTS_ERR_MASK); + sd_cmd(STOP_TRANSMISSION | SDHOST_BUSY, 0); + } else { + succ = 1; + } + } while(!succ); + wait_finish(); +} + +void writeblock(int block_idx, void* buf) { + unsigned int* buf_u = (unsigned int*)buf; + int succ = 0; + if (!is_hcs) { + block_idx <<= 9; + } + do{ + set_block(512, 1); + sd_cmd(WRITE_SINGLE_BLOCK | SDHOST_WRITE, block_idx); + for (int i = 0; i < 128; ++i) { + wait_fifo(); + set(SDHOST_DATA, buf_u[i]); + } + unsigned int hsts; + get(SDHOST_HSTS, hsts); + if (hsts & SDHOST_HSTS_ERR_MASK) { + set(SDHOST_HSTS, SDHOST_HSTS_ERR_MASK); + sd_cmd(STOP_TRANSMISSION | SDHOST_BUSY, 0); + } else { + succ = 1; + } + } while(!succ); + wait_finish(); +} + +void sd_init() { + pin_setup(); + sdhost_setup(); + sdcard_setup(); +} diff --git a/kernel/fs/sd.h b/kernel/fs/sd.h new file mode 100644 index 000000000..50d9db15c --- /dev/null +++ b/kernel/fs/sd.h @@ -0,0 +1,9 @@ +#ifndef SD_H +#define SD_H + +void sd_init(); + +void readblock(int block_idx, void * buf); +void writeblock(int block_idx, void * buf); + +#endif \ No newline at end of file diff --git a/kernel/fs/tmpfs.c b/kernel/fs/tmpfs.c index 63cdd1aad..5caf1d4ef 100644 --- a/kernel/fs/tmpfs.c +++ b/kernel/fs/tmpfs.c @@ -33,7 +33,6 @@ int tmpfs_lookup(struct vnode * dir_node, struct vnode ** target, const char * c { struct vnode * tmp_node = dir_node; - int count = 0; while (tmp_node->internel != NULL && ((struct tmpfs_internel *)(tmp_node->internel))->next_sibling != NULL) { if (!strcmp(component_name, ((struct tmpfs_internel *)(tmp_node->internel))->name)) @@ -59,7 +58,7 @@ int tmpfs_create(struct vnode * dir_node, struct vnode ** target, const char * c struct vnode * tmp_node = NULL; tmp_node = tmpfs_create_vnode(dir_node, component_name); - append_child(dir_node, tmp_node); + tmpfs_append_child(dir_node, tmp_node); *target = tmp_node; @@ -129,7 +128,7 @@ struct tmpfs_internel * tmpfs_create_internel(const char * name) return internel; } -void append_child(struct vnode * parent, struct vnode * child) +void tmpfs_append_child(struct vnode * parent, struct vnode * child) { struct tmpfs_internel * internel = (struct tmpfs_internel *)(parent->internel); diff --git a/kernel/fs/tmpfs.h b/kernel/fs/tmpfs.h index c05d9c878..5b1dabbde 100644 --- a/kernel/fs/tmpfs.h +++ b/kernel/fs/tmpfs.h @@ -23,6 +23,6 @@ int tmpfs_write(struct file * file, const void * buf, size_t len); struct vnode * tmpfs_create_vnode(struct vnode * src, const char * name); struct tmpfs_internel * tmpfs_create_internel(const char * name); -void append_child(struct vnode * parent, struct vnode * child); +void tmpfs_append_child(struct vnode * parent, struct vnode * child); #endif \ No newline at end of file diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 031151f89..3f1e0b6a9 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -1,5 +1,6 @@ #include "vfs.h" #include "tmpfs.h" +#include "fat32.h" #include "../mm/allocator.h" #include "../mm/cpio.h" #include "../process/thread.h" @@ -7,6 +8,7 @@ struct mount * rootfs; extern struct filesystem tmpfs; +extern struct filesystem fatfs; void init_filesystem() { From 4c91469ccfea00413984bedfdadb847360f540a3 Mon Sep 17 00:00:00 2001 From: ChenZhenHua Date: Wed, 23 Jun 2021 19:31:14 +0800 Subject: [PATCH 3/3] add fat32 --- initramfs.cpio | Bin 11264 -> 11264 bytes kernel/fs/fat32.c | 50 +++++++++++++++++++++++++-------------- kernel/fs/sd.c | 2 +- kernel/fs/vfs.c | 22 ++++++++++++++++- kernel/process/process.c | 3 +-- send_kernel.py | 1 + 6 files changed, 56 insertions(+), 22 deletions(-) diff --git a/initramfs.cpio b/initramfs.cpio index 9ed5ed200ebefed4a62e1756aac3d7d3d8fb80d2..1765479ffac145c2244c20061772f639b4a18aca 100644 GIT binary patch delta 270 zcmZpOXo#4wfY-&?z|q{<00bNjC$4p@-@DS0p&^KYfnma5W`>Cj4eAp=2Q#h|W@xzd zRhZ$Y4FkiJhs?sOns^$5zA!Urxd8bOfc!;ZT0~0(sLve8o^nWi;sa)pRUotUf&8yP zwTwVHMFx$DNsJ9aMqu@#S~?JYs~CamRDtY=YEZ-Vz!Ji%dVn-15HkQ3d=7S8`Bm8A z=ilnXn@=-pF*7-6On%P)dh$G#W1Cm7#jxlm=jWwmrt6hdlmOii1R1G0Ir#`Kg9nJO Y;2-Sb36z{{C@Q(xi2Izv=Lou63;6v(k~FA?PnN!^F?Qj4MSL7$!_f(wO*wS!9(k zkX_uQG4X3O)5`DC3_sl&7^Z;Keq(0PdcZ8a${EN%1mu4O@)?0@A25q)DK5~M=n52n z2$ToOJzy5qas={0a^egPm#n~SQ7sEFEwYL+9jM3<$oT>`1f)TDl`fF~8OVRgEWQfp z5UnPjh9DE57-NmYWDr}Ch2bJlot8e>5b;&LK$;7P8GvSe4t8AmHQEX2V27W7tBQ_`@8}Gv~pe< diff --git a/kernel/fs/fat32.c b/kernel/fs/fat32.c index 57a8407e9..40d369b74 100644 --- a/kernel/fs/fat32.c +++ b/kernel/fs/fat32.c @@ -41,15 +41,17 @@ int fat32_setup(struct filesystem * fs, struct mount * mount) char buffer[FAT_BLOCK_SIZE]; - readblock(BASE_PARTITION_BLOCK_SIZE, buffer); + sd_init(); - bytes_per_logical_sector = *((short*)&buffer[0x00B]); + readblock(BASE_PARTITION_BLOCK_SIZE, buffer); + + bytes_per_logical_sector = (int)(buffer[0x00C]<<8) + (int)(buffer[0x00B]); sectors_per_cluster = buffer[0x00D]; n_fat_tables = buffer[0x010]; - root_start_cluster = *((int*)buffer[0x02C]); - sectors_per_fat = *((int*)buffer[0x024]); - n_reserved_sectors = *((short*)buffer[0x00E]); - + root_start_cluster = (int)(buffer[0x02F]<<(8*3)) + (int)(buffer[0x02E]<<(8*2)) + (int)(buffer[0x02D]<<(8*1)) + (int)(buffer[0x02C]); + sectors_per_fat = (int)(buffer[0x027]<<(8*3)) + (int)(buffer[0x026]<<(8*2)) + (int)(buffer[0x025]<<(8*1)) + (int)(buffer[0x024]); + n_reserved_sectors = (int)(buffer[0x00F]<<8) + (int)(buffer[0x00E]); + ROOT_CLUSTER = root_start_cluster; FAT_BASE_BLOCK = BASE_PARTITION_BLOCK_SIZE + n_reserved_sectors; DATA_BASE_BLOCK = FAT_BASE_BLOCK + n_fat_tables * sectors_per_fat; @@ -68,7 +70,7 @@ int fat32_setup(struct filesystem * fs, struct mount * mount) uart_puts("\n\tReserved sectors number:"); uart_puts_i(n_reserved_sectors); uart_puts("\n==============================\n"); - + sd_init_fs(mount->root); return 0; @@ -78,7 +80,7 @@ int fat32_lookup(struct vnode * dir_node, struct vnode ** target, const char * c { struct vnode * fat_node = dir_node; - while(dir_node->internel != NULL && ((struct fat32_internel *)(fat_node->internel))->next_sibling != NULL) + while(dir_node->internel != NULL && fat_node != NULL && ((struct fat32_internel *)(fat_node->internel)) != NULL) { if (!strcmp(component_name, ((struct fat32_internel *)(fat_node->internel))->name)) { @@ -87,7 +89,7 @@ int fat32_lookup(struct vnode * dir_node, struct vnode ** target, const char * c fat_node = ((struct fat32_internel *)(fat_node->internel))->next_sibling; } - if (fat_node->internel == NULL || strcmp(component_name, ((struct fat32_internel *)(fat_node->internel))->name)) + if (fat_node == NULL || fat_node->internel == NULL || strcmp(component_name, ((struct fat32_internel *)(fat_node->internel))->name)) { return -1; } @@ -99,8 +101,8 @@ int fat32_lookup(struct vnode * dir_node, struct vnode ** target, const char * c } int fat32_create(struct vnode * dir_node, struct vnode ** target, const char * component_name) -{ - return -1; +{ + return 0; } int fat32_read(struct file * file, void * buf, size_t len) @@ -206,36 +208,48 @@ void fat32_append_child(struct vnode * parent, struct vnode * child) void sd_init_fs(struct vnode * root) { + char * filename = (char*)buddy_alloc(13); char buffer[FAT_BLOCK_SIZE]; readblock(DATA_BASE_BLOCK, buffer); int offset = 0, entry_index = 0; + while (buffer[offset] != 0 && buffer[offset] != 0xE5) { + // clear + for (int j = 0; j < 13; ++j) + { + filename[j] = ' '; + } + // filename - int i; - char filename[13] = { 0 }; + int i = 0; + // name for (i = 0; i < 8; ++i) { filename[i] = buffer[offset + i]; if (filename[i] == ' ') break; } + filename[i] = '.'; + i++; + // ext for (int j = 0; j < 3; ++i, ++j) { filename[i] = buffer[offset + 8 + j]; if (filename[i] == ' ') break; } + filename[i] = '\0'; - - int filesize = *((int *)&buffer[offset + 0x1C]); - + + int filesize = (int)(buffer[offset + 0x1F]<<(8*3)) + (int)(buffer[offset + 0x1E]<<(8*2)) + (int)(buffer[offset + 0x1D]<<(8*1)) + (int)(buffer[offset + 0x1C]); + int cluster_index; - cluster_index = *((short *)&buffer[offset + 0x14]); - cluster_index = (cluster_index << 16) + *((short *)&buffer[offset + 0x1A]); + cluster_index = (int)(buffer[offset + 0x15] << 8) + (int)(buffer[offset + 0x14]); + cluster_index = (cluster_index << 16) + (int)(buffer[offset + 0x1B]<<8) + (int)(buffer[offset + 0x1A]); struct vnode * node = fat32_create_vnode(root, filename, filesize, cluster_index, entry_index); diff --git a/kernel/fs/sd.c b/kernel/fs/sd.c index ba0ed32b8..1c107a585 100644 --- a/kernel/fs/sd.c +++ b/kernel/fs/sd.c @@ -1,5 +1,5 @@ // mmio -#define KVA 0xffff000000000000 +#define KVA (0) #define MMIO_BASE (KVA + 0x3f000000) // SD card command diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 3f1e0b6a9..ad312a84d 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -15,7 +15,7 @@ void init_filesystem() rootfs = (struct mount *)buddy_alloc(sizeof(struct mount)); rootfs->root = (struct vnode *)buddy_alloc(sizeof(struct vnode)); - register_filesystem(&tmpfs); + register_filesystem(&fatfs); } int register_filesystem(struct filesystem * fs) @@ -65,6 +65,24 @@ void vfs_test_1() do_exec("fs_test.img", ""); } +void vfs_test_2() +{ + int a = do_open("HELLO.TXT", 0); + int s; + char * buf; + + do_write(a, "Hello OSDI\n", 12); + + do_close(a); + + a = do_open("HELLO.TXT", 0); + s = do_read(a, buf, 100); + + buf[s - 1] = '\0'; + + uart_puts(buf); +} + void vfs_test(int test_id) { // current default thread @@ -78,6 +96,8 @@ void vfs_test(int test_id) thread_create(vfs_test_1); idle(); break; + case 2: + vfs_test_2(); default: break; } diff --git a/kernel/process/process.c b/kernel/process/process.c index 15438fc3d..75bb4917c 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -50,6 +50,7 @@ int do_open(const char * path_name, int flags) struct Thread * t = current_thread(); int fd = insert_fd(t->fd_table, f); + return fd; } @@ -67,11 +68,9 @@ int do_close(int fd) int do_write(int fd, const void * buf, size_t len) { struct Thread * t = current_thread(); - struct File * f = t->fd_table[fd].f; int ret = vfs_write(f, buf, len); - return ret; } diff --git a/send_kernel.py b/send_kernel.py index a34beb1f2..931022cda 100644 --- a/send_kernel.py +++ b/send_kernel.py @@ -1,6 +1,7 @@ import sys with open('/dev/ttyUSB0', 'rb+', buffering = 0) as tty: + #with open('KERNEL8.IMG', 'rb') as kernel_file: with open('kernel8.img', 'rb') as kernel_file: kernel_data = kernel_file.read()