实现内核日志系统 (#489)

* 实现写日志和读取日志,并且能够在用户态下执行dmesg命令查看日志

* 通过klogctl实现dmesg

* 改用ConstGenericRingBuffer作内核缓冲区

* 更改缓冲区容量

* 将能够输出到控制台的日志级别改为日志级别枚举类,使用SpinLock控制KMSG,使用枚举类定义SYSLOG_ACTION,将do_syslog系统调用接口放在syscall.rs

* fix warning

* 完善do_syslog注释

* 将KMSG接入kinfo、kdebug等

* fix warning

* 修复显示的秒数不正确,·以及无法通过CI的问题
This commit is contained in:
Jomo
2024-01-24 16:13:15 +08:00
committed by GitHub
parent d46c6d2794
commit 8d72b68da9
27 changed files with 763 additions and 26 deletions

113
user/apps/dmesg/main.c Normal file
View File

@ -0,0 +1,113 @@
#include "dmesg.h"
int main(int argc, char **argv)
{
unsigned int len = 1;
char *buf = NULL;
int opt;
unsigned int color = 65280;
// 获取内核缓冲区大小
len = klogctl(10, buf, len);
if (len < 16 * 1024)
len = 16 * 1024;
if (len > 16 * 1024 * 1024)
len = 16 * 1024 * 1024;
buf = malloc(len);
if (buf == NULL)
{
perror("");
return -1;
}
if (argc == 1)
{
// 无选项参数,默认打印所有日志消息
len = klogctl(2, buf, len);
}
else
{
// 获取第一个选项参数
opt = getopt(argv[1]);
// 无效参数
if (opt == -1)
{
print_bad_usage_msg();
return -1;
}
// 打印帮助手册
else if (opt == 0)
{
print_help_msg();
return 0;
}
// 4 -> 读取内核缓冲区后,清空缓冲区
// 5 -> 清空内核缓冲区
else if (opt == 4 || opt == 5)
{
len = klogctl(opt, buf, len);
}
// 读取特定日志级别的消息
else if (opt == 8)
{
// 无指定日志级别参数,打印错误使用信息
if (argc < 3)
{
print_bad_usage_msg();
return -1;
}
int level = -1;
// 获取日志级别
// 这里加1的原因是如果klogctl的第三个参数是0不会发生系统调用
level = getlevel(argv[2]) + 1;
if (level == -1)
return -1;
klogctl(8, buf, level);
len = klogctl(2, buf, len);
}
}
// 当前打印内容
// 0: 日志级别
// 1: 时间戳
// 2: 代码行号
// 3: 日志消息
unsigned int content = 0;
for (int i = 0; i < len; i++)
{
char c[2];
c[0] = buf[i];
c[1] = '\0';
syscall(100000, &c[0], color, 0);
if (content == 0 && buf[i] == '>')
{
content++;
}
else if (content == 1 && buf[i] == ']')
{
color = 16744448;
content++;
}
else if (content == 2 && buf[i] == ')')
{
color = 16777215;
content++;
}
else if (content == 3 && buf[i] == '\n')
{
color = 65280;
content = 0;
}
}
free(buf);
return 0;
}