diff --git a/repos/os/recipes/src/log_core/content.mk b/repos/os/recipes/src/log_core/content.mk new file mode 100644 index 0000000000..bd9e705fce --- /dev/null +++ b/repos/os/recipes/src/log_core/content.mk @@ -0,0 +1,2 @@ +SRC_DIR = src/app/log_core +include $(GENODE_DIR)/repos/base/recipes/src/content.inc diff --git a/repos/os/recipes/src/log_core/hash b/repos/os/recipes/src/log_core/hash new file mode 100644 index 0000000000..70c4700841 --- /dev/null +++ b/repos/os/recipes/src/log_core/hash @@ -0,0 +1 @@ +2017-12-13-b 766edac0917548ff49d04226d07e314b5b05b48a diff --git a/repos/os/recipes/src/log_core/used_apis b/repos/os/recipes/src/log_core/used_apis new file mode 100644 index 0000000000..3a7f09b08d --- /dev/null +++ b/repos/os/recipes/src/log_core/used_apis @@ -0,0 +1,3 @@ +base +os +timer_session diff --git a/repos/os/run/log_core.run b/repos/os/run/log_core.run new file mode 100644 index 0000000000..e3ad2fe589 --- /dev/null +++ b/repos/os/run/log_core.run @@ -0,0 +1,91 @@ +if {[have_spec linux]} { + puts "\n Run script is not supported on this platform. \n"; + exit 0 +} +if {[get_cmd_switch --autopilot] && ![have_include "power_on/qemu"]} { + puts "\n Run script is not supported on this platform. \n"; + exit 0 +} + +proc log_service { } { + if { [get_cmd_switch --autopilot] } { return log } + return ram +} + +build "core init drivers/timer server/vfs server/fs_log app/log_core" + +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <} [log_service] { name="log.log"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +build_boot_image "core init timer ld.lib.so vfs fs_log log_core" + +append qemu_args " -nographic " + +if { [get_cmd_switch --autopilot] } { + run_genode_until {.*\[init -> vfs] \[.*\n} 20 +} else { + run_genode_until forever +} diff --git a/repos/os/src/app/log_core/component.cc b/repos/os/src/app/log_core/component.cc new file mode 100644 index 0000000000..c35da4a5e2 --- /dev/null +++ b/repos/os/src/app/log_core/component.cc @@ -0,0 +1,126 @@ +/* + * \brief Component transforming core and kernel output to Genode LOG output + * \author Alexander Boettcher + * \date 2016-12-22 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* base includes */ +#include +#include + +/* os includes */ +#include +#include + + +class Log +{ + private: + + Genode::Attached_rom_dataspace _rom_ds; + Genode::Log_connection _log; + + char _buffer [Genode::Log_session::MAX_STRING_LEN + 1]; + unsigned short _buf_pos { 0 }; + unsigned _rom_pos { 0 }; + + unsigned log_size() const { return _rom_ds.size() - sizeof(_rom_pos); } + + char const * char_from_rom(unsigned offset = 0) const + { + return _rom_ds.local_addr() + sizeof(_rom_pos) + + (_rom_pos + offset) % log_size(); + } + + unsigned next_pos(unsigned pos) const { + return (pos + 1) % log_size(); } + + unsigned end_pos() const { + return *_rom_ds.local_addr() % log_size(); } + + void _rom_to_log(unsigned const last_pos) + { + unsigned up_to_pos = last_pos; + + for (; _rom_pos != next_pos(up_to_pos) + ; _rom_pos = next_pos(_rom_pos), up_to_pos = end_pos()) { + + char const c = *char_from_rom(); + + _buffer[_buf_pos++] = c; + + if (_buf_pos + 1U < sizeof(_buffer) && c != '\n') + continue; + + _buffer[_buf_pos] = 0; + _log.write(Genode::Log_session::String(_buffer)); + _buf_pos = 0; + } + } + + public: + + Log (Genode::Env &env, char const * const rom_name, + char const * const log_name) + : _rom_ds(env, rom_name), _log(env, log_name) + { + unsigned const pos = end_pos(); + + /* initial check whether already log wrapped at least one time */ + enum { COUNT_TO_CHECK_FOR_WRAP = 8 }; + for (unsigned i = 1; i <= COUNT_TO_CHECK_FOR_WRAP; i++) { + if (*char_from_rom(pos + i) == 0) + continue; + + /* wrap detected, set pos behind last known pos */ + _rom_pos = next_pos(pos + 1) % log_size(); + break; + } + + _rom_to_log(pos); + } + + void log() { _rom_to_log(end_pos()); } +}; + +struct Monitor +{ + Genode::Env &env; + + Log output { env, "log", "log" }; + + Timer::Connection timer { env }; + + Genode::Signal_handler interval { env.ep(), *this, &Monitor::check }; + + Monitor(Genode::Env &env) : env(env) + { + timer.sigh(interval); + + Genode::addr_t period_ms = 1000; + + try { + Genode::Attached_rom_dataspace config { env, "config" }; + period_ms = config.xml().attribute_value("period_ms", 1000UL); + } catch (...) { } + + Genode::log("update every ", period_ms," ms"); + + timer.trigger_periodic(1000UL * period_ms); + } + + void check() + { + output.log(); + } +}; + + +void Component::construct(Genode::Env &env) { static Monitor output(env); } diff --git a/repos/os/src/app/log_core/target.mk b/repos/os/src/app/log_core/target.mk new file mode 100644 index 0000000000..249fd0ce29 --- /dev/null +++ b/repos/os/src/app/log_core/target.mk @@ -0,0 +1,3 @@ +TARGET = log_core +SRC_CC = component.cc +LIBS = base diff --git a/tool/autopilot.list b/tool/autopilot.list index c348601566..967baea254 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -105,3 +105,4 @@ nic_dump slab ada fs_report +log_core