1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:17:35 +00:00

Kernel: Absorb LibBareMetal back into the kernel

This was supposed to be the foundation for some kind of pre-kernel
environment, but nobody is working on it right now, so let's move
everything back into the kernel and remove all the confusion.
This commit is contained in:
Andreas Kling 2020-05-16 12:00:04 +02:00
parent c12cfdea87
commit 21d5f4ada1
75 changed files with 140 additions and 203 deletions

View file

@ -27,7 +27,7 @@
#include <AK/StringView.h>
#include <Kernel/ACPI/DMIDecoder.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/StdLib.h>
namespace Kernel {

View file

@ -30,8 +30,8 @@
#include <AK/Types.h>
#include <AK/Vector.h>
#include <Kernel/VM/Region.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/VirtualAddress.h>
namespace Kernel {

View file

@ -29,7 +29,7 @@
#include <AK/RefCounted.h>
#include <AK/Types.h>
#include <AK/Vector.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -31,7 +31,7 @@
#include <Kernel/Interrupts/IRQHandler.h>
#include <Kernel/Lock.h>
#include <Kernel/VM/PhysicalPage.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {
namespace ACPI {

View file

@ -28,7 +28,7 @@
#include <Kernel/ACPI/MultiProcessorParser.h>
#include <Kernel/Interrupts/IOAPIC.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/StdLib.h>
//#define MULTIPROCESSOR_DEBUG

View file

@ -28,8 +28,8 @@
#include <AK/Types.h>
#include <Kernel/VM/Region.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/VirtualAddress.h>
namespace Kernel {
namespace MultiProcessor {

View file

@ -30,8 +30,8 @@
#include <Kernel/PCI/Access.h>
#include <Kernel/VM/MemoryManager.h>
#include <Kernel/VM/TypedMapping.h>
#include <LibBareMetal/IO.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/IO.h>
#include <Kernel/StdLib.h>
namespace Kernel {
namespace ACPI {

View file

@ -31,8 +31,8 @@
#include <Kernel/ACPI/Initialize.h>
#include <Kernel/FileSystem/File.h>
#include <Kernel/VM/Region.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/VirtualAddress.h>
namespace Kernel {
namespace ACPI {

View file

@ -39,7 +39,7 @@
#include <Kernel/KSyms.h>
#include <Kernel/Process.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
#include <LibC/mallocdefs.h>
//#define PAGE_FAULT_DEBUG

View file

@ -28,8 +28,8 @@
#include <AK/Badge.h>
#include <AK/Noncopyable.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/VirtualAddress.h>
#define PAGE_SIZE 4096
#define GENERIC_INTERRUPT_HANDLERS_COUNT 128

View file

@ -25,7 +25,7 @@
*/
#include <Kernel/CMOS.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace CMOS {

View file

@ -7,8 +7,9 @@ set(KERNEL_SOURCES
Arch/i386/CPU.cpp
CMOS.cpp
CommandLine.cpp
Devices/BlockDevice.cpp
Console.cpp
Devices/BXVGADevice.cpp
Devices/BlockDevice.cpp
Devices/CharacterDevice.cpp
Devices/Device.cpp
Devices/DiskPartition.cpp
@ -33,8 +34,8 @@ set(KERNEL_SOURCES
FileSystem/DevPtsFS.cpp
FileSystem/Ext2FileSystem.cpp
FileSystem/FIFO.cpp
FileSystem/FileBackedFileSystem.cpp
FileSystem/File.cpp
FileSystem/FileBackedFileSystem.cpp
FileSystem/FileDescription.cpp
FileSystem/FileSystem.cpp
FileSystem/Inode.cpp
@ -43,14 +44,13 @@ set(KERNEL_SOURCES
FileSystem/ProcFS.cpp
FileSystem/TmpFS.cpp
FileSystem/VirtualFileSystem.cpp
Heap/kmalloc.cpp
Heap/SlabAllocator.cpp
init.cpp
Heap/kmalloc.cpp
Interrupts/APIC.cpp
Interrupts/GenericInterruptHandler.cpp
Interrupts/InterruptManagement.cpp
Interrupts/IOAPIC.cpp
Interrupts/IRQHandler.cpp
Interrupts/InterruptManagement.cpp
Interrupts/PIC.cpp
Interrupts/SharedIRQHandler.cpp
Interrupts/SpuriousInterruptHandler.cpp
@ -64,41 +64,42 @@ set(KERNEL_SOURCES
Net/LoopbackAdapter.cpp
Net/NetworkAdapter.cpp
Net/NetworkTask.cpp
Net/Routing.cpp
Net/RTL8139NetworkAdapter.cpp
Net/Routing.cpp
Net/Socket.cpp
Net/TCPSocket.cpp
Net/UDPSocket.cpp
PCI/Access.cpp
PCI/Device.cpp
PCI/Initializer.cpp
PCI/IOAccess.cpp
PCI/Initializer.cpp
PCI/MMIOAccess.cpp
PerformanceEventBuffer.cpp
Process.cpp
Profiling.cpp
Ptrace.cpp
Random.cpp
RTC.cpp
Random.cpp
Scheduler.cpp
SharedBuffer.cpp
StdLib.cpp
Syscall.cpp
Tasks/FinalizerTask.cpp
Tasks/SyncTask.cpp
Thread.cpp
ThreadTracer.cpp
Time/HardwareTimer.cpp
Time/HPETComparator.cpp
Time/HPET.cpp
Time/PIT.cpp
TimerQueue.cpp
Time/RTC.cpp
Time/TimeManagement.cpp
TTY/MasterPTY.cpp
TTY/PTYMultiplexer.cpp
TTY/SlavePTY.cpp
TTY/TTY.cpp
TTY/VirtualConsole.cpp
Tasks/FinalizerTask.cpp
Tasks/SyncTask.cpp
Thread.cpp
ThreadTracer.cpp
Time/HPET.cpp
Time/HPETComparator.cpp
Time/HardwareTimer.cpp
Time/PIT.cpp
Time/RTC.cpp
Time/TimeManagement.cpp
TimerQueue.cpp
VM/AnonymousVMObject.cpp
VM/ContiguousVMObject.cpp
VM/InodeVMObject.cpp
@ -114,6 +115,8 @@ set(KERNEL_SOURCES
VM/SharedInodeVMObject.cpp
VM/VMObject.cpp
WaitQueue.cpp
init.cpp
kprintf.cpp
)
set(AK_SOURCES
@ -135,17 +138,10 @@ set(ELF_SOURCES
../Libraries/LibELF/Validation.cpp
)
set(BARE_METAL_SOURCES
../Libraries/LibBareMetal/Output/Console.cpp
../Libraries/LibBareMetal/Output/kprintf.cpp
../Libraries/LibBareMetal/StdLib.cpp
)
set(SOURCES
${KERNEL_SOURCES}
${AK_SOURCES}
${ELF_SOURCES}
${BARE_METAL_SOURCES}
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKERNEL")

93
Kernel/Console.cpp Normal file
View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Kernel/Console.h>
#include <Kernel/IO.h>
#include <Kernel/kstdio.h>
// Bytes output to 0xE9 end up on the Bochs console. It's very handy.
#define CONSOLE_OUT_TO_E9
static Console* s_the;
Console& Console::the()
{
ASSERT(s_the);
return *s_the;
}
bool Console::is_initialized()
{
return s_the != nullptr;
}
Console::Console()
: CharacterDevice(5, 1)
{
s_the = this;
}
Console::~Console()
{
}
bool Console::can_read(const Kernel::FileDescription&, size_t) const
{
return false;
}
ssize_t Console::read(Kernel::FileDescription&, size_t, u8*, ssize_t)
{
// FIXME: Implement reading from the console.
// Maybe we could use a ring buffer for this device?
return 0;
}
ssize_t Console::write(Kernel::FileDescription&, size_t, const u8* data, ssize_t size)
{
if (!size)
return 0;
if (!m_implementation)
return 0;
for (ssize_t i = 0; i < size; ++i)
put_char(data[i]);
return size;
}
void Console::put_char(char ch)
{
#ifdef CONSOLE_OUT_TO_E9
//if (ch != 27)
IO::out8(0xe9, ch);
#endif
m_logbuffer.enqueue(ch);
if (m_implementation)
m_implementation->on_sysconsole_receive(ch);
}
ConsoleImplementation::~ConsoleImplementation()
{
}

67
Kernel/Console.h Normal file
View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/CircularQueue.h>
#include <AK/Vector.h>
#include <Kernel/Devices/CharacterDevice.h>
class ConsoleImplementation {
public:
virtual ~ConsoleImplementation();
virtual void on_sysconsole_receive(u8) = 0;
};
class Console final : public Kernel::CharacterDevice {
AK_MAKE_ETERNAL
public:
static Console& the();
static bool is_initialized();
Console();
virtual ~Console() override;
// ^CharacterDevice
virtual bool can_read(const Kernel::FileDescription&, size_t) const override;
virtual bool can_write(const Kernel::FileDescription&, size_t) const override { return true; }
virtual ssize_t read(Kernel::FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(Kernel::FileDescription&, size_t, const u8*, ssize_t) override;
virtual const char* class_name() const override { return "Console"; }
void set_implementation(ConsoleImplementation* implementation)
{
m_implementation = implementation;
}
void put_char(char);
const CircularQueue<char, 16384>& logbuffer() const { return m_logbuffer; }
private:
ConsoleImplementation* m_implementation { nullptr };
CircularQueue<char, 16384> m_logbuffer;
};

View file

@ -30,7 +30,7 @@
#include <Kernel/Process.h>
#include <Kernel/VM/AnonymousVMObject.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
#include <LibC/errno_numbers.h>
#include <LibC/sys/ioctl_numbers.h>

View file

@ -29,7 +29,7 @@
#include <AK/String.h>
#include <AK/Types.h>
#include <Kernel/Devices/BlockDevice.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -31,7 +31,7 @@
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Devices/KeyboardDevice.h>
#include <Kernel/TTY/VirtualConsole.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
//#define KEYBOARD_DEBUG

View file

@ -29,7 +29,7 @@
#include <AK/String.h>
#include <AK/Types.h>
#include <Kernel/Devices/BlockDevice.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -31,7 +31,7 @@
#include <Kernel/FileSystem/ProcFS.h>
#include <Kernel/Process.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {

View file

@ -43,8 +43,8 @@
#include <Kernel/PCI/Device.h>
#include <Kernel/VM/PhysicalPage.h>
#include <Kernel/WaitQueue.h>
#include <LibBareMetal/IO.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/IO.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -27,7 +27,7 @@
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Devices/PCSpeaker.h>
#include <Kernel/Time/PIT.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
void PCSpeaker::tone_on(int frequency)
{

View file

@ -27,7 +27,7 @@
#include <AK/Memory.h>
#include <Kernel/Devices/PS2MouseDevice.h>
#include <Kernel/Devices/VMWareBackdoor.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {

View file

@ -30,7 +30,7 @@
#include <Kernel/Thread.h>
#include <Kernel/VM/AnonymousVMObject.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
//#define SB16_DEBUG

View file

@ -30,7 +30,7 @@
#include <Kernel/Interrupts/IRQHandler.h>
#include <Kernel/VM/PhysicalPage.h>
#include <Kernel/WaitQueue.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -25,7 +25,7 @@
*/
#include <Kernel/Devices/SerialDevice.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {

View file

@ -30,7 +30,7 @@
#include <Kernel/CommandLine.h>
#include <Kernel/Devices/VMWareBackdoor.h>
#include <Kernel/MousePacket.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {

View file

@ -33,7 +33,7 @@
#include <Kernel/Forward.h>
#include <Kernel/KResult.h>
#include <Kernel/UnixTypes.h>
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <Kernel/VirtualAddress.h>
namespace Kernel {

View file

@ -34,7 +34,7 @@
#include <Kernel/FileSystem/InodeMetadata.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/KBuffer.h>
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <Kernel/VirtualAddress.h>
namespace Kernel {

View file

@ -54,8 +54,8 @@
#include <Kernel/TTY/TTY.h>
#include <Kernel/VM/MemoryManager.h>
#include <Kernel/VM/PurgeableVMObject.h>
#include <LibBareMetal/Output/Console.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/Console.h>
#include <Kernel/StdLib.h>
#include <LibC/errno_numbers.h>
namespace Kernel {

View file

@ -38,7 +38,7 @@
#include <Kernel/KSyms.h>
#include <Kernel/Process.h>
#include <Kernel/Scheduler.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/StdLib.h>
#define SANITIZE_KMALLOC

178
Kernel/IO.h Normal file
View file

@ -0,0 +1,178 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/Assertions.h>
#include <AK/LogStream.h>
#include <AK/String.h>
#include <AK/Types.h>
#include <Kernel/Arch/i386/CPU.h>
namespace IO {
inline u8 in8(u16 port)
{
u8 value;
asm volatile("inb %1, %0"
: "=a"(value)
: "Nd"(port));
return value;
}
inline u16 in16(u16 port)
{
u16 value;
asm volatile("inw %1, %0"
: "=a"(value)
: "Nd"(port));
return value;
}
inline u32 in32(u16 port)
{
u32 value;
asm volatile("inl %1, %0"
: "=a"(value)
: "Nd"(port));
return value;
}
inline void repeated_in16(u16 port, u16* buffer, int buffer_size)
{
asm volatile("rep insw"
: "+D"(buffer), "+c"(buffer_size)
: "d"(port)
: "memory");
}
inline void out8(u16 port, u8 value)
{
asm volatile("outb %0, %1" ::"a"(value), "Nd"(port));
}
inline void out16(u16 port, u16 value)
{
asm volatile("outw %0, %1" ::"a"(value), "Nd"(port));
}
inline void out32(u16 port, u32 value)
{
asm volatile("outl %0, %1" ::"a"(value), "Nd"(port));
}
inline void repeated_out16(u16 port, const u16* data, int data_size)
{
asm volatile("rep outsw"
: "+S"(data), "+c"(data_size)
: "d"(port));
}
inline void delay(size_t microseconds)
{
for (size_t i = 0; i < microseconds; ++i)
IO::in8(0x80);
}
}
class IOAddress {
public:
IOAddress() { }
explicit IOAddress(u16 address)
: m_address(address)
{
}
IOAddress offset(u16 o) const { return IOAddress(m_address + o); }
u16 get() const { return m_address; }
void set(u16 address) { m_address = address; }
void mask(u16 m) { m_address &= m; }
template<typename T>
ALWAYS_INLINE T in()
{
if constexpr (sizeof(T) == 4)
return IO::in32(get());
if constexpr (sizeof(T) == 2)
return IO::in16(get());
if constexpr (sizeof(T) == 1)
return IO::in8(get());
ASSERT_NOT_REACHED();
}
template<typename T>
ALWAYS_INLINE void out(T value)
{
if constexpr (sizeof(T) == 4) {
IO::out32(get(), value);
return;
}
if constexpr (sizeof(T) == 2) {
IO::out16(get(), value);
return;
}
if constexpr (sizeof(T) == 1) {
IO::out8(get(), value);
return;
}
ASSERT_NOT_REACHED();
}
inline void out(u32 value, u8 bit_width)
{
if (bit_width == 32) {
IO::out32(get(), value);
return;
}
if (bit_width == 16) {
IO::out16(get(), value);
return;
}
if (bit_width == 8) {
IO::out8(get(), value);
return;
}
ASSERT_NOT_REACHED();
}
bool is_null() const { return m_address == 0; }
bool operator==(const IOAddress& other) const { return m_address == other.m_address; }
bool operator!=(const IOAddress& other) const { return m_address != other.m_address; }
bool operator>(const IOAddress& other) const { return m_address > other.m_address; }
bool operator>=(const IOAddress& other) const { return m_address >= other.m_address; }
bool operator<(const IOAddress& other) const { return m_address < other.m_address; }
bool operator<=(const IOAddress& other) const { return m_address <= other.m_address; }
private:
u16 m_address { 0 };
};
inline const LogStream& operator<<(const LogStream& stream, IOAddress value)
{
return stream << "IO " << String::format("%x", value.get());
}

View file

@ -31,7 +31,7 @@
#include <Kernel/Interrupts/APIC.h>
#include <Kernel/Interrupts/SpuriousInterruptHandler.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
#define IRQ_APIC_SPURIOUS 0x7f

View file

@ -37,7 +37,7 @@
#include <Kernel/Interrupts/UnhandledInterruptHandler.h>
#include <Kernel/Syscall.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
#define PCAT_COMPAT_FLAG 0x1

View file

@ -29,7 +29,7 @@
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Interrupts/GenericInterruptHandler.h>
#include <Kernel/Interrupts/PIC.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {

View file

@ -26,7 +26,7 @@
#include <Kernel/Net/E1000NetworkAdapter.h>
#include <Kernel/Thread.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
//#define E1000_DEBUG

View file

@ -32,7 +32,7 @@
#include <Kernel/Net/NetworkAdapter.h>
#include <Kernel/PCI/Access.h>
#include <Kernel/PCI/Device.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {

View file

@ -30,7 +30,7 @@
#include <Kernel/Net/LocalSocket.h>
#include <Kernel/Process.h>
#include <Kernel/UnixTypes.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/StdLib.h>
#include <LibC/errno_numbers.h>
//#define DEBUG_LOCAL_SOCKET

View file

@ -33,7 +33,7 @@
#include <Kernel/Net/LoopbackAdapter.h>
#include <Kernel/Net/NetworkAdapter.h>
#include <Kernel/Random.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/StdLib.h>
namespace Kernel {

View file

@ -25,7 +25,7 @@
*/
#include <Kernel/Net/RTL8139NetworkAdapter.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
//#define RTL8139_DEBUG

View file

@ -30,7 +30,7 @@
#include <Kernel/Net/NetworkAdapter.h>
#include <Kernel/PCI/Access.h>
#include <Kernel/PCI/Device.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {

View file

@ -25,7 +25,7 @@
*/
#include <Kernel/PCI/IOAccess.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {
namespace PCI {

View file

@ -31,7 +31,7 @@
#include <Kernel/PCI/IOAccess.h>
#include <Kernel/PCI/Initializer.h>
#include <Kernel/PCI/MMIOAccess.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {
namespace PCI {

67
Kernel/PhysicalAddress.h Normal file
View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/LogStream.h>
#include <AK/Types.h>
class PhysicalAddress {
public:
PhysicalAddress() {}
explicit PhysicalAddress(FlatPtr address)
: m_address(address)
{
}
PhysicalAddress offset(FlatPtr o) const { return PhysicalAddress(m_address + o); }
FlatPtr get() const { return m_address; }
void set(FlatPtr address) { m_address = address; }
void mask(FlatPtr m) { m_address &= m; }
bool is_null() const { return m_address == 0; }
u8* as_ptr() { return reinterpret_cast<u8*>(m_address); }
const u8* as_ptr() const { return reinterpret_cast<const u8*>(m_address); }
PhysicalAddress page_base() const { return PhysicalAddress(m_address & 0xfffff000); }
FlatPtr offset_in_page() const { return PhysicalAddress(m_address & 0xfff).get(); }
bool operator==(const PhysicalAddress& other) const { return m_address == other.m_address; }
bool operator!=(const PhysicalAddress& other) const { return m_address != other.m_address; }
bool operator>(const PhysicalAddress& other) const { return m_address > other.m_address; }
bool operator>=(const PhysicalAddress& other) const { return m_address >= other.m_address; }
bool operator<(const PhysicalAddress& other) const { return m_address < other.m_address; }
bool operator<=(const PhysicalAddress& other) const { return m_address <= other.m_address; }
private:
FlatPtr m_address { 0 };
};
inline const LogStream& operator<<(const LogStream& stream, PhysicalAddress value)
{
return stream << 'P' << value.as_ptr();
}

View file

@ -73,9 +73,9 @@
#include <Kernel/VM/ProcessPagingScope.h>
#include <Kernel/VM/PurgeableVMObject.h>
#include <Kernel/VM/SharedInodeVMObject.h>
#include <LibBareMetal/IO.h>
#include <LibBareMetal/Output/Console.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/IO.h>
#include <Kernel/Console.h>
#include <Kernel/StdLib.h>
#include <LibC/errno_numbers.h>
#include <LibC/limits.h>
#include <LibC/signal_numbers.h>

View file

@ -39,7 +39,7 @@
#include <Kernel/Thread.h>
#include <Kernel/UnixTypes.h>
#include <Kernel/VM/RangeAllocator.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/StdLib.h>
#include <LibC/signal_numbers.h>
namespace ELF {

256
Kernel/StdLib.cpp Normal file
View file

@ -0,0 +1,256 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/Assertions.h>
#include <AK/String.h>
#include <AK/Types.h>
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Heap/kmalloc.h>
#include <Kernel/StdLib.h>
#include <Kernel/VM/MemoryManager.h>
String copy_string_from_user(const char* user_str, size_t user_str_size)
{
Kernel::SmapDisabler disabler;
size_t length = strnlen(user_str, user_str_size);
return String(user_str, length);
}
extern "C" {
void copy_to_user(void* dest_ptr, const void* src_ptr, size_t n)
{
ASSERT(Kernel::is_user_range(VirtualAddress(dest_ptr), n));
ASSERT(!Kernel::is_user_range(VirtualAddress(src_ptr), n));
Kernel::SmapDisabler disabler;
memcpy(dest_ptr, src_ptr, n);
}
void copy_from_user(void* dest_ptr, const void* src_ptr, size_t n)
{
ASSERT(Kernel::is_user_range(VirtualAddress(src_ptr), n));
ASSERT(!Kernel::is_user_range(VirtualAddress(dest_ptr), n));
Kernel::SmapDisabler disabler;
memcpy(dest_ptr, src_ptr, n);
}
void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)
{
size_t dest = (size_t)dest_ptr;
size_t src = (size_t)src_ptr;
// FIXME: Support starting at an unaligned address.
if (!(dest & 0x3) && !(src & 0x3) && n >= 12) {
size_t size_ts = n / sizeof(size_t);
asm volatile(
"rep movsl\n"
: "=S"(src), "=D"(dest)
: "S"(src), "D"(dest), "c"(size_ts)
: "memory");
n -= size_ts * sizeof(size_t);
if (n == 0)
return dest_ptr;
}
asm volatile(
"rep movsb\n" ::"S"(src), "D"(dest), "c"(n)
: "memory");
return dest_ptr;
}
void* memmove(void* dest, const void* src, size_t n)
{
if (dest < src)
return memcpy(dest, src, n);
u8* pd = (u8*)dest;
const u8* ps = (const u8*)src;
for (pd += n, ps += n; n--;)
*--pd = *--ps;
return dest;
}
char* strcpy(char* dest, const char* src)
{
auto* dest_ptr = dest;
auto* src_ptr = src;
while ((*dest_ptr++ = *src_ptr++) != '\0')
;
return dest;
}
char* strncpy(char* dest, const char* src, size_t n)
{
size_t i;
for (i = 0; i < n && src[i] != '\0'; ++i)
dest[i] = src[i];
for (; i < n; ++i)
dest[i] = '\0';
return dest;
}
void memset_user(void* dest_ptr, int c, size_t n)
{
ASSERT(Kernel::is_user_range(VirtualAddress(dest_ptr), n));
Kernel::SmapDisabler disabler;
memset(dest_ptr, c, n);
}
void* memset(void* dest_ptr, int c, size_t n)
{
size_t dest = (size_t)dest_ptr;
// FIXME: Support starting at an unaligned address.
if (!(dest & 0x3) && n >= 12) {
size_t size_ts = n / sizeof(size_t);
size_t expanded_c = (u8)c;
expanded_c |= expanded_c << 8;
expanded_c |= expanded_c << 16;
asm volatile(
"rep stosl\n"
: "=D"(dest)
: "D"(dest), "c"(size_ts), "a"(expanded_c)
: "memory");
n -= size_ts * sizeof(size_t);
if (n == 0)
return dest_ptr;
}
asm volatile(
"rep stosb\n"
: "=D"(dest), "=c"(n)
: "0"(dest), "1"(n), "a"(c)
: "memory");
return dest_ptr;
}
char* strrchr(const char* str, int ch)
{
char* last = nullptr;
char c;
for (; (c = *str); ++str) {
if (c == ch)
last = const_cast<char*>(str);
}
return last;
}
size_t strlen(const char* str)
{
size_t len = 0;
while (*(str++))
++len;
return len;
}
size_t strnlen(const char* str, size_t maxlen)
{
size_t len = 0;
for (; len < maxlen && *str; str++)
len++;
return len;
}
int strcmp(const char* s1, const char* s2)
{
for (; *s1 == *s2; ++s1, ++s2) {
if (*s1 == 0)
return 0;
}
return *(const u8*)s1 < *(const u8*)s2 ? -1 : 1;
}
char* strdup(const char* str)
{
size_t len = strlen(str);
char* new_str = (char*)kmalloc(len + 1);
strcpy(new_str, str);
return new_str;
}
int memcmp(const void* v1, const void* v2, size_t n)
{
auto* s1 = (const u8*)v1;
auto* s2 = (const u8*)v2;
while (n-- > 0) {
if (*s1++ != *s2++)
return s1[-1] < s2[-1] ? -1 : 1;
}
return 0;
}
int strncmp(const char* s1, const char* s2, size_t n)
{
if (!n)
return 0;
do {
if (*s1 != *s2++)
return *(const unsigned char*)s1 - *(const unsigned char*)--s2;
if (*s1++ == 0)
break;
} while (--n);
return 0;
}
char* strstr(const char* haystack, const char* needle)
{
char nch;
char hch;
if ((nch = *needle++) != 0) {
size_t len = strlen(needle);
do {
do {
if ((hch = *haystack++) == 0)
return nullptr;
} while (hch != nch);
} while (strncmp(haystack, needle, len) != 0);
--haystack;
}
return const_cast<char*>(haystack);
}
[[noreturn]] void __cxa_pure_virtual()
{
ASSERT_NOT_REACHED();
}
void* realloc(void* p, size_t s)
{
return krealloc(p, s);
}
void free(void* p)
{
return kfree(p);
}
[[noreturn]] void __stack_chk_fail()
{
ASSERT_NOT_REACHED();
}
[[noreturn]] void __stack_chk_fail_local()
{
ASSERT_NOT_REACHED();
}
}

73
Kernel/StdLib.h Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/Forward.h>
namespace Syscall {
struct StringArgument;
}
String copy_string_from_user(const char*, size_t);
extern "C" {
static_assert(sizeof(size_t) == 4);
void copy_to_user(void*, const void*, size_t);
void copy_from_user(void*, const void*, size_t);
void memset_user(void*, int, size_t);
void* memcpy(void*, const void*, size_t);
char* strcpy(char*, const char*);
char* strncpy(char*, const char*, size_t);
int strncmp(const char* s1, const char* s2, size_t n);
char* strstr(const char* haystack, const char* needle);
int strcmp(char const*, const char*);
size_t strlen(const char*);
size_t strnlen(const char*, size_t);
void* memset(void*, int, size_t);
char* strdup(const char*);
int memcmp(const void*, const void*, size_t);
char* strrchr(const char* str, int ch);
void* memmove(void* dest, const void* src, size_t n);
inline u16 ntohs(u16 w) { return (w & 0xff) << 8 | ((w >> 8) & 0xff); }
inline u16 htons(u16 w) { return (w & 0xff) << 8 | ((w >> 8) & 0xff); }
}
template<typename T>
inline void copy_from_user(T* dest, const T* src)
{
copy_from_user(dest, src, sizeof(T));
}
template<typename T>
inline void copy_to_user(T* dest, const T* src)
{
copy_to_user(dest, src, sizeof(T));
}

View file

@ -29,8 +29,8 @@
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Devices/KeyboardDevice.h>
#include <Kernel/Heap/kmalloc.h>
#include <LibBareMetal/IO.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/IO.h>
#include <Kernel/StdLib.h>
namespace Kernel {

View file

@ -28,7 +28,7 @@
#include <Kernel/Devices/KeyboardDevice.h>
#include <Kernel/TTY/TTY.h>
#include <LibBareMetal/Output/Console.h>
#include <Kernel/Console.h>
namespace Kernel {

View file

@ -31,8 +31,8 @@
#include <AK/OwnPtr.h>
#include <AK/Types.h>
#include <AK/Vector.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/VM/Region.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
namespace Kernel {

View file

@ -30,7 +30,7 @@
#include <Kernel/Thread.h>
#include <Kernel/Time/PIT.h>
#include <Kernel/Time/TimeManagement.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
#define IRQ_TIMER 0
namespace Kernel {

View file

@ -28,7 +28,7 @@
#include <Kernel/CMOS.h>
#include <Kernel/Time/RTC.h>
#include <Kernel/Time/TimeManagement.h>
#include <LibBareMetal/IO.h>
#include <Kernel/IO.h>
namespace Kernel {
#define IRQ_TIMER 8

View file

@ -27,7 +27,7 @@
#pragma once
#include <Kernel/VM/VMObject.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -27,7 +27,7 @@
#pragma once
#include <Kernel/VM/VMObject.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -39,7 +39,7 @@
#include <Kernel/VM/PhysicalRegion.h>
#include <Kernel/VM/PurgeableVMObject.h>
#include <Kernel/VM/SharedInodeVMObject.h>
#include <LibBareMetal/StdLib.h>
#include <Kernel/StdLib.h>
//#define MM_DEBUG
//#define PAGE_FAULT_DEBUG

View file

@ -29,7 +29,7 @@
#include <AK/NonnullRefPtr.h>
#include <Kernel/Assertions.h>
#include <Kernel/Heap/SlabAllocator.h>
#include <LibBareMetal/Memory/PhysicalAddress.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {

View file

@ -29,7 +29,7 @@
#include <AK/String.h>
#include <AK/Traits.h>
#include <AK/Vector.h>
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <Kernel/VirtualAddress.h>
namespace Kernel {

77
Kernel/VirtualAddress.h Normal file
View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/LogStream.h>
#include <AK/Types.h>
class VirtualAddress {
public:
VirtualAddress() {}
explicit VirtualAddress(FlatPtr address)
: m_address(address)
{
}
explicit VirtualAddress(const void* address)
: m_address((FlatPtr)address)
{
}
bool is_null() const { return m_address == 0; }
bool is_page_aligned() const { return (m_address & 0xfff) == 0; }
VirtualAddress offset(FlatPtr o) const { return VirtualAddress(m_address + o); }
FlatPtr get() const { return m_address; }
void set(FlatPtr address) { m_address = address; }
void mask(FlatPtr m) { m_address &= m; }
bool operator<=(const VirtualAddress& other) const { return m_address <= other.m_address; }
bool operator>=(const VirtualAddress& other) const { return m_address >= other.m_address; }
bool operator>(const VirtualAddress& other) const { return m_address > other.m_address; }
bool operator<(const VirtualAddress& other) const { return m_address < other.m_address; }
bool operator==(const VirtualAddress& other) const { return m_address == other.m_address; }
bool operator!=(const VirtualAddress& other) const { return m_address != other.m_address; }
u8* as_ptr() { return reinterpret_cast<u8*>(m_address); }
const u8* as_ptr() const { return reinterpret_cast<const u8*>(m_address); }
VirtualAddress page_base() const { return VirtualAddress(m_address & 0xfffff000); }
private:
FlatPtr m_address { 0 };
};
inline VirtualAddress operator-(const VirtualAddress& a, const VirtualAddress& b)
{
return VirtualAddress(a.get() - b.get());
}
inline const LogStream& operator<<(const LogStream& stream, VirtualAddress value)
{
return stream << 'V' << value.as_ptr();
}

180
Kernel/kprintf.cpp Normal file
View file

@ -0,0 +1,180 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/PrintfImplementation.h>
#include <AK/Types.h>
#include <Kernel/Console.h>
#include <Kernel/IO.h>
#include <Kernel/Process.h>
#include <Kernel/kstdio.h>
#include <LibC/stdarg.h>
static bool serial_debug;
void set_serial_debug(bool on_or_off)
{
serial_debug = on_or_off;
}
int get_serial_debug()
{
return serial_debug;
}
static void color_on()
{
IO::out8(0xe9, 0x1b);
IO::out8(0xe9, '[');
IO::out8(0xe9, '3');
IO::out8(0xe9, '6');
IO::out8(0xe9, 'm');
}
static void color_off()
{
IO::out8(0xe9, 0x1b);
IO::out8(0xe9, '[');
IO::out8(0xe9, '0');
IO::out8(0xe9, 'm');
}
static void serial_putch(char ch)
{
static bool serial_ready = false;
static bool was_cr = false;
if (!serial_ready) {
IO::out8(0x3F8 + 1, 0x00);
IO::out8(0x3F8 + 3, 0x80);
IO::out8(0x3F8 + 0, 0x02);
IO::out8(0x3F8 + 1, 0x00);
IO::out8(0x3F8 + 3, 0x03);
IO::out8(0x3F8 + 2, 0xC7);
IO::out8(0x3F8 + 4, 0x0B);
serial_ready = true;
}
while ((IO::in8(0x3F8 + 5) & 0x20) == 0)
;
if (ch == '\n' && !was_cr)
IO::out8(0x3F8, '\r');
IO::out8(0x3F8, ch);
if (ch == '\r')
was_cr = true;
else
was_cr = false;
}
static void console_out(char ch)
{
if (serial_debug)
serial_putch(ch);
// It would be bad to reach the assert in Console()::the() and do a stack overflow
if (Console::is_initialized()) {
Console::the().put_char(ch);
} else {
IO::out8(0xe9, ch);
}
}
static void console_putch(char*&, char ch)
{
console_out(ch);
}
int kprintf(const char* fmt, ...)
{
color_on();
va_list ap;
va_start(ap, fmt);
int ret = printf_internal(console_putch, nullptr, fmt, ap);
va_end(ap);
color_off();
return ret;
}
static void buffer_putch(char*& bufptr, char ch)
{
*bufptr++ = ch;
}
int sprintf(char* buffer, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
int ret = printf_internal(buffer_putch, buffer, fmt, ap);
buffer[ret] = '\0';
va_end(ap);
return ret;
}
static void debugger_out(char ch)
{
if (serial_debug)
serial_putch(ch);
IO::out8(0xe9, ch);
}
static void debugger_putch(char*&, char ch)
{
debugger_out(ch);
}
extern "C" int dbgputstr(const char* characters, int length)
{
if (!characters)
return 0;
for (int i = 0; i < length; ++i)
debugger_out(characters[i]);
return 0;
}
extern "C" int kernelputstr(const char* characters, int length)
{
if (!characters)
return 0;
for (int i = 0; i < length; ++i)
console_out(characters[i]);
return 0;
}
extern "C" int dbgprintf(const char* fmt, ...)
{
color_on();
va_list ap;
va_start(ap, fmt);
int ret = printf_internal(debugger_putch, nullptr, fmt, ap);
va_end(ap);
color_off();
return ret;
}

51
Kernel/kstdio.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <AK/Types.h>
extern "C" {
int dbgprintf(const char* fmt, ...);
int dbgputstr(const char*, int);
int kernelputstr(const char*, int);
int kprintf(const char* fmt, ...);
int sprintf(char* buf, const char* fmt, ...);
void set_serial_debug(bool on_or_off);
int get_serial_debug();
}
#define printf dbgprintf
#ifdef __cplusplus
template<size_t N>
inline int dbgputstr(const char (&array)[N])
{
return ::dbgputstr(array, N);
}
#endif