AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
kmsg.c
Go to the documentation of this file.
1
8
9#include <core/system.h>
10#include <dev/dev.h>
11#include <fs/posix.h>
12#include <ds/ringbuf.h>
13#include <sys/sched.h>
14#include <console/earlycon.h>
15
16#include <memdev.h>
17
18struct dev kmsgdev;
19extern struct ringbuf *kmsg;
20extern struct waitq *kmsg_wait;
21
24static ssize_t kmsgdev_read(struct devid *dd __unused, off_t offset, struct iobuf *io)
25{
26 char tmp[256];
27 size_t size = io->resid, done = 0;
28
29 while (done < size) {
30 size_t len = ringbuf_read_noconsume(kmsg, offset + done, MIN(size - done, sizeof(tmp)), tmp);
31
32 if (!len)
33 break;
34
35 ssize_t r = iobuf_out(io, tmp, len);
36
37 if (r < 0)
38 return done ? (ssize_t) done : r;
39
40 done += r;
41
42 if ((size_t) r < len)
43 break;
44 }
45
46 return done;
47}
48
50static ssize_t kmsgdev_write(struct devid *dd __unused, off_t offset __unused, struct iobuf *io)
51{
52 /* what is written isn't NUL-terminated: print it a piece at a time,
53 * each piece terminated in a buffer */
54 char tmp[65];
55 size_t size = io->resid, done = 0;
56
57 while (done < size) {
58 ssize_t len = iobuf_in(io, tmp, MIN(size - done, sizeof(tmp) - 1));
59
60 if (len < 0)
61 return done ? (ssize_t) done : len;
62
63 tmp[len] = '\0';
64 printk("%s", tmp);
65 done += len;
66
67 if (io->fault)
68 break;
69 }
70
71 return done;
72}
73
75static int kmsg_file_open(struct file *file)
76{
77 file->vnode->read_queue = kmsg_wait;
78 return posix_file_open(file);
79}
80
81struct dev kmsgdev = {
82 .read = kmsgdev_read,
83 .write = kmsgdev_write,
84
85 .fops = {
86 .open = kmsg_file_open,
87 .read = posix_file_read,
88 .write = posix_file_write,
89 .close = posix_file_close,
90
91 .can_read = __vfs_can_always,
92 .can_write = __vfs_can_always,
93 .eof = __vfs_eof_never,
94 },
95};
#define MIN(a, b)
Definition system.h:11
ssize_t iobuf_out(struct iobuf *io, const void *src, size_t n)
Copies bytes from the kernel into the iobuf's buffer, and moves past them.
Definition iobuf.c:115
ssize_t iobuf_in(struct iobuf *io, void *dst, size_t n)
Copies bytes from the iobuf's buffer into the kernel, and moves past them.
Definition iobuf.c:135
struct dev kmsgdev
Definition kmsg.c:18
static ssize_t kmsgdev_read(struct devid *dd, off_t offset, struct iobuf *io)
Reads the kernel's messages from offset on, a piece at a time through a small buffer.
Definition kmsg.c:24
static int kmsg_file_open(struct file *file)
Opens /dev/kmsg: its readers wait on the kernel's message queue.
Definition kmsg.c:75
static ssize_t kmsgdev_write(struct devid *dd, off_t offset, struct iobuf *io)
Prints what is written as a kernel message.
Definition kmsg.c:50
int posix_file_open(struct file *file)
Finishes opening a file: with O_TRUNC, a regular file is truncated to 0 bytes.
Definition open.c:17
int posix_file_close(struct file *file)
Closes an open file by dropping its reference to its vnode.
Definition close.c:15
ssize_t posix_file_read(struct file *file, struct iobuf *io)
Reads from an open file at its offset, and moves the offset past what was read.
Definition read.c:29
ssize_t posix_file_write(struct file *file, struct iobuf *io)
Writes to an open file at its offset, and moves the offset past what was written.
Definition write.c:25
struct waitq * kmsg_wait
Definition printk.c:26
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
Definition printk.c:249
struct ringbuf * kmsg
Definition printk.c:25
A device driver: its operations, any of which may be NULL.
Definition dev.h:28
Which device: its kind (S_IFCHR or S_IFBLK) and numbers.
Definition dev.h:21
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
An iobuf.
Definition iobuf.h:35
int fault
Definition iobuf.h:40
size_t resid
Definition iobuf.h:38
A ring buffer.
Definition ringbuf.h:18
Definition waitq.h:19
long int ssize_t
Definition types.h:12
long int off_t
Definition types.h:10