mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-26 11:41:35 +01:00
gem5 internals: document python c++ interface
This commit is contained in:
128
README.adoc
128
README.adoc
@@ -10380,7 +10380,7 @@ The only hairy thing in QEMU is the binary code generation.
|
|||||||
+
|
+
|
||||||
gem5 however has tended towards intensive code generation in order to support all its different hardware types:
|
gem5 however has tended towards intensive code generation in order to support all its different hardware types:
|
||||||
+
|
+
|
||||||
*** lots of magic happen on top of pybind11, which is already magic, to more automatically glue the C++ and Python worlds
|
*** lots of magic happen on top of pybind11, which is already magic, to more automatically glue the C++ and Python worlds: <<gem5-python-c-interaction>>
|
||||||
*** .isa code which describes most of the instructions
|
*** .isa code which describes most of the instructions
|
||||||
*** <<gem5-ruby-build,Ruby>> for memory systems
|
*** <<gem5-ruby-build,Ruby>> for memory systems
|
||||||
|
|
||||||
@@ -12187,6 +12187,132 @@ xdg-open "$(./getvar --arch aarch64 --gem5-build-id ruby gem5_build_build_dir)/A
|
|||||||
|
|
||||||
A minimized ruby config which was not merged upstream can be found for study at: https://gem5-review.googlesource.com/c/public/gem5/+/13599/1
|
A minimized ruby config which was not merged upstream can be found for study at: https://gem5-review.googlesource.com/c/public/gem5/+/13599/1
|
||||||
|
|
||||||
|
=== gem5 internals
|
||||||
|
|
||||||
|
==== gem5 Python C++ interaction
|
||||||
|
|
||||||
|
The interaction uses the Python C extension interface https://docs.python.org/2/extending/extending.html interface through the pybind11 helper library: https://github.com/pybind/pybind11
|
||||||
|
|
||||||
|
The C++ executable both:
|
||||||
|
|
||||||
|
* starts running the Python executable
|
||||||
|
* provides Python classes written in C++ for that Python code to use
|
||||||
|
|
||||||
|
An example of this can be found at:
|
||||||
|
|
||||||
|
* https://docs.python.org/2/extending/embedding.html#extending-embedded-python
|
||||||
|
* https://github.com/pybind/pybind11/tree/v2.2.3/tests/test_embed
|
||||||
|
|
||||||
|
then gem5 magic `simobject` class adds some crazy stuff on top of it further... is is a mess. in particular, it auto generates `params/` headers. TODO: why is this mess needed at all? pybind11 seems to handle constructor arguments just fine:
|
||||||
|
|
||||||
|
* https://github.com/pybind/pybind11/blob/v2.2.3/tests/test_class.py#L77
|
||||||
|
* https://github.com/pybind/pybind11/blob/v2.2.3/tests/test_class.cpp#L41
|
||||||
|
|
||||||
|
Let's study `BadDevice` for example:
|
||||||
|
|
||||||
|
`src/dev/BadDevice.py` defines `devicename`:
|
||||||
|
|
||||||
|
....
|
||||||
|
class BadDevice(BasicPioDevice):
|
||||||
|
type = 'BadDevice'
|
||||||
|
cxx_header = "dev/baddev.hh"
|
||||||
|
devicename = Param.String("Name of device to error on")
|
||||||
|
....
|
||||||
|
|
||||||
|
The object is created in Python for example from `src/dev/alpha/Tsunami.py` as:
|
||||||
|
|
||||||
|
....
|
||||||
|
fb = BadDevice(pio_addr=0x801fc0003d0, devicename='FrameBuffer')
|
||||||
|
....
|
||||||
|
|
||||||
|
Since `BadDevice` has no `+__init__+` method, and neither `BasicPioDevice`, it all just falls through until the SimObject.__init__ constructor.
|
||||||
|
|
||||||
|
This constructor will loop through the inheritance chain and give the Python parameters to the C++ BadDeviceParams class as follows.
|
||||||
|
|
||||||
|
The auto-generated `build/ARM/params/BadDevice.hh` file defines BadDeviceParams in C++:
|
||||||
|
|
||||||
|
....
|
||||||
|
#ifndef __PARAMS__BadDevice__
|
||||||
|
#define __PARAMS__BadDevice__
|
||||||
|
|
||||||
|
class BadDevice;
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "params/BasicPioDevice.hh"
|
||||||
|
|
||||||
|
struct BadDeviceParams
|
||||||
|
: public BasicPioDeviceParams
|
||||||
|
{
|
||||||
|
BadDevice * create();
|
||||||
|
std::string devicename;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __PARAMS__BadDevice__
|
||||||
|
....
|
||||||
|
|
||||||
|
and `./python/_m5/param_BadDevice.cc` defines the param Python from C++ with pybind11:
|
||||||
|
|
||||||
|
....
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
static void
|
||||||
|
module_init(py::module &m_internal)
|
||||||
|
{
|
||||||
|
py::module m = m_internal.def_submodule("param_BadDevice");
|
||||||
|
py::class_<BadDeviceParams, BasicPioDeviceParams, std::unique_ptr<BadDeviceParams, py::nodelete>>(m, "BadDeviceParams")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def("create", &BadDeviceParams::create)
|
||||||
|
.def_readwrite("devicename", &BadDeviceParams::devicename)
|
||||||
|
;
|
||||||
|
|
||||||
|
py::class_<BadDevice, BasicPioDevice, std::unique_ptr<BadDevice, py::nodelete>>(m, "BadDevice")
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static EmbeddedPyBind embed_obj("BadDevice", module_init, "BasicPioDevice");
|
||||||
|
....
|
||||||
|
|
||||||
|
`src/dev/baddev.hh` then uses the parameters on the constructor:
|
||||||
|
|
||||||
|
....
|
||||||
|
class BadDevice : public BasicPioDevice
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string devname;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef BadDeviceParams Params;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const Params *
|
||||||
|
params() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const Params *>(_params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor for the Baddev Class.
|
||||||
|
* @param p object parameters
|
||||||
|
* @param a base address of the write
|
||||||
|
*/
|
||||||
|
BadDevice(Params *p);
|
||||||
|
....
|
||||||
|
|
||||||
|
`src/dev/baddev.cc` then uses the parameter:
|
||||||
|
|
||||||
|
....
|
||||||
|
BadDevice::BadDevice(Params *p)
|
||||||
|
: BasicPioDevice(p, 0x10), devname(p->devicename)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
....
|
||||||
|
|
||||||
|
Tested on gem5 08c79a194d1a3430801c04f37d13216cc9ec1da3.
|
||||||
|
|
||||||
== Buildroot
|
== Buildroot
|
||||||
|
|
||||||
=== Introduction to Buildroot
|
=== Introduction to Buildroot
|
||||||
|
|||||||
Reference in New Issue
Block a user