kernel.early-console is used to specify which output device the kernel boot log should be written to. the first thing the kernel does on boot after initialising the bootstrap processor is initialise the early console, making it useful for debugging problems that occur early in the boot process. this arg accepts a list of hard-coded values for output devices, such as tty0 for the display or ttyS0 for the serial port. the exact values supported will depend on the platform. once all drivers are loaded, the kernel switches to the device specified by kernel.console for output. unlike kernel.early-console, this arg specifies the name of a tty device in /dev/tty. this means that, not only are more devices supported (any device provided by a tty driver), but the kernel can also get input from the user using this console too (not used by the kernel itself, but will be used by the user to interact with userspace programs, like the shell).
146 lines
4.7 KiB
C
146 lines
4.7 KiB
C
#ifndef SOCKS_TTY_H_
|
|
#define SOCKS_TTY_H_
|
|
|
|
#include <socks/status.h>
|
|
#include <socks/device.h>
|
|
#include <socks/queue.h>
|
|
#include <socks/object.h>
|
|
#include <socks/termios.h>
|
|
#include <stdint.h>
|
|
|
|
#define TTY_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_CHAR ? (dev)->chr.c_tty : NULL)
|
|
#define TTY_DRIVER(drv) ((struct tty_driver *)((char *)drv - offsetof(struct tty_driver, tty_base)))
|
|
|
|
#define TTY_INPUT_QUEUE_SIZE 256
|
|
#define TTY_LINE_MAX 4096
|
|
|
|
struct kext;
|
|
|
|
/* The TTY system.
|
|
|
|
TTYs are an enhanced version of the console object. Rather than a simple output
|
|
device for log messages, TTYs are intended to support fully-featured interactive
|
|
user sessions, including advanced display manipulation (if applicable) and
|
|
buffered user input.
|
|
|
|
A TTY object is split into 2 parts:
|
|
- struct tty: This represents the terminal session, and tracks things like the cursor
|
|
position, input buffer, flags, etc.
|
|
- struct tty_driver: This is a set of function callbacks that the TTY can use to
|
|
manipulate the output device. This could represent a char-based framebuffer
|
|
device, a serial port, etc.
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
enum tty_driver_type {
|
|
/* For TTYs operating on simple IO devices like serial ports.
|
|
Allows writing characters, receiving characters, and not much else. */
|
|
TTY_DRIVER_SIMPLE,
|
|
/* For TTYs operating on more capable display interfaces.
|
|
Allows putting characters at arbitrary locations, scrolling, etc */
|
|
TTY_DRIVER_FULL,
|
|
};
|
|
|
|
/* TTY cursor status. The extra cursor styles are just for completeness,
|
|
the important one to support (if possible), is TTY_CURSOR_NONE.
|
|
The others can be interpreted as "just turn on a cursor of any style". */
|
|
enum tty_cursor {
|
|
TTY_CURSOR_ULINE,
|
|
TTY_CURSOR_BLOCK,
|
|
TTY_CURSOR_NONE,
|
|
};
|
|
|
|
/* direction to use for scrolling. The important one to support is
|
|
TTY_SCROLL_DOWN for when output overflows the display */
|
|
enum tty_scroll_dir {
|
|
TTY_SCROLL_DOWN,
|
|
TTY_SCROLL_UP,
|
|
};
|
|
|
|
enum tty_modifier_key {
|
|
TTY_KEY_OTHER = 0x00u,
|
|
TTY_KEY_CTRL = 0x01u,
|
|
TTY_KEY_ALT = 0x02u,
|
|
TTY_KEY_SHIFT = 0x04u,
|
|
};
|
|
|
|
/* character attribute. this could be as simple as VGA's 16-colour palette
|
|
plus an extra bit for bright, or a full 24-bit RGB value with bold and underline
|
|
support, depending on what the driver supports. */
|
|
typedef uint64_t tty_attrib_t;
|
|
|
|
struct tty_driver_ops {
|
|
void (*tty_init)(struct device *dev);
|
|
void (*tty_deinit)(struct device *dev);
|
|
void (*tty_clear)(struct device *dev, int x, int y, int width, int height);
|
|
void (*tty_putc)(struct device *dev, int c, int xpos, int ypos, tty_attrib_t attrib);
|
|
void (*tty_set_cursor)(struct device *dev, enum tty_cursor cur);
|
|
void (*tty_move_cursor)(struct device *dev, int x, int y);
|
|
void (*tty_scroll)(struct device *dev, enum tty_scroll_dir dir, int lines);
|
|
};
|
|
|
|
struct tty_driver {
|
|
struct driver tty_base;
|
|
|
|
char tty_name[16];
|
|
enum tty_driver_type tty_type;
|
|
struct queue_entry tty_head;
|
|
|
|
struct tty_driver_ops *tty_ops;
|
|
};
|
|
|
|
struct tty_ldisc {
|
|
char name[OBJECT_NAME_MAX];
|
|
kern_status_t(*read)(struct device *, void *, size_t, size_t *, socks_flags_t);
|
|
void(*write)(struct device *, const struct input_event *);
|
|
};
|
|
|
|
struct tty_device {
|
|
unsigned int tty_xcells, tty_ycells;
|
|
unsigned int tty_xcur, tty_ycur;
|
|
struct termios tty_config;
|
|
tty_attrib_t tty_curattrib;
|
|
|
|
enum tty_modifier_key tty_modstate;
|
|
|
|
struct tty_ldisc *tty_ldisc;
|
|
|
|
/* input characters processed from tty_events, returned by tty_read() */
|
|
struct ringbuffer tty_input;
|
|
char *tty_linebuf;
|
|
};
|
|
|
|
extern void register_tty_console(void);
|
|
extern void redirect_printk_to_tty(struct device *dest);
|
|
|
|
extern kern_status_t tty_bootstrap(void);
|
|
extern struct tty_ldisc *tty_default_line_discipline(void);
|
|
|
|
extern struct device *tty_device_create(void);
|
|
extern kern_status_t tty_device_register(struct device *dev, struct tty_driver *owner, struct device *parent);
|
|
|
|
extern void tty_set_foreground(struct device *tty);
|
|
extern kern_status_t tty_connect_foreground_input_device(struct device *input);
|
|
|
|
extern struct tty_driver *tty_driver_create(struct kext *self, const char *name);
|
|
extern kern_status_t tty_driver_destroy(struct tty_driver *drv);
|
|
extern kern_status_t tty_driver_register(struct tty_driver *drv);
|
|
extern kern_status_t tty_driver_unregister(struct tty_driver *drv);
|
|
static inline struct driver *tty_driver_base(struct tty_driver *drv)
|
|
{
|
|
return &drv->tty_base;
|
|
}
|
|
|
|
extern kern_status_t tty_read(struct device *tty, void *buf, size_t offset, size_t max, size_t *nr_read, socks_flags_t flags);
|
|
extern kern_status_t tty_write(struct device *tty, const void *buf, size_t offset, size_t len, size_t *nr_written, socks_flags_t flags);
|
|
extern kern_status_t tty_report_event(struct device *tty, const struct input_event *ev);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|