From: Minep Date: Mon, 11 Dec 2023 01:00:23 +0000 (+0000) Subject: Merge branch 'master' of github.com:Minep/lunaix-os X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/bef1210245bb3180a57f26405369654eaa477f63?hp=0165ff6162aa6546f9f471edff7eed8672c3159b Merge branch 'master' of github.com:Minep/lunaix-os --- diff --git a/README.md b/README.md index c161be6..f9e0e52 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,24 @@ make CX_PREFIX=i686-linux-gnu- all **※:由于在`-O2`模式下,GCC会进行CSE优化,这导致LunaixOS会出现一些非常奇怪、离谱的bug,从而影响到基本运行。具体原因有待调查。** +### 4.4 设置内核启动参数 + +在 make 的时候通过`CMDLINE`变量可以设置内核启动参数列表。该列表可以包含多个参数,通过一个或多个空格来分割。每个参数可以为键值对 `=` 或者是开关标志位 ``。目前 Lunaix 支持以下参数: + ++ `console=` 设置系统终端的输入输出设备(tty设备)。其中 `` 是设备文件路径 (注意,这里的设备文件路径是针对Lunaix,而非Linux)。关于LunaixOS设备文件系统的介绍可参考 Lunaix Wiki(WIP) + +如果`CMDLINE`未指定,则将会载入默认参数: + +``` +console=/dev/ttyFB0 +``` + +其中,`/dev/ttyFB0` 指向基于VGA文本模式的tty设备,也就是平时启动QEMU时看到的黑色窗口。 + +当然,读者也可以使用 `/dev/ttyS0` 来作为默认tty设备,来验证 Lunaix 的灵活性与兼容性。该路径指向第一个串口设备。可以通过telnet协议在`12345`端口上进行访问——端口号可以自行修改QEMU启动参数(位于:`makeinc/qemu.mkinc`)来变更。 + +**注意:** 根据操作系统和键盘布局的不同,telnet客户端对一些关键键位的映射(如退格,回车)可能有所差别(如某些版本的Linux会将退格键映射为`0x7f`,也就是ASCII的``字符,而非我们熟知`0x08`)。如果读者想要通过串口方式把玩Lunaix,请修改`usr/init/init.c`里面的终端初始化代码,将`VERASE`设置为正确的映射(修改方式可以参考 POSIX termios 的使用方式。由于Lunaix的终端接口的实现是完全兼容POSIX的,读者可以直接去查阅Linux自带的帮助`man termios`,无需作任何的转换) + ## 5. 运行,分支以及 Issue ### 5.1 虚拟磁盘(非必须) diff --git a/lunaix-os/GRUB_TEMPLATE b/lunaix-os/GRUB_TEMPLATE index c33d45f..db98366 100644 --- a/lunaix-os/GRUB_TEMPLATE +++ b/lunaix-os/GRUB_TEMPLATE @@ -2,6 +2,6 @@ default=0 timeout=0 menuentry "$_OS_NAME" { - multiboot /boot/kernel.bin console=/dev/vcon + multiboot /boot/kernel.bin $KCMD module --nounzip /boot/modksyms modksyms } \ No newline at end of file diff --git a/lunaix-os/config-grub.sh b/lunaix-os/config-grub.sh index ff4d4b6..956cb4f 100755 --- a/lunaix-os/config-grub.sh +++ b/lunaix-os/config-grub.sh @@ -1,5 +1,3 @@ #!/usr/bin/bash -export _OS_NAME=$1 - -cat GRUB_TEMPLATE | envsubst > "$2" \ No newline at end of file +cat GRUB_TEMPLATE | envsubst > "$1" \ No newline at end of file diff --git a/lunaix-os/hal/char/serial.c b/lunaix-os/hal/char/serial.c index 528f141..d93ff39 100644 --- a/lunaix-os/hal/char/serial.c +++ b/lunaix-os/hal/char/serial.c @@ -6,6 +6,7 @@ #include #include +#include #define lock_sdev(sdev) device_lock((sdev)->dev) #define unlock_sdev(sdev) device_unlock((sdev)->dev) @@ -143,41 +144,41 @@ serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len) } static int -__serial_read(struct device* dev, void* buf, size_t offset, size_t len) +__serial_read(struct device* dev, void* buf, off_t fpos, size_t len) { - return serial_readbuf(serial_device(dev), &((u8_t*)buf)[offset], len); + return serial_readbuf(serial_device(dev), (u8_t*)buf, len); } static int -__serial_read_async(struct device* dev, void* buf, size_t offset, size_t len) +__serial_read_async(struct device* dev, void* buf, off_t fpos, size_t len) { return serial_readbuf_nowait( - serial_device(dev), &((u8_t*)buf)[offset], len); + serial_device(dev), (u8_t*)buf, len); } static int -__serial_read_page(struct device* dev, void* buf, size_t offset) +__serial_read_page(struct device* dev, void* buf, off_t fpos) { - return serial_readbuf(serial_device(dev), &((u8_t*)buf)[offset], MEM_PAGE); + return serial_readbuf(serial_device(dev), (u8_t*)buf, MEM_PAGE); } static int -__serial_write(struct device* dev, void* buf, size_t offset, size_t len) +__serial_write(struct device* dev, void* buf, off_t fpos, size_t len) { - return serial_writebuf(serial_device(dev), &((u8_t*)buf)[offset], len); + return serial_writebuf(serial_device(dev), (u8_t*)buf, len); } static int -__serial_write_async(struct device* dev, void* buf, size_t offset, size_t len) +__serial_write_async(struct device* dev, void* buf, off_t fpos, size_t len) { return serial_writebuf_nowait( - serial_device(dev), &((u8_t*)buf)[offset], len); + serial_device(dev), (u8_t*)buf, len); } static int -__serial_write_page(struct device* dev, void* buf, size_t offset) +__serial_write_page(struct device* dev, void* buf, off_t fpos) { - return serial_writebuf(serial_device(dev), &((u8_t*)buf)[offset], MEM_PAGE); + return serial_writebuf(serial_device(dev), (u8_t*)buf, MEM_PAGE); } static int @@ -200,6 +201,38 @@ __serial_poll_event(struct device* dev) return sdev->dev->poll_evflags; } +static void sdev_execmd(struct serial_dev* sdev, u32_t req, ...) +{ + va_list args; + va_start(args, req); + + sdev->exec_cmd(sdev, req, args); + + va_end(args); +} + +static void +__serial_set_speed(struct device* dev, speed_t speed) +{ + struct serial_dev* sdev = serial_device(dev); + lock_sdev(sdev); + + sdev_execmd(sdev, SERIO_SETBRDIV, speed); + + unlock_sdev(sdev); +} + +static void +__serial_set_cntrl_mode(struct device* dev, tcflag_t cflag) +{ + struct serial_dev* sdev = serial_device(dev); + lock_sdev(sdev); + + sdev_execmd(sdev, SERIO_SETCNTRLMODE, cflag); + + unlock_sdev(sdev); +} + #define RXBUF_SIZE 512 struct serial_dev* @@ -215,18 +248,25 @@ serial_create(struct devclass* class, char* if_ident) dev->ops.write_page = __serial_write_page; dev->ops.exec_cmd = __serial_exec_command; dev->ops.poll = __serial_poll_event; - + sdev->dev = dev; dev->underlay = sdev; + struct termport_capability* tp_cap = + new_capability(TERMPORT_CAP, struct termport_capability); + tp_cap->set_speed = __serial_set_speed; + tp_cap->set_cntrl_mode = __serial_set_cntrl_mode; + waitq_init(&sdev->wq_rxdone); waitq_init(&sdev->wq_txdone); rbuffer_init(&sdev->rxbuf, valloc(RXBUF_SIZE), RXBUF_SIZE); llist_append(&serial_devs, &sdev->sdev_list); + + device_grant_capability(dev, cap_meta(tp_cap)); - register_device(dev, class, "port%s%d", if_ident, class->variant); + register_device(dev, class, "serial%d", class->variant); - sdev->at_term = term_create(dev, if_ident); + term_create(dev, if_ident); class->variant++; return sdev; diff --git a/lunaix-os/hal/char/uart/16550.h b/lunaix-os/hal/char/uart/16550.h index 1b903a7..ccee415 100644 --- a/lunaix-os/hal/char/uart/16550.h +++ b/lunaix-os/hal/char/uart/16550.h @@ -25,6 +25,11 @@ #define UART_rIE_ELSI (1 << 2) #define UART_rIE_EDSSI (1 << 3) +#define UART_rLC_STOPB (1 << 2) +#define UART_rLC_PAREN (1 << 3) +#define UART_rLC_PAREVN (1 << 4) +#define UART_rLC_SETBRK (1 << 6) + #define UART_rLS_THRE (1 << 5) #define UART_rLS_DR 1 #define UART_rLS_BI (1 << 4) @@ -65,6 +70,7 @@ struct uart16550 u8_t rie; u8_t rfc; u8_t rmc; + u8_t rlc; } cntl_save; u32_t (*read_reg)(struct uart16550* uart, ptr_t regoff); @@ -90,7 +96,13 @@ uart_clrie(struct uart16550* uart) static inline void uart_setie(struct uart16550* uart) { - uart->write_reg(uart, UART_rIE, uart->cntl_save.rie | 1); + uart->write_reg(uart, UART_rIE, uart->cntl_save.rie); +} + +static inline void +uart_setlc(struct uart16550* uart) +{ + uart->write_reg(uart, UART_rLC, uart->cntl_save.rlc); } struct uart16550* diff --git a/lunaix-os/hal/char/uart/16550_base.c b/lunaix-os/hal/char/uart/16550_base.c index 8ec752e..d78f3cf 100644 --- a/lunaix-os/hal/char/uart/16550_base.c +++ b/lunaix-os/hal/char/uart/16550_base.c @@ -2,6 +2,7 @@ #include #include +#include #include "16550.h" @@ -41,6 +42,22 @@ uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len) return RXTX_DONE; } +static void +uart_set_control_mode(struct uart16550* uart, tcflag_t cflags) +{ + uart->cntl_save.rie &= ~(UART_rIE_ERBFI | UART_rIE_EDSSI); + uart->cntl_save.rie |= (!(cflags & _CLOCAL)) * UART_rIE_EDSSI; + uart->cntl_save.rie |= (!!(cflags & _CREAD)) * UART_rIE_ERBFI; + uart_setie(uart); + + uart->cntl_save.rlc &= ~(UART_rLC_STOPB | UART_rLC_PAREN | UART_rLC_PAREVN | 0b11); + uart->cntl_save.rlc |= (!!(cflags & _CSTOPB)) * UART_rLC_STOPB; + uart->cntl_save.rlc |= (!!(cflags & _CPARENB)) * UART_rLC_PAREN; + uart->cntl_save.rlc |= (!(cflags & _CPARODD)) * UART_rLC_PAREVN; + uart->cntl_save.rlc |= (cflags & _CSZ_MASK) >> 2; + uart_setlc(uart); +} + int uart_general_exec_cmd(struct serial_dev* sdev, u32_t req, va_list args) { @@ -52,6 +69,12 @@ uart_general_exec_cmd(struct serial_dev* sdev, u32_t req, va_list args) case SERIO_RXDA: uart_clrie(uart); break; + case SERIO_SETBRDIV: + // TODO + break; + case SERIO_SETCNTRLMODE: + uart_set_control_mode(uart, va_arg(args, tcflag_t)); + break; default: return ENOTSUP; } @@ -92,6 +115,6 @@ done: serial_accept_buffer(pos->sdev, tmpbuf, i); serial_accept_one(pos->sdev, 0); - + serial_end_recv(pos->sdev); } diff --git a/lunaix-os/hal/term/console.c b/lunaix-os/hal/term/console.c index 4410358..7d9b57b 100644 --- a/lunaix-os/hal/term/console.c +++ b/lunaix-os/hal/term/console.c @@ -34,8 +34,12 @@ setup_default_tty() assert(device_addalias(NULL, dev_meta(dev), "tty")); - // TODO implement capability list - // for now, we just assume the parameter always pointed to valid device + if (!device_get_capability(dev, TERMIOS_CAP)) { + FATAL("not a terminal device: %s", console_dev); + } + + INFO("system console: %s", console_dev); + sysconsole = dev; } lunaix_initfn(setup_default_tty, call_on_boot); \ No newline at end of file diff --git a/lunaix-os/hal/term/lcntls/lcntl.c b/lunaix-os/hal/term/lcntls/lcntl.c index fdaf244..0802318 100644 --- a/lunaix-os/hal/term/lcntls/lcntl.c +++ b/lunaix-os/hal/term/lcntls/lcntl.c @@ -80,17 +80,17 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) } } + if (out) { + goto do_out; + } + if (c == '\n') { latest_eol = cooked->ptr + 1; - if (!out && (_lf & _ECHONL)) { + if ((_lf & _ECHONL)) { rbuffer_put(output, c); } } - if (out) { - goto do_out; - } - // For input procesing if (c == '\n' || c == EOL) { @@ -107,7 +107,8 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) } else if (c == SUSP) { raise_sig(tdev, lbuf, SIGSTOP); } else if (c == ERASE) { - rbuffer_erase(cooked); + if (!rbuffer_erase(cooked)) + continue; } else if (c == KILL) { // TODO shrink the rbuffer } else { @@ -146,7 +147,7 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) } } - if (!rbuffer_empty(output) && !(_lf & _NOFLSH)) { + if (!out && !rbuffer_empty(output) && !(_lf & _NOFLSH)) { term_flush(tdev); } diff --git a/lunaix-os/hal/term/term.c b/lunaix-os/hal/term/term.c index 160b629..3cc9741 100644 --- a/lunaix-os/hal/term/term.c +++ b/lunaix-os/hal/term/term.c @@ -76,27 +76,36 @@ term_exec_cmd(struct device* dev, u32_t req, va_list args) break; } case TDEV_TCGETATTR: { - struct _termios* tios = va_arg(args, struct _termios*); - *tios = (struct _termios){.c_oflag = term->oflags, + struct termios* tios = va_arg(args, struct termios*); + *tios = (struct termios){.c_oflag = term->oflags, .c_iflag = term->iflags, - .c_lflag = term->lflags}; + .c_lflag = term->lflags, + .c_cflag = term->cflags}; memcpy(tios->c_cc, term->cc, _NCCS * sizeof(cc_t)); tios->c_baud = term->iospeed; } break; case TDEV_TCSETATTR: { - struct _termios* tios = va_arg(args, struct _termios*); + struct termios* tios = va_arg(args, struct termios*); term->iflags = tios->c_iflag; term->oflags = tios->c_oflag; term->lflags = tios->c_lflag; memcpy(term->cc, tios->c_cc, _NCCS * sizeof(cc_t)); + tcflag_t old_cf = term->cflags; + term->cflags = tios->c_cflag; + + if (!term->tp_cap) { + goto done; + } + if (tios->c_baud != term->iospeed) { term->iospeed = tios->c_baud; - if (!term->chdev_ops.set_speed) { - goto done; - } - term->chdev_ops.set_speed(term->chdev, tios->c_baud); + term->tp_cap->set_speed(term->chdev, tios->c_baud); + } + + if (old_cf != tios->c_cflag) { + term->tp_cap->set_cntrl_mode(term->chdev, tios->c_cflag); } } break; default: @@ -110,14 +119,14 @@ done: } static int -tdev_do_write(struct device* dev, void* buf, size_t offset, size_t len) +tdev_do_write(struct device* dev, void* buf, off_t fpos, size_t len) { struct term* tdev = termdev(dev); lbuf_ref_t current = ref_current(&tdev->line_out); size_t wrsz = 0; while (wrsz < len) { wrsz += rbuffer_puts( - deref(current), &((char*)buf)[offset + wrsz], len - wrsz); + deref(current), &((char*)buf)[wrsz], len - wrsz); if (rbuffer_full(deref(current))) { term_flush(tdev); @@ -131,7 +140,7 @@ tdev_do_write(struct device* dev, void* buf, size_t offset, size_t len) } static int -tdev_do_read(struct device* dev, void* buf, size_t offset, size_t len) +tdev_do_read(struct device* dev, void* buf, off_t fpos, size_t len) { struct term* tdev = termdev(dev); lbuf_ref_t current = ref_current(&tdev->line_in); @@ -144,7 +153,7 @@ tdev_do_read(struct device* dev, void* buf, size_t offset, size_t len) } rdsz += rbuffer_gets( - deref(current), &((char*)buf)[offset + rdsz], len - rdsz); + deref(current), &((char*)buf)[rdsz], len - rdsz); } return rdsz; @@ -175,6 +184,7 @@ term_create(struct device* chardev, char* suffix) terminal->dev->ops.read = tdev_do_read; terminal->dev->ops.write = tdev_do_write; + terminal->dev->ops.exec_cmd = term_exec_cmd; // TODO choice of lcntl can be flexible terminal->lcntl = line_controls[ANSI_LCNTL]; @@ -189,6 +199,14 @@ term_create(struct device* chardev, char* suffix) register_device(terminal->dev, &termdev, "tty%d", termdev.variant++); } + struct capability_meta* termport_cap = device_get_capability(chardev, TERMPORT_CAP); + if (termport_cap) { + terminal->tp_cap = get_capability(termport_cap, struct termport_capability); + } + + struct capability_meta* term_cap = new_capability_marker(TERMIOS_CAP); + device_grant_capability(terminal->dev, term_cap); + load_default_setting(terminal); return terminal; diff --git a/lunaix-os/hal/term/term_io.c b/lunaix-os/hal/term/term_io.c index 8042e3b..835659d 100644 --- a/lunaix-os/hal/term/term_io.c +++ b/lunaix-os/hal/term/term_io.c @@ -33,7 +33,7 @@ do_read_raw(struct term* tdev) max_lb_sz -= sz; // TODO pass a flags to read to indicate it is non blocking ops - sz += chdev->ops.read_async(chdev, inbuffer, sz, max_lb_sz); + sz += chdev->ops.read_async(chdev, &inbuffer[sz], 0, max_lb_sz); } rbuffer_puts(line_in->next, inbuffer, sz); @@ -99,14 +99,14 @@ term_flush(struct term* tdev) struct linebuffer* line_out = &tdev->line_out; size_t xmit_len = line_out->current->len; - void* xmit_buf = line_out->next->buffer; + char* xmit_buf = line_out->next->buffer; rbuffer_gets(line_out->current, xmit_buf, xmit_len); off_t off = 0; int ret = 0; while (xmit_len && ret >= 0) { - ret = tdev->chdev->ops.write(tdev->chdev, xmit_buf, off, xmit_len); + ret = tdev->chdev->ops.write(tdev->chdev, &xmit_buf[off], 0, xmit_len); xmit_len -= ret; off += ret; } diff --git a/lunaix-os/includes/hal/serial.h b/lunaix-os/includes/hal/serial.h index c346c51..f65fd08 100644 --- a/lunaix-os/includes/hal/serial.h +++ b/lunaix-os/includes/hal/serial.h @@ -7,7 +7,7 @@ #include #include -#include +#include #define SERIAL_RW_RX 0x0 #define SERIAL_RW_TX 0x1 @@ -28,7 +28,6 @@ struct serial_dev struct device* dev; struct waitq wq_rxdone; struct waitq wq_txdone; - struct term* at_term; void* backend; struct rbuffer rxbuf; diff --git a/lunaix-os/includes/hal/term.h b/lunaix-os/includes/hal/term.h index 6b76db3..0f11e52 100644 --- a/lunaix-os/includes/hal/term.h +++ b/lunaix-os/includes/hal/term.h @@ -31,6 +31,29 @@ struct term_lcntl int (*process_and_put)(struct term*, struct linebuffer*, char); }; +/** + * @brief Communication port capability that a device is supported natively, + * or able to emulate low level serial transmission behaviour specify + * by POSIX1-2008, section 11. + * + */ +#define TERMPORT_CAP 0x4d524554U + +/** + * @brief A termios capability that a device provide interfaces which is + * compliant to POSIX1-2008 + * + */ +#define TERMIOS_CAP 0x534f4954U + +struct termport_capability +{ + CAPABILITY_META; + + void (*set_speed)(struct device*, speed_t); + void (*set_cntrl_mode)(struct device*, tcflag_t); +}; + struct term { struct device* dev; @@ -40,15 +63,13 @@ struct term struct linebuffer line_in; pid_t fggrp; - struct - { - int (*set_speed)(struct device*, speed_t); - } chdev_ops; + struct termport_capability* tp_cap; /* -- POSIX.1-2008 compliant fields -- */ tcflag_t iflags; tcflag_t oflags; tcflag_t lflags; + tcflag_t cflags; cc_t cc[_NCCS]; speed_t iospeed; }; diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index 05b8639..287cdad 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -100,6 +100,28 @@ #define DEV_IFSEQ 0x1 // sequential (character) device #define DEV_IFSYS 0x3 // a system device +struct capability_meta +{ + struct llist_header caps; + unsigned int cap_type; +}; + +#define CAPABILITY_META \ + union { \ + struct capability_meta cap_meta; \ + struct { \ + struct llist_header caps; \ + unsigned int cap_type; \ + }; \ + } + +#define get_capability(cap, cap_type) \ + container_of((cap), cap_type, cap_meta) +#define cap_meta(cap) (&(cap)->cap_meta) + +typedef struct llist_header capability_list_t; + + struct device_meta { u32_t magic; @@ -149,6 +171,8 @@ struct device DEVICE_METADATA; + capability_list_t capabilities; + /* -- device state -- */ mutex_t lock; @@ -324,6 +348,22 @@ device_populate_info(struct device* dev, struct dev_info* devinfo); void device_scan_drivers(); +/*------ Capability ------*/ + +struct capability_meta* +alloc_capability(int cap, unsigned int size); + +#define new_capability(cap_type, cap_impl)\ + ((cap_impl*)alloc_capability((cap_type), sizeof(cap_impl))) + +#define new_capability_marker(cap_type)\ + (alloc_capability((cap_type), sizeof(struct capability_meta))) + +void +device_grant_capability(struct device* dev, struct capability_meta* cap); + +struct capability_meta* +device_get_capability(struct device* dev, unsigned int cap_type); /*------ Load hooks ------*/ void diff --git a/lunaix-os/includes/lunaix/syslog.h b/lunaix-os/includes/lunaix/syslog.h index b372daa..4877857 100644 --- a/lunaix-os/includes/lunaix/syslog.h +++ b/lunaix-os/includes/lunaix/syslog.h @@ -29,6 +29,7 @@ } #define DEBUG(fmt, ...) kprintf(KDEBUG fmt, ##__VA_ARGS__) +#define INFO(fmt, ...) kprintf(KINFO fmt, ##__VA_ARGS__) #define WARN(fmt, ...) kprintf(KWARN fmt, ##__VA_ARGS__) #define ERROR(fmt, ...) kprintf(KERROR fmt, ##__VA_ARGS__) #define FATAL(fmt, ...) \ diff --git a/lunaix-os/includes/usr/lunaix/dirent_defs.h b/lunaix-os/includes/usr/lunaix/dirent_defs.h index 7792355..9142a4d 100644 --- a/lunaix-os/includes/usr/lunaix/dirent_defs.h +++ b/lunaix-os/includes/usr/lunaix/dirent_defs.h @@ -6,7 +6,7 @@ #define DT_FILE 0x0 #define DT_DIR 0x1 #define DT_SYMLINK 0x2 -#define DT_PIPE 0x2 +#define DT_PIPE 0x3 struct lx_dirent { diff --git a/lunaix-os/includes/usr/lunaix/serial.h b/lunaix-os/includes/usr/lunaix/serial.h index 7cdd74b..c01bb15 100644 --- a/lunaix-os/includes/usr/lunaix/serial.h +++ b/lunaix-os/includes/usr/lunaix/serial.h @@ -9,4 +9,7 @@ #define SERIO_TXEN IOREQ(3, 0) #define SERIO_TXDA IOREQ(4, 0) +#define SERIO_SETBRDIV IOREQ(5, 0) +#define SERIO_SETCNTRLMODE IOREQ(6, 0) + #endif /* __LUNAIX_USERIAL_H */ diff --git a/lunaix-os/includes/usr/lunaix/term.h b/lunaix-os/includes/usr/lunaix/term.h index 8866b30..b1f6c1f 100644 --- a/lunaix-os/includes/usr/lunaix/term.h +++ b/lunaix-os/includes/usr/lunaix/term.h @@ -67,6 +67,18 @@ #define _B19200 19200 #define _B38400 38400 +#define _CLOCAL 1 +#define _CREAD (1 << 1) +#define _CSZ_MASK (0b11 << 2) +#define _CS5 (0b00 << 2) +#define _CS6 (0b01 << 2) +#define _CS7 (0b10 << 2) +#define _CS8 (0b11 << 2) +#define _CSTOPB (1 << 4) +#define _CHUPCL (1 << 5) +#define _CPARENB (1 << 6) +#define _CPARODD (1 << 7) + #define _TCSANOW 1 #define _TCSADRAIN 2 #define _TCSAFLUSH 3 @@ -82,7 +94,7 @@ typedef int tcflag_t; typedef char cc_t; typedef unsigned int speed_t; -struct _termios +struct termios { tcflag_t c_iflag; tcflag_t c_oflag; diff --git a/lunaix-os/kernel/device/capability.c b/lunaix-os/kernel/device/capability.c new file mode 100644 index 0000000..b31f914 --- /dev/null +++ b/lunaix-os/kernel/device/capability.c @@ -0,0 +1,32 @@ +#include +#include + +struct capability_meta* +alloc_capability(int cap, unsigned int size) +{ + struct capability_meta* cm = (struct capability_meta*)vzalloc(size); + + cm->cap_type = cap; + + return cm; +} + +void +device_grant_capability(struct device* dev, struct capability_meta* cap) +{ + llist_append(&dev->capabilities, &cap->caps); +} + +struct capability_meta* +device_get_capability(struct device* dev, unsigned int cap_type) +{ + struct capability_meta *pos, *n; + + llist_for_each(pos, n, &dev->capabilities, caps) { + if (pos->cap_type == cap_type){ + return pos; + } + } + + return NULL; +} \ No newline at end of file diff --git a/lunaix-os/kernel/device/device.c b/lunaix-os/kernel/device/device.c index b88f8f6..d3552c6 100644 --- a/lunaix-os/kernel/device/device.c +++ b/lunaix-os/kernel/device/device.c @@ -77,6 +77,7 @@ device_create(struct device* dev, dev->dev_type = type; device_init_meta(dev_meta(dev), parent, DEV_STRUCT); + llist_init_head(&dev->capabilities); mutex_init(&dev->lock); iopoll_init_evt_q(&dev->pollers); } @@ -299,9 +300,9 @@ __DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args) goto done; } - struct device* dev = (struct device*)fd_s->file->inode->data; - if (valid_device_subtype_ref(dev, DEV_STRUCT)) { - errno &= ENODEV; + struct device* dev = resolve_device(fd_s->file->inode->data); + if (!valid_device_subtype_ref(dev, DEV_STRUCT)) { + errno = ENODEV; goto done; } @@ -312,11 +313,11 @@ __DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args) } if (!dev->ops.exec_cmd) { - errno &= ENOTSUP; + errno = ENOTSUP; goto done; } - errno &= dev->ops.exec_cmd(dev, req, args); + errno = dev->ops.exec_cmd(dev, req, args); done: return DO_STATUS_OR_RETURN(errno); diff --git a/lunaix-os/kernel/ds/rbuffer.c b/lunaix-os/kernel/ds/rbuffer.c index bfcc3a5..ab4dea5 100644 --- a/lunaix-os/kernel/ds/rbuffer.c +++ b/lunaix-os/kernel/ds/rbuffer.c @@ -63,7 +63,7 @@ rbuffer_puts(struct rbuffer* rb, char* buf, size_t len) int rbuffer_gets(struct rbuffer* rb, char* buf, size_t len) { - if (!len) + if (!len || !rb->len) return 0; size_t nlen = MIN(len, rb->len); diff --git a/lunaix-os/kernel/fs/mount.c b/lunaix-os/kernel/fs/mount.c index 96cc741..2b996d4 100644 --- a/lunaix-os/kernel/fs/mount.c +++ b/lunaix-os/kernel/fs/mount.c @@ -63,6 +63,8 @@ __vfs_do_unmount(struct v_mount* mnt) mnt_chillax(mnt->parent); + mnt->mnt_point->mnt = mnt->parent; + vfs_sb_free(sb); atomic_fetch_sub(&mnt->mnt_point->ref_count, 1); vfree(mnt); @@ -249,6 +251,11 @@ __DEFINE_LXSYSCALL4(int, goto done; } + if (mnt->mnt->mnt_point == mnt) { + errno = EBUSY; + goto done; + } + // By our convention. // XXX could we do better? struct device* device = NULL; diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index 80d2036..28cede5 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -708,7 +708,7 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count) file->inode->atime = clock_unixtime(); if ((file->inode->itype & VFS_IFSEQDEV) || (fd_s->flags & FO_DIRECT)) { - errno = file->ops->read(file->inode, buf, count, file->f_pos); + errno = file->ops->read(file->inode, buf, count, file->f_pos); } else { errno = pcache_read(file->inode, buf, count, file->f_pos); } @@ -860,7 +860,7 @@ vfs_readlink(struct v_dnode* dnode, char* buf, size_t size) int vfs_get_dtype(int itype) { - if ((itype & VFS_IFSYMLINK)) { + if ((itype & VFS_IFSYMLINK) == VFS_IFSYMLINK) { return DT_SYMLINK; } else if (!(itype & VFS_IFFILE)) { return DT_DIR; @@ -1003,6 +1003,11 @@ __DEFINE_LXSYSCALL1(int, mkdir, const char*, path) goto done; } + if (!(errno = vfs_walk(parent, name_value, &dir, NULL, 0))) { + errno = EEXIST; + goto done; + } + if ((errno = vfs_check_writable(parent))) { goto done; } diff --git a/lunaix-os/kernel/tty/lxconsole.c b/lunaix-os/kernel/tty/lxconsole.c index cf2d43c..2540077 100644 --- a/lunaix-os/kernel/tty/lxconsole.c +++ b/lunaix-os/kernel/tty/lxconsole.c @@ -23,6 +23,8 @@ #include #include +#include + static struct console lx_console; int @@ -38,24 +40,16 @@ void console_flush(); static waitq_t lx_reader; -static volatile char ttychr; static volatile pid_t fg_pgid = 0; -static inline void -print_control_code(const char cntrl) -{ - console_write_char('^'); - console_write_char(cntrl + 64); -} - int __lxconsole_listener(struct input_device* dev) { u32_t key = dev->current_pkt.sys_code; u32_t type = dev->current_pkt.pkt_type; kbd_kstate_t state = key >> 16; - ttychr = key & 0xff; + u8_t ttychr = key & 0xff; key = key & 0xffff; if (type == PKT_RELEASE) { @@ -68,18 +62,6 @@ __lxconsole_listener(struct input_device* dev) goto done; } ttychr = cntrl - 'a' + 1; - switch (ttychr) { - case TCINTR: - signal_send(-fg_pgid, _SIGINT); - print_control_code(ttychr); - break; - case TCSTOP: - signal_send(-fg_pgid, _SIGSTOP); - print_control_code(ttychr); - break; - default: - break; - } } else if (key == KEY_PG_UP) { console_view_up(); goto done; @@ -92,6 +74,7 @@ __lxconsole_listener(struct input_device* dev) goto done; } + fifo_putone(&lx_console.input, ttychr); pwake_all(&lx_reader); done: @@ -161,40 +144,11 @@ __tty_read(struct device* dev, void* buf, size_t offset, size_t len) struct console* console = (struct console*)dev->underlay; size_t count = fifo_read(&console->input, buf, len); - if (count > 0 && ((char*)buf)[count - 1] == '\n') { + if (count > 0) { return count; } - while (count < len) { - pwait(&lx_reader); - - if (ttychr < 0x1B) { - // ASCII control codes - switch (ttychr) { - case TCINTR: - fifo_clear(&console->input); - return 0; - case TCBS: - if (fifo_backone(&console->input)) { - console_write_char(ttychr); - } - continue; - case TCLF: - case TCCR: - goto proceed; - default: - break; - } - print_control_code(ttychr); - continue; - } - - proceed: - console_write_char(ttychr); - if (!fifo_putone(&console->input, ttychr) || ttychr == '\n') { - break; - } - } + pwait(&lx_reader); return count + fifo_read(&console->input, buf + count, len - count); } @@ -355,12 +309,14 @@ lxconsole_spawn_ttydev(struct device_def* devdef) register_device(tty_dev, &devdef->class, "vcon"); + term_create(tty_dev, "FB"); + return 0; } static struct device_def lxconsole_def = { .name = "Lunaix Virtual Console", - .class = DEVCLASSV(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 12), + .class = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN), .init = lxconsole_spawn_ttydev }; // FIXME diff --git a/lunaix-os/makefile b/lunaix-os/makefile index 4e0ea86..c332bf7 100644 --- a/lunaix-os/makefile +++ b/lunaix-os/makefile @@ -10,6 +10,8 @@ export ARCH DEPS := $(CC) $(LD) $(AR) xorriso grub-mkrescue +CMDLINE ?= console=/dev/ttyFB0 + kbuild_dir := build kbin_dir := $(kbuild_dir)/bin os_img_dir := $(kbuild_dir)/img @@ -45,9 +47,11 @@ kernel: @$(MAKE) $(MKFLAGS) -I $(mkinc_dir) -f kernel.mk all .PHONY: image +export KCMD=$(CMDLINE) +export _OS_NAME=$(OS_NAME) image: usr/build kernel $(call status,TASK,$(notdir $@)) - @./config-grub.sh ${OS_NAME} $(os_img_dir)/boot/grub/grub.cfg + @./config-grub.sh $(os_img_dir)/boot/grub/grub.cfg @cp -r usr/build/* $(os_img_dir)/usr @cp -r $(kbin_dir)/* $(os_img_dir)/boot @grub-mkrescue -o $(kimg) $(os_img_dir) -- -volid "$(OS_ID) $(OS_VER)" -system_id "$(OS_NAME)" @@ -92,7 +96,6 @@ debug-qemu: all-debug @QMPORT=$(QEMU_MON_PORT) gdb $(kbin) -ex "target remote localhost:1234" debug-qemu-vscode: all-debug - @i686-elf-objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg @qemu-system-i386 $(call get_qemu_options,$(kimg)) @sleep 0.5 @telnet 127.0.0.1 $(QEMU_MON_PORT) diff --git a/lunaix-os/usr/cat/main.c b/lunaix-os/usr/cat/main.c index 0a15f8c..9f0d35b 100644 --- a/lunaix-os/usr/cat/main.c +++ b/lunaix-os/usr/cat/main.c @@ -11,14 +11,26 @@ int main(int argc, const char* argv[]) { int fd = 0; - unsigned int size = 0; + int size = 0; + struct file_stat stat; for (int i = 1; i < argc; i++) { fd = open(argv[i], FO_RDONLY); + if (fd < 0) { printf("open failed: %s (error: %d)", argv[i], fd); continue; } + if (fstat(fd, &stat) < 0) { + printf("fail to get stat %d\n", errno); + return 1; + } + + if (!(stat.mode & F_MFILE)) { + printf("%s is a directory", argv[i]); + return 1; + } + do { size = read(fd, buffer, BUFSIZE); write(stdout, buffer, size); diff --git a/lunaix-os/usr/init/init.c b/lunaix-os/usr/init/init.c index 1b80f49..0a2f541 100644 --- a/lunaix-os/usr/init/init.c +++ b/lunaix-os/usr/init/init.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -14,6 +15,32 @@ } \ } while (0) +#define check(statement) \ + do { \ + int err = 0; \ + if ((err = (statement))) { \ + syslog(2, #statement " failed: %d", err); \ + return err; \ + } \ + } while (0) + +int +init_termios(int fd) { + struct termios term; + + check(tcgetattr(fd, &term)); + + term.c_lflag = ICANON | IEXTEN | ISIG | ECHO | ECHOE | ECHONL; + term.c_iflag = ICRNL | IGNBRK; + term.c_oflag = ONLCR | OPOST; + term.c_cflag = CREAD | CLOCAL | CS8 | CPARENB; + term.c_cc[VERASE] = 0x08; + + check(tcsetattr(fd, 0, &term)); + + return 0; +} + int main(int argc, const char** argv) { @@ -32,6 +59,8 @@ main(int argc, const char** argv) return err; } + check(init_termios(err)); + if ((err = dup(err)) < 0) { syslog(2, "fail to setup tty i/o (%d)\n", errno); return err; diff --git a/lunaix-os/usr/libc/includes/termios.h b/lunaix-os/usr/libc/includes/termios.h new file mode 100644 index 0000000..42ad0ac --- /dev/null +++ b/lunaix-os/usr/libc/includes/termios.h @@ -0,0 +1,114 @@ +#ifndef __LUNAIX_TERMIOS_H +#define __LUNAIX_TERMIOS_H + +#include + +#define BRKINT _BRKINT +#define ICRNL _ICRNL +#define IGNBRK _IGNBRK +#define IGNCR _IGNCR +#define IGNPAR _IGNPAR +#define INLCR _INLCR +#define INPCK _INPCK +#define ISTRIP _ISTRIP +#define IUCLC _IUCLC +#define IXANY _IXANY +#define IXOFF _IXOFF +#define IXON _IXON +#define PARMRK _PARMRK + +#define OPOST _OPOST +#define OCRNL _OCRNL + +// 2 +// 3 +// 4 + +#define ONLRET _ONLRET +#define ONLCR _ONLCR + +// 7 + +#define OLCUC _OLCUC + +#define ECHO _ECHO +#define ECHOE _ECHOE +#define ECHOK _ECHOK +#define ECHONL _ECHONL +#define ICANON _ICANON +#define ISIG _ISIG +#define IEXTEN _IEXTEN +#define NOFLSH _NOFLSH + +#define VEOF _VEOF +#define VEOL _VEOL +#define VERASE _VERASE +#define VINTR _VINTR +#define VKILL _VKILL +#define VQUIT _VQUIT +#define VSUSP _VSUSP +#define VSTART _VSTART +#define VSTOP _VSTOP +#define VMIN _VMIN +#define VTIME _VTIME +#define NCCS _NCCS + +#define B50 _B50 +#define B75 _B75 +#define B110 _B110 +#define B134 _B134 +#define B150 _B150 +#define B200 _B200 +#define B300 _B300 +#define B600 _B600 +#define B1200 _B1200 +#define B1800 _B1800 +#define B2400 _B2400 +#define B4800 _B4800 +#define B9600 _B9600 +#define B19200 _B19200 +#define B38400 _B38400 + +#define CLOCAL _CLOCAL +#define CREAD _CREAD +#define CS5 _CS5 +#define CS6 _CS6 +#define CS7 _CS7 +#define CS8 _CS8 +#define CSTOPB _CSTOPB +#define CHUPCL _CHUPCL +#define CPARENB _CPARENB +#define CPARODD _CPARODD + +#define TCSANOW _TCSANOW +#define TCSADRAIN _TCSADRAIN +#define TCSAFLUSH _TCSAFLUSH + +static inline speed_t cfgetispeed(const struct termios* termios) { return termios->c_baud; } +static inline speed_t cfgetospeed(const struct termios* termios) { return termios->c_baud; } + +static inline int cfsetispeed(struct termios* termios, speed_t baud) +{ + termios->c_baud = baud; + return 0; +} + +static inline int cfsetospeed(struct termios* termios, speed_t baud) +{ + termios->c_baud = baud; + return 0; +} + + +// TODO +//int tcdrain(int); +//int tcflow(int, int); +//int tcflush(int, int); +// pid_t tcgetsid(int); + +int tcgetattr(int, struct termios *); +int tcsendbreak(int, int); +int tcsetattr(int, int, const struct termios *); + + +#endif /* __LUNAIX_TERMIOS_H */ diff --git a/lunaix-os/usr/libc/src/termios.c b/lunaix-os/usr/libc/src/termios.c new file mode 100644 index 0000000..52c97e4 --- /dev/null +++ b/lunaix-os/usr/libc/src/termios.c @@ -0,0 +1,22 @@ +#include +#include + +int +tcgetattr(int fd, struct termios* termios_p) +{ + return ioctl(fd, TDEV_TCGETATTR, termios_p); +} + + +int +tcsendbreak(int fd, int ) +{ + // TODO + return 0; +} + +int +tcsetattr(int fd, int optional_actions, const struct termios* termios_p) +{ + return ioctl(fd, TDEV_TCSETATTR, termios_p); +} diff --git a/lunaix-os/usr/ls/ls.c b/lunaix-os/usr/ls/ls.c index 646dd6b..ece96e4 100644 --- a/lunaix-os/usr/ls/ls.c +++ b/lunaix-os/usr/ls/ls.c @@ -20,9 +20,9 @@ main(int argc, const char* argv[]) while ((dent = readdir(dir))) { if (dent->d_type == DT_DIR) { - printf(" \033[3m%s\033[39;49m\n", dent->d_name); + printf(" %s\n", dent->d_name); } else if (dent->d_type == DT_SYMLINK) { - printf(" \033[13m%s@\033[39;49m\n", dent->d_name); + printf(" %s@\n", dent->d_name); } else { printf(" %s\n", dent->d_name); } diff --git a/lunaix-os/usr/sh/sh.c b/lunaix-os/usr/sh/sh.c index 4a924db..2c9bb8d 100644 --- a/lunaix-os/usr/sh/sh.c +++ b/lunaix-os/usr/sh/sh.c @@ -143,7 +143,7 @@ sh_loop() while (1) { getcwd(pwd, 512); - printf("[\033[2m%s\033[39;49m]$ ", pwd); + printf("[%s]$ ", pwd); int sz = read(stdin, buf, 511); if (sz < 0) {