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

Kernel: Add very simple PPM parser for Aarch64

This is much simpler and more embeddable version than libGFX one.
Solely purpose is to draw initial boot logo on screen before kernel
is even booted.
This commit is contained in:
Marcin Undak 2021-10-20 00:29:41 -04:00 committed by Andreas Kling
parent dbb61620be
commit e7141c4230
3 changed files with 150 additions and 0 deletions

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "BootPPMParser.h"
namespace Prekernel {
BootPPMParser::BootPPMParser(u8 const* buffer, u32 buffer_size)
{
m_cursor = reinterpret_cast<char const*>(buffer);
m_buffer_end = m_cursor + buffer_size;
}
bool BootPPMParser::parse()
{
if (!check_position()) {
return false;
}
if (!parse_magic()) {
return false;
}
if (!parse_new_line()) {
return false;
}
if (!parse_comment()) {
return false;
}
if (!parse_integer(image.width)) {
return false;
}
if (!parse_integer(image.height)) {
return false;
}
u32 max_color_value;
if (!parse_integer(max_color_value) || max_color_value != 255) {
return false;
}
image.pixel_data = reinterpret_cast<u8 const*>(m_cursor);
return true;
}
bool BootPPMParser::check_position() const
{
if (m_cursor >= m_buffer_end) {
return false;
}
return true;
}
bool BootPPMParser::parse_magic()
{
if (m_cursor[0] != 'P' || m_cursor[1] != '6') {
return false;
}
m_cursor += 2;
return check_position();
}
bool BootPPMParser::parse_new_line()
{
if (*m_cursor != '\n') {
return false;
}
++m_cursor;
return check_position();
}
bool BootPPMParser::parse_comment()
{
if (*m_cursor == '#') {
// Skip to the next new line character
while (check_position() && *m_cursor != '\n') {
++m_cursor;
}
++m_cursor;
}
return check_position();
}
bool BootPPMParser::parse_integer(u32& value)
{
auto begin = m_cursor;
while (check_position() && *m_cursor != ' ' && *m_cursor != '\n') {
++m_cursor;
}
auto end = m_cursor;
++m_cursor;
if (!check_position()) {
return false;
}
value = 0;
u32 multiplier = 1;
while (--end >= begin) {
value += multiplier * (*end - '0');
multiplier *= 10;
}
return true;
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
namespace Prekernel {
// Quick parser for .ppm image format (raw PortablePixMap)
// This is much simpler version than userland implementation in PPMLoader.cpp
class BootPPMParser {
public:
struct {
u32 width = 0;
u32 height = 0;
u8 const* pixel_data = nullptr;
} image;
BootPPMParser(u8 const* buffer, u32 buffer_size);
bool parse();
private:
char const* m_cursor;
char const* m_buffer_end;
bool check_position() const;
bool parse_magic();
bool parse_new_line();
bool parse_comment();
bool parse_integer(u32& value);
};
}

View file

@ -6,6 +6,7 @@ if ("${SERENITY_ARCH}" STREQUAL "aarch64")
set(SOURCES set(SOURCES
${SOURCES} ${SOURCES}
Arch/aarch64/Aarch64_asm_utils.S Arch/aarch64/Aarch64_asm_utils.S
Arch/aarch64/BootPPMParser.cpp
Arch/aarch64/GPIO.cpp Arch/aarch64/GPIO.cpp
Arch/aarch64/Framebuffer.cpp Arch/aarch64/Framebuffer.cpp
Arch/aarch64/Mailbox.cpp Arch/aarch64/Mailbox.cpp