From 7455f5ea4200c5f90bcbc2c025c58a00938952c4 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 28 Jan 2019 22:40:55 +0100 Subject: [PATCH] Expose the kernel log buffer through /proc/dmesg. Also add a /bin/dmesg program for convenience. --- AK/CircularQueue.h | 23 +++++++++++++++++++++++ Kernel/Console.cpp | 1 + Kernel/Console.h | 4 ++++ Kernel/ProcFileSystem.cpp | 11 +++++++++++ Kernel/sync.sh | 1 + Userland/.gitignore | 1 + Userland/Makefile | 5 +++++ Userland/dmesg.cpp | 31 +++++++++++++++++++++++++++++++ 8 files changed, 77 insertions(+) create mode 100644 Userland/dmesg.cpp diff --git a/AK/CircularQueue.h b/AK/CircularQueue.h index 88e95e3480..acb91216b9 100644 --- a/AK/CircularQueue.h +++ b/AK/CircularQueue.h @@ -46,7 +46,30 @@ public: return value; } + class ConstIterator { + public: + bool operator!=(const ConstIterator& other) { return m_index != other.m_index; } + ConstIterator& operator++() + { + m_index = (m_index + 1) % Capacity; + if (m_index == m_queue.m_head) + m_index = m_queue.m_size; + return *this; + } + + const T& operator*() const { return m_queue.m_elements[m_index]; } + private: + friend class CircularQueue; + ConstIterator(const CircularQueue& queue, const size_t index) : m_queue(queue), m_index(index) { } + const CircularQueue& m_queue; + size_t m_index { 0 }; + }; + + ConstIterator begin() const { return ConstIterator(*this, m_head); } + ConstIterator end() const { return ConstIterator(*this, size()); } + private: + friend class ConstIterator; T m_elements[Capacity]; size_t m_size { 0 }; size_t m_head { 0 }; diff --git a/Kernel/Console.cpp b/Kernel/Console.cpp index 4dbd2df5b4..08b5e19a77 100644 --- a/Kernel/Console.cpp +++ b/Kernel/Console.cpp @@ -52,6 +52,7 @@ void Console::put_char(char ch) //if (ch != 27) IO::out8(0xe9, ch); #endif + m_logbuffer.enqueue(ch); if (m_implementation) m_implementation->on_sysconsole_receive(ch); } diff --git a/Kernel/Console.h b/Kernel/Console.h index 683d73f467..75dd0f9014 100644 --- a/Kernel/Console.h +++ b/Kernel/Console.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -29,7 +30,10 @@ public: void put_char(char); + const CircularQueue& logbuffer() const { return m_logbuffer; } + private: ConsoleImplementation* m_implementation { nullptr }; + CircularQueue m_logbuffer; }; diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 86cefbb230..aa985b2970 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -6,6 +6,7 @@ #include "StdLib.h" #include "i386.h" #include "KSyms.h" +#include "Console.h" #include static ProcFS* s_the; @@ -198,6 +199,15 @@ ByteBuffer procfs$mm(SynthFSInode&) return builder.to_byte_buffer(); } +ByteBuffer procfs$dmesg(SynthFSInode&) +{ + InterruptDisabler disabler; + StringBuilder builder; + for (char ch : Console::the().logbuffer()) + builder.append(ch); + return builder.to_byte_buffer(); +} + ByteBuffer procfs$mounts(SynthFSInode&) { InterruptDisabler disabler; @@ -386,6 +396,7 @@ bool ProcFS::initialize() add_file(create_generated_file("summary", procfs$summary)); add_file(create_generated_file("cpuinfo", procfs$cpuinfo)); add_file(create_generated_file("inodes", procfs$inodes)); + add_file(create_generated_file("dmesg", procfs$dmesg)); m_sys_dir = add_file(create_directory("sys")); return true; } diff --git a/Kernel/sync.sh b/Kernel/sync.sh index f485bba22a..429515b955 100755 --- a/Kernel/sync.sh +++ b/Kernel/sync.sh @@ -49,6 +49,7 @@ cp -v ../Userland/guitest mnt/bin/guitest cp -v ../Userland/guitest2 mnt/bin/guitest2 cp -v ../Userland/sysctl mnt/bin/sysctl cp -v ../Terminal/Terminal mnt/bin/Terminal +cp -v ../Userland/dmesg mnt/bin/dmesg sh sync-local.sh cp -v kernel.map mnt/ ln -s dir_a mnt/dir_cur diff --git a/Userland/.gitignore b/Userland/.gitignore index 6ce961cd0c..fa2a9cc58e 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -27,3 +27,4 @@ sysctl rm cp rmdir +dmesg diff --git a/Userland/Makefile b/Userland/Makefile index e4bc3924e6..80bb0ee77c 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -24,6 +24,7 @@ OBJS = \ sysctl.o \ cp.o \ rmdir.o \ + dmesg.o \ rm.o APPS = \ @@ -53,6 +54,7 @@ APPS = \ sysctl \ cp \ rmdir \ + dmesg \ rm ARCH_FLAGS = @@ -118,6 +120,9 @@ tst: tst.o mm: mm.o $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a +dmesg: dmesg.o + $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a + kill: kill.o $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a diff --git a/Userland/dmesg.cpp b/Userland/dmesg.cpp new file mode 100644 index 0000000000..4f396a1b53 --- /dev/null +++ b/Userland/dmesg.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + (void) argc; + (void) argv; + int fd = open("/proc/dmesg", O_RDONLY); + if (fd < 0) { + perror("open /proc/dmesg"); + return 1; + } + for (;;) { + char buffer[BUFSIZ]; + ssize_t nread = read(fd, buffer, sizeof(buffer)); + if (nread < 0) { + perror("read"); + return 1; + } + if (nread == 0) { + break; + } + ssize_t nwritten = write(1, buffer, nread); + assert(nwritten == nread); + } + int rc = close(fd); + assert(rc == 0); + return 0; +}