diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-05-13 15:48:00 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-05-13 15:48:00 +0800 |
| commit | b5faa01c335354f6b4090757603343ad26071591 (patch) | |
| tree | 6497889fd4181955e82a15b87f3a245808418c96 | |
| parent | 1274be88b61b685a7792e77fc38b90b8a30fcab7 (diff) | |
| download | lume-b5faa01c335354f6b4090757603343ad26071591.tar.gz lume-b5faa01c335354f6b4090757603343ad26071591.tar.xz | |
feat: add printk and vprintk functions with Linux-style log level parsing
| -rw-r--r-- | na/include/lume/klog.h | 20 | ||||
| -rw-r--r-- | na/lib/klog.cc | 50 |
2 files changed, 70 insertions, 0 deletions
diff --git a/na/include/lume/klog.h b/na/include/lume/klog.h index 457dcfe..b63810f 100644 --- a/na/include/lume/klog.h +++ b/na/include/lume/klog.h @@ -108,6 +108,11 @@ void klog(KlogLevel level, const char* fmt, ...); __attribute__((format(printf, 3, 4))) void klog_ex(KlogLevel level, KlogSubsys subsys, const char* fmt, ...); +/* Linux-style printk interface */ +__attribute__((format(printf, 1, 2))) +int printk(const char* fmt, ...); +int vprintk(const char* fmt, __builtin_va_list va); + /* Set runtime log level filter. Messages above this level are * still stored in the ring buffer but not printed to console. */ void klog_set_level(KlogLevel level); @@ -160,6 +165,21 @@ void klog_stats(KlogStats* out); #define pr_debug(fmt, ...) do {} while (0) #endif +/* Linux kernel loglevel prefixes */ +#define KERN_SOH "\001" +#define KERN_EMERG KERN_SOH "0" +#define KERN_ALERT KERN_SOH "1" +#define KERN_CRIT KERN_SOH "2" +#define KERN_ERR KERN_SOH "3" +#define KERN_WARNING KERN_SOH "4" +#define KERN_NOTICE KERN_SOH "5" +#define KERN_INFO KERN_SOH "6" +#define KERN_DEBUG KERN_SOH "7" + +/* Boot stage log (thin wrapper over printk) */ +#define BOOT_STAGE(n, desc) \ + printk(KERN_INFO "STAGE%u %s\n", (unsigned)(n), (desc)) + extern "C" [[noreturn]] void kernel_panic(const char* msg, const char* detail = nullptr); #ifdef __cplusplus diff --git a/na/lib/klog.cc b/na/lib/klog.cc index c67971b..bf081de 100644 --- a/na/lib/klog.cc +++ b/na/lib/klog.cc @@ -86,6 +86,27 @@ static const char* klog_subsys_name(KlogSubsys subsys) return "?"; } +static const char* parse_kern_level(const char* fmt, KlogLevel* level) +{ + if (!fmt || !level) { + return fmt; + } + + /* Linux-style "\001n" prefix (KERN_SOH) */ + if (fmt[0] == '\001' && fmt[1] >= '0' && fmt[1] <= '7') { + *level = static_cast<KlogLevel>(fmt[1] - '0'); + return fmt + 2; + } + + /* Alternate "<n>" prefix */ + if (fmt[0] == '<' && fmt[1] >= '0' && fmt[1] <= '7' && fmt[2] == '>') { + *level = static_cast<KlogLevel>(fmt[1] - '0'); + return fmt + 3; + } + + return fmt; +} + /* ======================================================================== * Ring Buffer Operations * ======================================================================== */ @@ -320,6 +341,35 @@ static void klog_vex(KlogLevel level, KlogSubsys subsys, } } +int vprintk(const char* fmt, __builtin_va_list va) +{ + KlogLevel level = KLOG_INFO; + const char* real_fmt = parse_kern_level(fmt, &level); + + __builtin_va_list va_copy; + __builtin_va_copy(va_copy, va); + + char tmp[KLOG_LINE_MAX + 1]; + int len = vsnprintf_(tmp, KLOG_LINE_MAX, real_fmt, va_copy); + __builtin_va_end(va_copy); + + klog_vex(level, KLOG_SUBSYS_GENERIC, real_fmt, va); + + if (len < 0) { + return 0; + } + return len; +} + +int printk(const char* fmt, ...) +{ + __builtin_va_list va; + __builtin_va_start(va, fmt); + int ret = vprintk(fmt, va); + __builtin_va_end(va); + return ret; +} + void klog_set_level(KlogLevel level) { g_klog.console_level = level; |
