diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-01-04 14:05:49 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-01-04 14:05:49 +0800 |
| commit | d3cf3f08d1343d6b265516d5a79ce2d197b59d26 (patch) | |
| tree | a4bbae6cff94fa69eea30db865267b211eb4c86b /src/user | |
| parent | 210025560c80b48af4875af199f183ad709e3bf0 (diff) | |
| download | lume-d3cf3f08d1343d6b265516d5a79ce2d197b59d26.tar.gz lume-d3cf3f08d1343d6b265516d5a79ce2d197b59d26.tar.xz | |
feat(file-system): implement read and write FAT32 File System and basic shell
Diffstat (limited to 'src/user')
| -rw-r--r-- | src/user/echo.cc | 22 | ||||
| -rw-r--r-- | src/user/entry.S | 3 | ||||
| -rw-r--r-- | src/user/init.cc | 4 | ||||
| -rw-r--r-- | src/user/ls.cc | 112 | ||||
| -rw-r--r-- | src/user/mkdir.cc | 21 | ||||
| -rw-r--r-- | src/user/sh.cc | 53 | ||||
| -rw-r--r-- | src/user/usys.S | 3 |
7 files changed, 184 insertions, 34 deletions
diff --git a/src/user/echo.cc b/src/user/echo.cc new file mode 100644 index 0000000..ff4b8be --- /dev/null +++ b/src/user/echo.cc @@ -0,0 +1,22 @@ +#include "user/user.h" +#include "ulib/stdio.h" +#include "ulib/string.h" + +int main(int argc, char* argv[]) +{ + int i; + + for (i = 1; i < argc; i++) + { + write(1, argv[i], strlen(argv[i])); + if (i + 1 < argc) + { + write(1, " ", 1); + } + else + { + write(1, "\n", 1); + } + } + exit(0); +}
\ No newline at end of file diff --git a/src/user/entry.S b/src/user/entry.S index 110ebbf..432211c 100644 --- a/src/user/entry.S +++ b/src/user/entry.S @@ -2,9 +2,6 @@ .global _start _start: - li a0, 0 - li a1, 0 - call main call exit diff --git a/src/user/init.cc b/src/user/init.cc index 827a21e..07ed97e 100644 --- a/src/user/init.cc +++ b/src/user/init.cc @@ -2,12 +2,14 @@ #include "ulib/stdlib.h" #include "ulib/string.h" #include "user/user.h" +#include "drivers/uart_color.h" int main() { char *argv[] = {(char *)"sh", 0}; - printf("[Init] Starting Lume OS Shell...\n"); + printf(ANSI_BLUE"\n[Init] Starting Lume OS Shell..."ANSI_RESET); + printf("\n"); while (1) { diff --git a/src/user/ls.cc b/src/user/ls.cc new file mode 100644 index 0000000..e472578 --- /dev/null +++ b/src/user/ls.cc @@ -0,0 +1,112 @@ +#include "ulib/stdio.h" +#include "ulib/stdlib.h" +#include "ulib/string.h" +#include "user/user.h" +#include "common/fcntl.h" + + +struct FAT32_DirEnt +{ + char name[11]; + uint8 attr; + uint8 lcase; + uint8 ctime_cs; + uint16 ctime; + uint16 cdate; + uint16 adate; + uint16 fstClusHI; + uint16 wtime; + uint16 wdate; + uint16 fstClusLO; + uint32 fileSize; +} __attribute__((packed)); + +#define ATTR_DIRECTORY 0x10 +#define ATTR_LONG_NAME 0x0F + +void fmt_name(char *dst, const char *src) +{ + int i; + char *d = dst; + + for (i = 0; i < 8; i++) + { + if (src[i] == ' ') + break; + *d++ = src[i]; + } + + if (src[8] != ' ') + { + *d++ = '.'; + for (i = 8; i < 11; i++) + { + if (src[i] == ' ') + break; + *d++ = src[i]; + } + } + *d = 0; + + for (d = dst; *d; d++) + { + if (*d >= 'A' && *d <= 'Z') + *d += 32; + } +} + +void ls(const char *path) +{ + int fd; + struct FAT32_DirEnt de; + char name_buf[16]; + + if ((fd = open(path, O_RDONLY)) < 0) + { + printf("ls: cannot open %s\n", path); + return; + } + + while (read(fd, &de, sizeof(de)) == sizeof(de)) + { + if (de.name[0] == 0) + { + break; + } + + if ((unsigned char)de.name[0] == 0xE5) + { + continue; + } + + if ((de.attr & ATTR_LONG_NAME) == ATTR_LONG_NAME) + { + continue; + } + + fmt_name(name_buf, de.name); + + printf("%s %d\t%s\n", + (de.attr & ATTR_DIRECTORY) ? "<DIR>" : " ", + de.fileSize, + name_buf); + } + + close(fd); +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + ls("."); + } + else + { + for (int i = 1; i < argc; i++) + { + ls(argv[i]); + } + } + exit(0); +}
\ No newline at end of file diff --git a/src/user/mkdir.cc b/src/user/mkdir.cc new file mode 100644 index 0000000..8219109 --- /dev/null +++ b/src/user/mkdir.cc @@ -0,0 +1,21 @@ +#include "ulib/stdio.h" +#include "user/user.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) + { + printf("Usage: mkdir <dirname> ...\n"); + exit(1); + } + + for (int i = 1; i < argc; i++) + { + if (mkdir(argv[i]) < 0) + { + printf("mkdir: cannot create directory '%s'\n", argv[i]); + } + } + + exit(0); +}
\ No newline at end of file diff --git a/src/user/sh.cc b/src/user/sh.cc index 1f2e950..b4122f7 100644 --- a/src/user/sh.cc +++ b/src/user/sh.cc @@ -3,6 +3,7 @@ #include "ulib/string.h" #include "user/user.h" #include "common/fcntl.h" +#include "drivers/uart_color.h" constexpr int MAX_ARGS = 10; const char *WHITESPACE = " \t\r\n\v"; @@ -334,35 +335,13 @@ int getcmd(char *buf, int nbuf) write(1, "$ ", 2); memset(buf, 0, nbuf); - int i = 0; - while (i < nbuf - 1) - { - char c; - int n = read(0, &c, 1); - if (n <= 0) - return -1; + int n = read(0, buf, nbuf - 1); - if (c == '\b' || c == 127) - { - if (i > 0) - { - write(1, "\b \b", 3); - i--; - } - } - else if (c == '\n' || c == '\r') - { - write(1, "\n", 1); - buf[i] = 0; - return 0; - } - else - { - write(1, &c, 1); - buf[i++] = c; - } - } - return -1; + if (n < 0) + return -1; + + buf[n] = 0; + return 0; } int main() @@ -379,10 +358,18 @@ int main() // } // } - printf("\n[Lume Shell] Initialized! \n"); + printf(ANSI_GREEN"\n[Lume Shell] Welcome! \n"ANSI_RESET); + printf(ANSI_YELLOW "[Lume Shell] Start your journey of exploration!"ANSI_RESET); + printf("\n"); while (getcmd(buf, sizeof(buf)) >= 0) { + int len = strlen(buf); + if (len > 0 && buf[len - 1] == '\n') + { + buf[len - 1] = 0; + } + if (buf[0] == 'c' && buf[1] == 'd' && (buf[2] == ' ' || buf[2] == '\n' || buf[2] == 0)) { if (buf[strlen(buf) - 1] == '\n') @@ -401,6 +388,14 @@ int main() } continue; } + if (strcmp(buf, "shutdown") == 0 || strcmp(buf, "poweroff") == 0) + { + printf(ANSI_BLUE"System shutting down..."ANSI_RESET); + printf("\n"); + shutdown(); + + continue; + } if (fork_or_panic() == 0) { diff --git a/src/user/usys.S b/src/user/usys.S index f85917e..56cbb22 100644 --- a/src/user/usys.S +++ b/src/user/usys.S @@ -38,4 +38,5 @@ SYSCALL(sleep) SYSCALL(uptime) SYSCALL(putc) SYSCALL(disk_test) -SYSCALL(lseek)
\ No newline at end of file +SYSCALL(lseek) +SYSCALL(shutdown)
\ No newline at end of file |
