diff --git a/run/child_intercepted_log.run b/run/child_intercepted_log.run new file mode 100644 index 0000000..6cc6c13 --- /dev/null +++ b/run/child_intercepted_log.run @@ -0,0 +1,96 @@ +# +# Build +# + +set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]] +set use_nic_driver [expr !$use_usb_driver && ![have_spec odroid_xu] && ![have_spec linux]] + +if {[expr !$use_usb_driver && !$use_nic_driver] || + [expr [have_spec imx53] && [have_spec trustzone]]} { + puts "\n Run script is not supported on this platform. \n"; exit 0 } + +set build_components { + core init + drivers/timer drivers/nic + app/child_intercepted_log app/hello +} + +lappend_if $use_usb_driver build_components drivers/usb +lappend_if [have_spec gpio] build_components drivers/gpio + +proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv } + if {[have_spec rpi] && [have_spec foc]} { return foc_gpio_drv } + return gpio_drv } + +source ${genode_dir}/repos/base/run/platform_drv.inc +append_platform_drv_build_components + +build $build_components + +create_boot_directory + +# +# Generate config +# + +set config { + + + + + + + + + + + + + + + + + + + + + + } + +append_if [have_spec gpio] config " + + + + + " + +append_if $use_usb_driver config { + + + + + + + + + } + +append_platform_drv_config + +append config { + +} + +install_config $config + +# +# Boot image +# + +build_boot_image { core ld.lib.so init child_intercepted_log hello timer } + +append qemu_args " -nographic " + +#append_if [have_spec lan9119] qemu_args " -net nic,macaddr=02:00:00:00:01:03 -net nic,model=lan9118 -net tap,ifname=tap0,script=no " + +run_genode_until forever diff --git a/src/app/child_intercepted_log/main.cc b/src/app/child_intercepted_log/main.cc new file mode 100644 index 0000000..6ff536d --- /dev/null +++ b/src/app/child_intercepted_log/main.cc @@ -0,0 +1,185 @@ +#include +#include + +#include + +#include +#include + +#include + +#include + +/* custom services */ +#include + +using namespace Genode; + +namespace Custom { + class Log_session_component; + class Log_session_factory; +} + +class MyChild : public Child_policy { +public: + typedef Genode::Registered Parent_service; + typedef Genode::Registry Parent_services; +private: + Env &_env; + Cap_quota const _cap_quota {50}; + Ram_quota const _ram_quota {1 * 1024 * 1024}; + + Parent_services &_parent_services; + Genode::Local_service &_ls; + + Child _child; + + template + static Genode::Service *_find_service(Genode::Registry &services, + Genode::Service::Name const &name) + { + Genode::Service *service = nullptr; + services.for_each([&] (T &s) { + if (!service && (s.name() == name)) + service = &s; }); + return service; + } + +public: + MyChild(Env &env, Parent_services &parent_services, Genode::Local_service &ls) + : + _env(env), _parent_services(parent_services), _ls(ls), _child(_env.rm(), _env.ep().rpc_ep(), *this) + {} + ~MyChild() { }; + + Name name() const override { return "hello"; }; + + Pd_session &ref_pd() override { return _env.pd(); } + Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); } + + void init(Pd_session &pd, Pd_session_capability pd_cap) override + { + pd.ref_account(ref_pd_cap()); + ref_pd().transfer_quota(pd_cap, _cap_quota); + ref_pd().transfer_quota(pd_cap, _ram_quota); + } + + Genode::Child_policy::Route + resolve_session_request(Genode::Service::Name const &service_name, + Genode::Session_label const &label) override + { + auto route = [&] (Genode::Service &service) { + return Genode::Child_policy::Route { .service = service, + .label = label, + .diag = Genode::Session::Diag() }; }; + + Genode::Service *service = nullptr; + service = _find_service(_parent_services, service_name); + if (!strcmp("LOG", service_name.string())) { + service = &_ls; + } + return route(*service); + } +}; + +namespace Example { + struct Main; +} + +class Custom::Log_session_component : public Genode::Rpc_object +{ + Genode::Rpc_entrypoint &_ep; + Genode::Env &_env; + Genode::Log_connection _parent_log; + + public: + + Log_session_component(Genode::Rpc_entrypoint &ep, Genode::Env &env, const char *label) + : + _ep(ep), + _env(env), + _parent_log(env, label) + { + _ep.manage(this); + } + + ~Log_session_component() { + _ep.dissolve(this); + } + + size_t write(String const &string_buf) { + Genode::log("interception!"); + auto result = _parent_log.write(string_buf); + return result; + } +}; + +class Custom::Log_session_factory : public Genode::Local_service::Factory +{ + Genode::Allocator &_alloc; + Genode::Rpc_entrypoint &_ep; + Genode::Env &_env; + + public: + + Log_session_factory(Genode::Allocator &alloc, Genode::Rpc_entrypoint &ep, Genode::Env &env) + : + _alloc(alloc), + _ep(ep), + _env(env) + { } + + Custom::Log_session_component &create(Args const &, Genode::Affinity) override + { + Genode::log("creating log_session_component"); + return *new (_alloc) Custom::Log_session_component(_ep, _env, "test"); + } + + void upgrade(Custom::Log_session_component &, Args const &) override { } + + void destroy(Custom::Log_session_component &session) override + { + Genode::destroy(_alloc, &session); + } +}; + +struct Example::Main +{ + Genode::Env &_env; + + Genode::Heap _heap { _env.ram(), _env.rm() }; + + MyChild::Parent_services _parent_services { }; + + Main(Genode::Env &env) : _env(env) + { + const char *names[] = { "RM", "PD", "CPU", "IO_MEM", "IO_PORT", "IRQ", "ROM", "LOG", 0 }; + + for (unsigned i = 0; names[i]; i++) { + new (_heap) MyChild::Parent_service(_parent_services, env, names[i]); + } + + /* custom service */ + // create new entrypoint + Genode::Entrypoint *_ep = new (_heap) Genode::Entrypoint(_env, 16 * 1024, "custom ep"); + Custom::Log_session_factory _clf { _heap, _ep->rpc_ep(), _env }; + Genode::Local_service ls { _clf }; + /******************/ + + new (_heap) MyChild(_env, _parent_services, ls); + } +}; + +void Component::construct(Genode::Env &env) +{ + Genode::log("Hello World from child!"); + + static Example::Main main(env); + + /* The component does not exit after the construct function returns. Instead, it be- + * comes ready to respond to requests or signals originating from other components. The + * example above does not interact with other components though. + * + * Genode Foundations p. 30 + */ +} diff --git a/src/app/child_intercepted_log/target.mk b/src/app/child_intercepted_log/target.mk new file mode 100644 index 0000000..6bafbd0 --- /dev/null +++ b/src/app/child_intercepted_log/target.mk @@ -0,0 +1,3 @@ +TARGET = child_intercepted_log +SRC_CC = main.cc +LIBS = base