Browse Source

Expose the kernel log buffer through /proc/dmesg.

Also add a /bin/dmesg program for convenience.
Andreas Kling 6 years ago
parent
commit
7455f5ea42
8 changed files with 77 additions and 0 deletions
  1. 23 0
      AK/CircularQueue.h
  2. 1 0
      Kernel/Console.cpp
  3. 4 0
      Kernel/Console.h
  4. 11 0
      Kernel/ProcFileSystem.cpp
  5. 1 0
      Kernel/sync.sh
  6. 1 0
      Userland/.gitignore
  7. 5 0
      Userland/Makefile
  8. 31 0
      Userland/dmesg.cpp

+ 23 - 0
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 };

+ 1 - 0
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);
 }

+ 4 - 0
Kernel/Console.h

@@ -1,5 +1,6 @@
 #pragma once
 
+#include <AK/CircularQueue.h>
 #include <AK/Compiler.h>
 #include <AK/Vector.h>
 #include <Kernel/CharacterDevice.h>
@@ -29,7 +30,10 @@ public:
 
     void put_char(char);
 
+    const CircularQueue<char, 16384>& logbuffer() const { return m_logbuffer; }
+
 private:
     ConsoleImplementation* m_implementation { nullptr };
+    CircularQueue<char, 16384> m_logbuffer;
 };
 

+ 11 - 0
Kernel/ProcFileSystem.cpp

@@ -6,6 +6,7 @@
 #include "StdLib.h"
 #include "i386.h"
 #include "KSyms.h"
+#include "Console.h"
 #include <AK/StringBuilder.h>
 
 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;
 }

+ 1 - 0
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

+ 1 - 0
Userland/.gitignore

@@ -27,3 +27,4 @@ sysctl
 rm
 cp
 rmdir
+dmesg

+ 5 - 0
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
 

+ 31 - 0
Userland/dmesg.cpp

@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+
+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;
+}