summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-01-04 14:12:24 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-01-04 14:12:24 +0800
commita64d25c07b31d57f8706073e11cd774d0880d6dd (patch)
treea4bbae6cff94fa69eea30db865267b211eb4c86b /src/drivers
parent210025560c80b48af4875af199f183ad709e3bf0 (diff)
parentd3cf3f08d1343d6b265516d5a79ce2d197b59d26 (diff)
downloadlume-a64d25c07b31d57f8706073e11cd774d0880d6dd.tar.gz
lume-a64d25c07b31d57f8706073e11cd774d0880d6dd.tar.xz
Merge pull request #5 from Richard-Qin-001/dev/file-system
feat(file-system): implement read and write FAT32 File System and basic shell
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/uart.cc100
1 files changed, 47 insertions, 53 deletions
diff --git a/src/drivers/uart.cc b/src/drivers/uart.cc
index 4064b16..55609ba 100644
--- a/src/drivers/uart.cc
+++ b/src/drivers/uart.cc
@@ -7,6 +7,15 @@
namespace Drivers
{
+ struct
+ {
+ Spinlock lock;
+ char buf[128]; // Line buffer
+ uint32 r; // Read pointer (position taken by the user)
+ uint32 w; // Write pointer (position confirmed by Enter)
+ uint32 e; // Editing cursor (current typing position)
+ } cons;
+
// Circular buffer structure
struct
{
@@ -21,6 +30,7 @@ namespace Drivers
void uart_init()
{
uart_rx.lock.init("uart_rx");
+ cons.lock.init("console");
uart_tx_lock.init("uart_tx");
uart_rx.r = 0;
uart_rx.w = 0;
@@ -119,88 +129,72 @@ namespace Drivers
struct Proc *p = myproc();
int target_idx = 0;
- uart_rx.lock.acquire();
+ cons.lock.acquire();
while (target_idx < len)
{
+ while (cons.r < cons.w)
+ {
+ char c = cons.buf[cons.r++ % sizeof(cons.buf)];
+ cons.lock.release();
+
+ if (VM::copyout(p->pagetable, target + target_idx, &c, 1) < 0)
+ return -1;
+
+ target_idx++;
+ if (c == '\n')
+ return target_idx;
+ if (target_idx == len)
+ return target_idx;
+
+ cons.lock.acquire();
+ }
+
+ uart_rx.lock.acquire();
while (uart_rx.r == uart_rx.w)
{
- if (p->xstate != 0)
+ if (p->xstate)
{
uart_rx.lock.release();
+ cons.lock.release();
return -1;
}
+ cons.lock.release();
ProcManager::sleep(&uart_rx, &uart_rx.lock);
+ cons.lock.acquire();
}
- char c = uart_rx.buf[uart_rx.r % UART_RX_BUF_SIZE];
- uart_rx.r++;
-
+ char c = uart_rx.buf[uart_rx.r++ % UART_RX_BUF_SIZE];
uart_rx.lock.release();
- // 1. Handle Backspace (127 or \b)
if (c == 127 || c == '\b')
{
- if (target_idx > 0)
- {
- // Erase character from screen: Backspace, Space, Backspace
- uart_putc('\b');
- uart_putc(' ');
- uart_putc('\b');
- target_idx--;
- }
- uart_rx.lock.acquire();
- continue;
- }
-
- // 2. Handle Ctrl+U (Kill Line)
- if (c == 0x15)
- {
- while (target_idx > 0)
+ if (cons.e != cons.w)
{
+ cons.e--;
uart_putc('\b');
uart_putc(' ');
uart_putc('\b');
- target_idx--;
}
- uart_rx.lock.acquire();
- continue;
}
-
- // 3. Handle Ctrl+L (Clear Screen)
- if (c == 0x0C)
+ else
{
- uart_puts(ANSI_CLEAR);
- uart_puts("$ ");
- uart_rx.lock.acquire();
- continue;
- }
-
- // 4. Handle Return (CR -> LF)
- if (c == '\r')
- {
- c = '\n';
- }
+ if (c == '\r')
+ c = '\n';
- // Echo back to user
- // uart_putc(c);
+ uart_putc(c);
- if (VM::copyout(p->pagetable, target + target_idx, &c, 1) < 0)
- {
- return -1;
- }
-
- target_idx++;
+ cons.buf[cons.e++ % sizeof(cons.buf)] = c;
- if (c == '\n')
- {
- return target_idx;
+ if (c == '\n' || cons.e == cons.w + sizeof(cons.buf))
+ {
+ cons.w = cons.e;
+ ProcManager::wakeup(&cons);
+ }
}
-
- uart_rx.lock.acquire();
}
- uart_rx.lock.release();
+ cons.lock.release();
return target_idx;
}
} \ No newline at end of file