kexts: add generic vga/fb tty driver
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#include <socks/pmap.h>
|
#include <socks/pmap.h>
|
||||||
#include <socks/device.h>
|
#include <socks/device.h>
|
||||||
|
#include <socks/tty.h>
|
||||||
#include <socks/kext.h>
|
#include <socks/kext.h>
|
||||||
#include <socks/clock.h>
|
#include <socks/clock.h>
|
||||||
#include <socks/types.h>
|
#include <socks/types.h>
|
||||||
@@ -20,6 +21,10 @@
|
|||||||
#include <arch/acpi.h>
|
#include <arch/acpi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON
|
||||||
|
#include <socks/fbcon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PTR32(x) ((void *)((uintptr_t)(x)))
|
#define PTR32(x) ((void *)((uintptr_t)(x)))
|
||||||
|
|
||||||
static ml_cpu_block g_bootstrap_cpu = {0};
|
static ml_cpu_block g_bootstrap_cpu = {0};
|
||||||
@@ -56,6 +61,8 @@ static void init_bootfb(multiboot_info_t *mb)
|
|||||||
__bootfb_varinfo.fb_bpp = mb->framebuffer_bpp;
|
__bootfb_varinfo.fb_bpp = mb->framebuffer_bpp;
|
||||||
__bootfb_varinfo.fb_stride = mb->framebuffer_pitch;
|
__bootfb_varinfo.fb_stride = mb->framebuffer_pitch;
|
||||||
|
|
||||||
|
__bootfb_fixedinfo.fb_baseptr = mb->framebuffer_addr;
|
||||||
|
|
||||||
switch (mb->framebuffer_type) {
|
switch (mb->framebuffer_type) {
|
||||||
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
|
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
|
||||||
__bootfb_varinfo.fb_flags = FB_MODE_PALETTE;
|
__bootfb_varinfo.fb_flags = FB_MODE_PALETTE;
|
||||||
@@ -77,6 +84,7 @@ static void init_bootfb(multiboot_info_t *mb)
|
|||||||
__bootfb_varinfo.fb_alpha.b_offset = 0;
|
__bootfb_varinfo.fb_alpha.b_offset = 0;
|
||||||
break;
|
break;
|
||||||
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
|
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
|
||||||
|
__bootfb_fixedinfo.fb_baseptr = 0xb8000;
|
||||||
__bootfb_varinfo.fb_flags = FB_MODE_VGATEXT;
|
__bootfb_varinfo.fb_flags = FB_MODE_VGATEXT;
|
||||||
__bootfb_varinfo.fb_xcells = 80;
|
__bootfb_varinfo.fb_xcells = 80;
|
||||||
__bootfb_varinfo.fb_ycells = 25;
|
__bootfb_varinfo.fb_ycells = 25;
|
||||||
@@ -84,8 +92,6 @@ static void init_bootfb(multiboot_info_t *mb)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
__bootfb_fixedinfo.fb_baseptr = mb->framebuffer_addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void use_uniprocessor_topology(void)
|
static void use_uniprocessor_topology(void)
|
||||||
@@ -101,7 +107,7 @@ int ml_init(uintptr_t arg)
|
|||||||
init_bootfb(mb);
|
init_bootfb(mb);
|
||||||
|
|
||||||
bootstrap_cpu_init();
|
bootstrap_cpu_init();
|
||||||
vgacon_init();
|
early_vgacon_init();
|
||||||
serialcon_init(115200);
|
serialcon_init(115200);
|
||||||
clock_calibrate(500);
|
clock_calibrate(500);
|
||||||
|
|
||||||
@@ -148,6 +154,8 @@ int ml_init(uintptr_t arg)
|
|||||||
acpi_init();
|
acpi_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
tty_init();
|
||||||
|
|
||||||
ml_int_enable();
|
ml_int_enable();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
10
kexts/drivers/tty/fbcon/extension.yaml
Normal file
10
kexts/drivers/tty/fbcon/extension.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name: fbcon
|
||||||
|
description: |
|
||||||
|
VGA/Framebuffer kernel console.
|
||||||
|
id: net.doorstuck.socks.fbcon
|
||||||
|
license: BSD-3-Clause
|
||||||
|
copyright: Copyright © Max Wash 2023
|
||||||
|
sources:
|
||||||
|
- main.c
|
||||||
|
- fbcon.c
|
||||||
|
- vgacon.c
|
||||||
91
kexts/drivers/tty/fbcon/fbcon.c
Normal file
91
kexts/drivers/tty/fbcon/fbcon.c
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include <socks/tty.h>
|
||||||
|
#include "fbcon.h"
|
||||||
|
|
||||||
|
#define CELL_WIDTH 8
|
||||||
|
#define CELL_HEIGHT 16
|
||||||
|
|
||||||
|
static void fbcon_init(struct device *dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fbcon_deinit(struct device *dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fbcon_clear(struct device *dev, int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fbcon_putc(struct device *dev, int c, int xpos, int ypos, tty_attrib_t attrib)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fbcon_set_cursor(struct device *dev, enum tty_cursor cur)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fbcon_move_cursor(struct device *dev, int x, int y)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fbcon_scroll(struct device *dev, enum tty_scroll_dir dir, int lines)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct tty_driver_ops fbcon_ops = {
|
||||||
|
.tty_init = fbcon_init,
|
||||||
|
.tty_deinit = fbcon_deinit,
|
||||||
|
.tty_clear = fbcon_clear,
|
||||||
|
.tty_putc = fbcon_putc,
|
||||||
|
.tty_set_cursor = fbcon_set_cursor,
|
||||||
|
.tty_move_cursor = fbcon_move_cursor,
|
||||||
|
.tty_scroll = fbcon_scroll,
|
||||||
|
};
|
||||||
|
|
||||||
|
kern_status_t init_fbcon_console(struct device *tty, struct device *fb)
|
||||||
|
{
|
||||||
|
struct char_device *cdev = CHAR_DEVICE(tty);
|
||||||
|
struct framebuffer_varinfo fb_mode;
|
||||||
|
struct framebuffer_fixedinfo fixedinfo;
|
||||||
|
struct tty_device *ttydev = cdev->c_tty;
|
||||||
|
|
||||||
|
struct fbcon_priv *priv = kmalloc(sizeof *priv, VM_NORMAL);
|
||||||
|
if (!priv) {
|
||||||
|
return KERN_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t status = framebuffer_get_varinfo(fb, &fb_mode);
|
||||||
|
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
kfree(priv);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = framebuffer_get_fixedinfo(fb, &fixedinfo);
|
||||||
|
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
kfree(priv);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ttydev->tty_xcells = fb_mode.fb_xres / CELL_WIDTH;
|
||||||
|
ttydev->tty_ycells = fb_mode.fb_yres / CELL_HEIGHT;
|
||||||
|
ttydev->tty_xcur = 0;
|
||||||
|
ttydev->tty_ycur = 0;
|
||||||
|
|
||||||
|
priv->fbdev = fb;
|
||||||
|
priv->fb_pitch = fb_mode.fb_stride;
|
||||||
|
priv->fb_pixels = vm_phys_to_virt(fixedinfo.fb_baseptr);
|
||||||
|
priv->tty_ops = &fbcon_ops;
|
||||||
|
tty->dev_priv = priv;
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
24
kexts/drivers/tty/fbcon/fbcon.h
Normal file
24
kexts/drivers/tty/fbcon/fbcon.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef FBCON_H_
|
||||||
|
#define FBCON_H_
|
||||||
|
|
||||||
|
#include <socks/status.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct fbcon_priv {
|
||||||
|
struct device *fbdev;
|
||||||
|
union {
|
||||||
|
uint32_t *fb_pixels;
|
||||||
|
uint16_t *fb_cells;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned long fb_pitch;
|
||||||
|
struct tty_driver_ops *tty_ops;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct device;
|
||||||
|
struct tty_driver_ops;
|
||||||
|
|
||||||
|
extern kern_status_t init_fbcon_console(struct device *tty, struct device *fb);
|
||||||
|
extern kern_status_t init_vgacon_console(struct device *tty, struct device *fb);
|
||||||
|
|
||||||
|
#endif
|
||||||
11
kexts/drivers/tty/fbcon/include/socks/fbcon.h
Normal file
11
kexts/drivers/tty/fbcon/include/socks/fbcon.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef SOCKS_FBCON_H_
|
||||||
|
#define SOCKS_FBCON_H_
|
||||||
|
|
||||||
|
#include <socks/status.h>
|
||||||
|
|
||||||
|
struct device;
|
||||||
|
|
||||||
|
extern kern_status_t start_console_on_framebuffer(struct device *fb);
|
||||||
|
extern void early_vgacon_init(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
110
kexts/drivers/tty/fbcon/main.c
Normal file
110
kexts/drivers/tty/fbcon/main.c
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#include <socks/printk.h>
|
||||||
|
#include <socks/device.h>
|
||||||
|
#include <socks/kext.h>
|
||||||
|
#include <socks/tty.h>
|
||||||
|
#include <socks/libc/stdio.h>
|
||||||
|
#include "fbcon.h"
|
||||||
|
|
||||||
|
static struct tty_driver *fbcon_driver = NULL;
|
||||||
|
static struct device *tty0 = NULL;
|
||||||
|
|
||||||
|
static void tty_console_write(struct console *con, const char *s, unsigned int len)
|
||||||
|
{
|
||||||
|
if (!tty0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tty_console_read(struct console *con, char *s, unsigned int len)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct console tty_console = {
|
||||||
|
.c_name = "tty0",
|
||||||
|
.c_write = tty_console_write,
|
||||||
|
.c_read = tty_console_read,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void tty_clear(struct device *dev, int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
struct fbcon_priv *priv = dev->dev_priv;
|
||||||
|
priv->tty_ops->tty_clear(dev, x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tty_putc(struct device *dev, int c, int xpos, int ypos, tty_attrib_t attrib)
|
||||||
|
{
|
||||||
|
struct fbcon_priv *priv = dev->dev_priv;
|
||||||
|
priv->tty_ops->tty_putc(dev, c, xpos, ypos, attrib);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tty_set_cursor(struct device *dev, enum tty_cursor cur)
|
||||||
|
{
|
||||||
|
struct fbcon_priv *priv = dev->dev_priv;
|
||||||
|
priv->tty_ops->tty_set_cursor(dev, cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tty_move_cursor(struct device *dev, int x, int y)
|
||||||
|
{
|
||||||
|
struct fbcon_priv *priv = dev->dev_priv;
|
||||||
|
priv->tty_ops->tty_move_cursor(dev, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tty_scroll(struct device *dev, enum tty_scroll_dir dir, int lines)
|
||||||
|
{
|
||||||
|
struct fbcon_priv *priv = dev->dev_priv;
|
||||||
|
priv->tty_ops->tty_scroll(dev, dir, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct tty_driver_ops tty_ops = {
|
||||||
|
.tty_clear = tty_clear,
|
||||||
|
.tty_putc = tty_putc,
|
||||||
|
.tty_set_cursor = tty_set_cursor,
|
||||||
|
.tty_move_cursor = tty_move_cursor,
|
||||||
|
.tty_scroll = tty_scroll,
|
||||||
|
};
|
||||||
|
|
||||||
|
static kern_status_t online(struct kext *self)
|
||||||
|
{
|
||||||
|
fbcon_driver = tty_driver_create(self, "tty");
|
||||||
|
if (!fbcon_driver) {
|
||||||
|
return KERN_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fbcon_driver->tty_ops = &tty_ops;
|
||||||
|
|
||||||
|
tty_driver_register(fbcon_driver);
|
||||||
|
console_register(&tty_console);
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t start_console_on_framebuffer(struct device *fb)
|
||||||
|
{
|
||||||
|
struct framebuffer_varinfo fb_mode;
|
||||||
|
framebuffer_get_varinfo(fb, &fb_mode);
|
||||||
|
|
||||||
|
struct device *tty = tty_device_create();
|
||||||
|
|
||||||
|
kern_status_t status;
|
||||||
|
if (fb_mode.fb_flags & FB_MODE_VGATEXT) {
|
||||||
|
status = init_vgacon_console(tty, fb);
|
||||||
|
} else {
|
||||||
|
status = init_fbcon_console(tty, fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
/* TODO destroy tty device */
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tty0) {
|
||||||
|
tty0 = tty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_KEXT("net.doorstuck.socks.fbcon",
|
||||||
|
online, NULL,
|
||||||
|
KEXT_NO_DEPENDENCIES);
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <socks/tty.h>
|
||||||
#include <arch/serial.h>
|
#include <arch/serial.h>
|
||||||
#include <socks/libc/string.h>
|
#include <socks/libc/string.h>
|
||||||
#include <socks/libc/ctype.h>
|
#include <socks/libc/ctype.h>
|
||||||
@@ -6,6 +7,7 @@
|
|||||||
#include <socks/vm.h>
|
#include <socks/vm.h>
|
||||||
#include <socks/printk.h>
|
#include <socks/printk.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "fbcon.h"
|
||||||
|
|
||||||
#define VGA_PORT_CMD 0x3D4
|
#define VGA_PORT_CMD 0x3D4
|
||||||
#define VGA_PORT_DATA 0x3D5
|
#define VGA_PORT_DATA 0x3D5
|
||||||
@@ -108,14 +110,14 @@ static void vgacon_write(struct console *con, const char *s, unsigned int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct console vgacon = {
|
static struct console early_vgacon = {
|
||||||
.c_name = "vgacon",
|
.c_name = "vgacon",
|
||||||
.c_flags = CON_BOOT,
|
.c_flags = CON_BOOT,
|
||||||
.c_write = vgacon_write,
|
.c_write = vgacon_write,
|
||||||
.c_lock = SPIN_LOCK_INIT,
|
.c_lock = SPIN_LOCK_INIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
void vgacon_init(void)
|
void early_vgacon_init(void)
|
||||||
{
|
{
|
||||||
g_console_cursor_xpos = 0;
|
g_console_cursor_xpos = 0;
|
||||||
g_console_cursor_ypos = 0;
|
g_console_cursor_ypos = 0;
|
||||||
@@ -127,6 +129,92 @@ void vgacon_init(void)
|
|||||||
init_vga_cursor();
|
init_vga_cursor();
|
||||||
move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos);
|
move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos);
|
||||||
|
|
||||||
console_register(&vgacon);
|
console_register(&early_vgacon);
|
||||||
early_printk_init(&vgacon);
|
early_printk_init(&early_vgacon);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vgacon_init(struct device *dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vgacon_deinit(struct device *dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vgacon_clear(struct device *dev, int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vgacon_putc(struct device *dev, int c, int xpos, int ypos, tty_attrib_t attrib)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vgacon_set_cursor(struct device *dev, enum tty_cursor cur)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vgacon_move_cursor(struct device *dev, int x, int y)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vgacon_scroll(struct device *dev, enum tty_scroll_dir dir, int lines)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct tty_driver_ops vgacon_ops = {
|
||||||
|
.tty_init = vgacon_init,
|
||||||
|
.tty_deinit = vgacon_deinit,
|
||||||
|
.tty_clear = vgacon_clear,
|
||||||
|
.tty_putc = vgacon_putc,
|
||||||
|
.tty_set_cursor = vgacon_set_cursor,
|
||||||
|
.tty_move_cursor = vgacon_move_cursor,
|
||||||
|
.tty_scroll = vgacon_scroll,
|
||||||
|
};
|
||||||
|
|
||||||
|
kern_status_t init_vgacon_console(struct device *tty, struct device *fb)
|
||||||
|
{
|
||||||
|
struct char_device *cdev = CHAR_DEVICE(tty);
|
||||||
|
struct framebuffer_varinfo fb_mode;
|
||||||
|
struct framebuffer_fixedinfo fixedinfo;
|
||||||
|
struct tty_device *ttydev = cdev->c_tty;
|
||||||
|
|
||||||
|
struct fbcon_priv *priv = kmalloc(sizeof *priv, VM_NORMAL);
|
||||||
|
if (!priv) {
|
||||||
|
return KERN_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t status = framebuffer_get_varinfo(fb, &fb_mode);
|
||||||
|
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
kfree(priv);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = framebuffer_get_fixedinfo(fb, &fixedinfo);
|
||||||
|
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
kfree(priv);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ttydev->tty_xcells = fb_mode.fb_xcells;
|
||||||
|
ttydev->tty_ycells = fb_mode.fb_ycells;
|
||||||
|
ttydev->tty_xcur = 0;
|
||||||
|
ttydev->tty_ycur = 0;
|
||||||
|
|
||||||
|
priv->fbdev = fb;
|
||||||
|
priv->fb_pitch = fb_mode.fb_stride;
|
||||||
|
priv->fb_pixels = vm_phys_to_virt(fixedinfo.fb_baseptr);
|
||||||
|
priv->tty_ops = &vgacon_ops;
|
||||||
|
tty->dev_priv = priv;
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
8
kexts/drivers/tty/serialcon/extension.yaml
Normal file
8
kexts/drivers/tty/serialcon/extension.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
name: serialcon
|
||||||
|
description: |
|
||||||
|
Serial port console.
|
||||||
|
id: net.doorstuck.socks.serialcon
|
||||||
|
license: BSD-3-Clause
|
||||||
|
copyright: Copyright © Max Wash 2023
|
||||||
|
sources:
|
||||||
|
- main.c
|
||||||
38
kexts/drivers/tty/serialcon/main.c
Normal file
38
kexts/drivers/tty/serialcon/main.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include <socks/printk.h>
|
||||||
|
#include <socks/device.h>
|
||||||
|
#include <socks/kext.h>
|
||||||
|
#include <socks/tty.h>
|
||||||
|
#include <socks/libc/stdio.h>
|
||||||
|
|
||||||
|
static struct tty_driver *serialcon_driver = NULL;
|
||||||
|
|
||||||
|
static kern_status_t online(struct kext *self)
|
||||||
|
{
|
||||||
|
serialcon_driver = tty_driver_create(self, "ttyS");
|
||||||
|
if (!serialcon_driver) {
|
||||||
|
return KERN_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_driver_register(serialcon_driver);
|
||||||
|
|
||||||
|
struct device *ttyS0 = tty_device_create();
|
||||||
|
struct device *ttyS1 = tty_device_create();
|
||||||
|
struct device *ttyS2 = tty_device_create();
|
||||||
|
struct device *ttyS3 = tty_device_create();
|
||||||
|
|
||||||
|
snprintf(ttyS0->dev_name, sizeof ttyS0->dev_name, "ttyS0");
|
||||||
|
snprintf(ttyS1->dev_name, sizeof ttyS1->dev_name, "ttyS1");
|
||||||
|
snprintf(ttyS2->dev_name, sizeof ttyS2->dev_name, "ttyS2");
|
||||||
|
snprintf(ttyS3->dev_name, sizeof ttyS3->dev_name, "ttyS3");
|
||||||
|
|
||||||
|
tty_device_register(ttyS0, serialcon_driver, misc_device());
|
||||||
|
tty_device_register(ttyS1, serialcon_driver, misc_device());
|
||||||
|
tty_device_register(ttyS2, serialcon_driver, misc_device());
|
||||||
|
tty_device_register(ttyS3, serialcon_driver, misc_device());
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_KEXT("net.doorstuck.socks.serialcon",
|
||||||
|
online, NULL,
|
||||||
|
KEXT_NO_DEPENDENCIES);
|
||||||
Reference in New Issue
Block a user