{"id":10158,"date":"2022-08-17T09:26:05","date_gmt":"2022-08-17T09:26:05","guid":{"rendered":"https:\/\/digitalgateamg.com\/?p=10158"},"modified":"2023-08-08T14:46:20","modified_gmt":"2023-08-08T14:46:20","slug":"qemu-development-during-the-chip-shortage","status":"publish","type":"post","link":"https:\/\/digitalgateamg.com\/de\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/","title":{"rendered":"QEMU-Entwicklung"},"content":{"rendered":"<p data-renderer-start-pos=\"37\">In Anbetracht der aktuellen Entwicklungen auf dem Weltmarkt, insbesondere der weltweiten Chip-Knappheit, gibt es einige Probleme, die bei der Bereitstellung von Software auf einer Embedded-Plattform zu l\u00f6sen sind, aber es fehlt die Plattform selbst.<\/p>\n<p data-renderer-start-pos=\"37\">Das ist kein leichtes Unterfangen, insbesondere f\u00fcr Unternehmen, die Software f\u00fcr verschiedene Plattformen einsetzen und nicht die M\u00f6glichkeit haben, die Vielzahl der auf dem Markt erh\u00e4ltlichen SoCs auf Lager zu haben. Es gibt auch die Situation, dass ein neuer Chip in der Entwicklung ist und die Software daf\u00fcr aus Effizienzgr\u00fcnden parallel entwickelt werden muss.<\/p>\n<p data-renderer-start-pos=\"636\">In Anbetracht all dessen muss es praktisch sein, Hardware auf unseren Standard-x64-Maschinen zu emulieren. Aber was tun wir, wenn unterschiedliche Speicherkarten oder sogar ISAs (Instruction Set Architectures) beteiligt sind? Bei dieser Aufgabe kommen die F\u00e4higkeiten von QEMU zur Hilfe.<\/p>\n<p data-renderer-start-pos=\"891\">Dieser Artikel dokumentiert die Schritte, die erforderlich sind, um eine benutzerdefinierte Maschine zu QEMUs bestehenden Maschinen hinzuzuf\u00fcgen und die etablierten Konstrukte in QEMU zu nutzen und sogar die Open-Source-Natur des Projekts zu nutzen.<\/p>\n<h2>Eine kurze QEMU-Beschreibung<\/h2>\n<p data-renderer-start-pos=\"1138\">QEMU als Open-Source-Maschinenemulator und Virtualisierer. Das bedeutet, dass er sowohl als VM Ihrer Wahl als auch als Maschinenvirtualisierer fungieren kann, indem er Speicherabbildungen der tats\u00e4chlichen Hardware nachahmt und (f\u00fcr die als Gast ausgef\u00fchrte Software sichtbare) Effekte erzeugt, die dem entsprechenden Hardware-Gegenst\u00fcck sehr \u00e4hnlich sind.<\/p>\n<p data-renderer-start-pos=\"1466\">Es unterst\u00fctzt derzeit eine Vielzahl von ARM-G\u00e4sten und bietet Unterst\u00fctzung f\u00fcr etwa f\u00fcnfzig verschiedene Maschinen. Es werden sowohl \u201eA-Profil\"-CPUs als auch \u201eM-Profil\"-CPUs unterst\u00fctzt, wenn auch in einer numerisch begrenzteren Form, was die Maschinen betrifft.<\/p>\n<p data-renderer-start-pos=\"1733\" class=\"translation-block\">Obwohl Unterst\u00fctzung f\u00fcr eine Vielzahl von spezifischen Maschinen und SoCs angeboten wird, wird auch eine virtuelle Maschine angeboten. Diese Maschine, virt genannt, ist eine allgemeine ARM-Systememulationsvariante. Virt bietet eine Vielzahl von unterst\u00fctzten \u201ecpus\" (z. B. cortex-a15, cortex-a53 usw.) und verschiedene Peripherieger\u00e4te an. Die Verwendung dieser Maschine ist nur dann zu empfehlen, wenn die Besonderheiten der spezifischen Hardware und ihre Beschr\u00e4nkungen bei der Softwareentwicklung ignoriert werden.<\/p>\n<h2>Systemanforderungen<\/h2>\n<p data-renderer-start-pos=\"2219\">QEMU kann auf den folgenden Host-Plattformen ausgef\u00fchrt werden:<\/p>\n<ul>\n<li data-renderer-start-pos=\"2219\">Linux<\/li>\n<li data-renderer-start-pos=\"2219\">Microsoft Windows<\/li>\n<li data-renderer-start-pos=\"2219\">macOS<\/li>\n<li data-renderer-start-pos=\"2219\">einige andere UNIX-Plattformen<\/li>\n<\/ul>\n<h2>Initialisierung<\/h2>\n<p data-renderer-start-pos=\"2361\">F\u00fcr die Ausf\u00fchrung von QEMU wird die Verwendung eines Linux-basierten Systems als Host empfohlen, zumindest f\u00fcr den speziellen Fall dieses Artikels. In diesem Fall l\u00e4uft QEMU auf einer Ubuntu-Version 18.04.<\/p>\n<p data-renderer-start-pos=\"2555\">Die f\u00fcr dieses Beispiel verwendete QEMU-Version ist auf GitHub mit dem Tag v.7.0.0 gekennzeichnet.<\/p>\n<p data-renderer-start-pos=\"2360\" class=\"translation-block\"><strong>DISCLAIMER:<\/strong> Dies ist kein vollwertiges Tutorial, wenn Sie erwarten, dass Sie am Ende eine spezifische Maschine implementiert haben, mit genauen Adressen und anderen Parametern einer spezifischen Maschine, w\u00fcrde ich das Tutorial empfehlen, das in den Referenzen von S. Sopha erw\u00e4hnt wird (mit dem Hinweis, dass das FreeRTOS-Tutorial, das ben\u00f6tigt wird, um die Maschinenimplementierung zu \u00fcberpr\u00fcfen, nicht vollst\u00e4ndig ist). Die vorliegende Arbeit dokumentiert eine andere Sichtweise auf die Implementierung einer Maschine in QEMU und sie zielt darauf ab, mehr erkl\u00e4rend als praktisch zu sein, beginnend mit dem Teil <em>\u201eKlonen bereits existierender Quell- und Header-Dateien\".<\/em> Zuvor k\u00f6nnen Sie dem Tutorial Schritt f\u00fcr Schritt folgen und die praktischen Anforderungen erf\u00fcllen.<\/p>\n<h2>Klonen des Git-Repositorys<\/h2>\n<p data-renderer-start-pos=\"2360\">Um die aktuellste Version von QEMU zu klonen, sollten Sie den folgenden Befehl ausf\u00fchren:<\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>git clone https:\/\/github.com\/qemu\/qemu<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<h2>Vorbereitungen f\u00fcr den Aufbau<\/h2>\n<p data-renderer-start-pos=\"2360\">Es gibt eine Reihe von Abh\u00e4ngigkeiten, die f\u00fcr den erfolgreichen Betrieb von QEMU erforderlich sind, aber das folgende Skript sollte zumindest f\u00fcr die Version 7.0.0 von QEMU ausreichend sein:<\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp># Set up locales\napt-get update && apt-get install -y \n    apt-utils locales sudo && \n    dpkg-reconfigure locales && \n    locale-gen en_US.UTF-8 && \n    update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \n    apt-get clean && \n    rm -rf \/var\/lib\/apt\/lists\/*\napt-get update && apt-get install -y \n    git \n    build-essential \n    zlib1g-dev \n    pkg-config \n    libglib2.0-dev \n    binutils-dev \n    libboost-all-dev \n    autoconf \n    libtool \n    libssl-dev \n    libpixman-1-dev \n    libpython-dev \n    python-pip \n    python-capstone \n    virtualenv && \n    apt-get clean && \n    rm -rf \/var\/lib\/apt\/lists\/*\napt update -y\napt upgrade -y\napt install ninja-build<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<h2>Konfigurieren und Erstellen<\/h2>\n<p data-renderer-start-pos=\"4245\" class=\"translation-block\">F\u00fcr die Konfiguration und den Build muss sichergestellt werden, dass ein Build-Verzeichnis innerhalb des QEMU-Repositorys existiert. Die ausgew\u00e4hlte Konfiguration ist in Zeile 4 markiert und gilt f\u00fcr eine Reihe von 32-Bit- und 64-Bit-ARM-unterst\u00fctzten Maschinen. Diese Konfiguration umfasst auch die <em>virt<\/em> generic machine.<\/p>\n<p data-renderer-start-pos=\"4539\" class=\"translation-block\"><strong>! Warnung:<\/strong> Wenn Sie \u00c4nderungen an Quell- oder Headerdateien vornehmen, die bereits von <em>configure <\/em>eingebunden wurden, m\u00fcssen Sie configure beim Kompilieren nicht erneut ausf\u00fchren. Sie sollten nur <em>make<\/em> ausf\u00fchren,  da es sehr zeitaufwendig ist,  diese zahlreichen Header- und Quelldateien von Grund auf zu kompilieren.<\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>cd qemu \nmkdir build \ncd build \n..\/configure --target-list=aarch64-softmmu # preparing the build for ARM machines running on 64 and 32 bits\nmake<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<h2>Pr\u00fcfen der Maschinenliste<\/h2>\n<p data-renderer-start-pos=\"4370\">Um die Maschinenliste zu \u00fcberpr\u00fcfen, verwenden Sie die folgenden Befehle:<\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>cd qemu\ncd build\ncd aarch64-softmmu\n.\/qemu-system-aarch64 -M help<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<p data-renderer-start-pos=\"4370\">Dieser Befehl ist n\u00fctzlich, um zu \u00fcberpr\u00fcfen, ob der Kompilierungsprozess korrekt durchgef\u00fchrt wurde und er wird n\u00fctzlich sein, wenn Sie versuchen, die benutzerdefinierte Maschine zu QEMU hinzuzuf\u00fcgen.<\/p>\n<h2>Betrieb eines Rechners<\/h2>\n<p data-renderer-start-pos=\"4370\" class=\"translation-block\">Zum Betrieb eines Rechners sind m\u00f6glicherweise ein Kernel-Image und eine Ger\u00e4tebaumdatei (<em>.dtb - device tree blob file<\/em>) erforderlich. Das Kernel-Image kann ein von buildroot kompiliertes Linux-Kernel-Image sein oder auch Yocto kann f\u00fcr diese Aufgabe verwendet werden. Die Kompilierung eines Linux-Kernel-Images liegt au\u00dferhalb des Rahmens dieses Tutorials. Die .dtb-Datei beschreibt die Speicherzuordnungen der darstellenden Hardware.<\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp># Follow the steps from the pervious code snippet to get to the qemu-system-aarch64 file, or use make install instead of just make\n.\/qemu-system-aarch64 -M <machine_selected_from_list> \n                      -kernel <path_to_kernel_image_file> \n                      -dtb <path_to_dtb_file><\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<h2>Hinzuf\u00fcgen eines neuen Rechners zu QEMU<\/h2>\n<p data-renderer-start-pos=\"6154\" class=\"translation-block\">Nennen wir den neuen Rechner <em>arm-example<\/em> oder <em>ARM_EXAMPLE<\/em>, um allgemein genug zu sein. Daher werden wir im weiteren Verlauf dieses Abschnitts diese Namenskonvention verwenden.<\/p>\n<p data-renderer-start-pos=\"6305\" class=\"translation-block\">Damit der Rechner beim Aufruf von  <em>.\/qemu-system-aarch64 -M help<\/em> erscheint, m\u00fcssen Sie ihn zu den Dateien <em>Kconfig, meson.build<\/em> hinzuf\u00fcgen.<\/p>\n<p data-renderer-start-pos=\"6427\">Nach dem Hinzuf\u00fcgen der genannten Teile werden die Quell- und Headerdateien von einem Rechner kopiert, der \u00e4hnlich genug ist, um weiter implementiert zu werden.<\/p>\n<p data-renderer-start-pos=\"6558\">An den Variablen, die die Adressen des Rechners darstellen, m\u00fcssen \u00c4nderungen vorgenommen werden. Au\u00dferdem k\u00f6nnte es erforderlich sein, Konstanten zu \u00e4ndern, die den Maschinennamen, den Typ, die Uhren und die Unterbrechungsroutinen darstellen.<\/p>\n<h2>Hinzuf\u00fcgen eines Rechners zur Konfiguration<\/h2>\n<p data-renderer-start-pos=\"6792\" class=\"translation-block\">Da es sich um einen ARM 64-Bit-Rechner handelt, muss zun\u00e4chst das Verzeichnis <em>hw\/arm<\/em> innerhalb des <em>qemu<\/em>-Verzeichnisses gefunden werden. Dort werden die Dateien <em>meson.build<\/em> und <em>Kconfig<\/em> wie in den folgenden Schnipseln ge\u00e4ndert:<\/p>\n<ul>\n<li data-renderer-start-pos=\"6992\"><em data-renderer-mark=\"true\">Kconfig:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>config RASPI\n    bool\n    select FRAMEBUFFER\n    select PL011 # UART\n    select SDHCI\n    select USB_DWC2\n# beginning of added arm-example\/ARM_EXAMPLE \nconfig ARM_EXAMPLE\n    bool\n    select PL011 # UART for a latter implementation, it can even be commented\n# end of added arm-example\/ARM_EXAMPLE\nconfig STM32F100_SOC\n    bool\n    select ARM_V7M\n    select STM32F2XX_USART\n    select STM32F2XX_SPI<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"6792\"><em data-renderer-mark=\"true\">meson.build:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c', 'bcm2836.c', 'raspi.c'))\n# beginning of added arm-example\/ARM_EXAMPLE file(s)\narm_ss.add(when: 'CONFIG_ARM_EXAMPLE', if_true: files('arm-example.c'))\n# end of added arm-example\/ARM_EXAMPLE file(s)\narm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<p data-renderer-start-pos=\"7766\" class=\"translation-block\">Im Verzeichnis <em>configs\/devices\/<\/em> m\u00fcssen Sie die Datei <em>arm-softmmu.mak<\/em> wie folgt \u00e4ndern.<\/p>\n<p data-renderer-start-pos=\"7861\"><em data-renderer-mark=\"true\">arm-softmmu.mak<\/em>:<\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>CONFIG_TOSA=y\n# beginning of added arm-example\/ARM_EXAMPLE\nCONFIG_ARM_EXAMPLE=y\n# end of added arm-example\/ARM_EXAMPLE\nCONFIG_Z2=y<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<h2>Klonen bereits vorhandener Quell- und Header-Dateien<\/h2>\n<p data-renderer-start-pos=\"8063\" class=\"translation-block\">Die Hauptquelldatei <em>raspi.c<\/em> und die entsprechenden Header- und Abh\u00e4ngigkeitsdateien werden entweder geklont oder in ihrer urspr\u00fcnglichen Form beibehalten, damit dieses Beispiel funktioniert.<\/p>\n<p data-renderer-start-pos=\"8212\" class=\"translation-block\">Kopieren Sie die Datei <em>raspi.c<\/em> und benennen Sie sie in <em>arm-example.c<\/em> um.<\/p>\n<p data-renderer-start-pos=\"8268\" class=\"translation-block\">In der Datei <em>arm-example.c<\/em> wird die folgende Struktur verwendet:<\/p>\n<ul>\n<li>Header-Dateien;<\/li>\n<li data-renderer-start-pos=\"8337\">Konstanten, die den Namen, die Firmware-Adresse, die Makroinitialisierung des Rechnernamens usw. darstellen;<\/li>\n<li data-renderer-start-pos=\"8337\" class=\"translation-block\">Funktion <em>board_ram_size<\/em> - zum Abrufen der Gr\u00f6\u00dfe des verf\u00fcgbaren RAM-Speichers auf der Karte;<\/li>\n<li data-renderer-start-pos=\"8337\" class=\"translation-block\">Funktion <em>setup_boot<\/em> - pr\u00fcft, ob Firmware vorhanden ist und l\u00e4dt den Kernel;<\/li>\n<li data-renderer-start-pos=\"8337\" class=\"translation-block\">Funktion <em>arm_example_machine_init<\/em> - Initialisierung der verschiedenen Ger\u00e4te, die von diesem Rechner verwendet werden (z. B. SoC);<\/li>\n<li data-renderer-start-pos=\"8337\" class=\"translation-block\">Funktion <em>arm_example_machine_class_common_init<\/em> - deklariert die Namen und einige Variablen, die in der MachineClass Datenstruktur vorhanden sind;<\/li>\n<li data-renderer-start-pos=\"8337\" class=\"translation-block\">Funktion <em>arm_example_machine_class_init<\/em> - deklariert allgemeine Namen und Variablen in der MachineClass Datenstruktur;<\/li>\n<li data-renderer-start-pos=\"8337\" class=\"translation-block\">Constant <em>arm_example_machine_types<\/em> - deklariert Felder, die f\u00fcr die Registrierung der Maschine in der QEMU-Liste der Maschinen verwendet werden und verkn\u00fcpft die Initialisierungsfunktionen von oben mit dem Maschinentyp;<\/li>\n<li data-renderer-start-pos=\"8337\" class=\"translation-block\">Aufruf der durch das <strong>DEFINE_TYPES<\/strong>-Makro definierten Funktion - wird verwendet, um die Maschine durch Aufruf der oben beschriebenen TypeInfo-Konstante an die Liste der Maschinen anzuh\u00e4ngen.<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"9331\">Im Folgenden werden die Schnipsel f\u00fcr diese Teile des Codes vorgestellt. Die Reihenfolge ist von unten nach oben.<\/p>\n<ul>\n<li>DEFINE_TYPES MACRO<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>DEFINE_TYPES(arm_example_machine_types)<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li>CONSTANT arm_example_machine_types<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static const TypeInfo arm_example_machine_types[] = {\n    {\n        .name           = MACHINE_TYPE_NAME(\"arm-example\"),\n        .parent         = TYPE_ARM_EXAMPLE_MACHINE,\n        .class_init     = arm_example_machine_class_init,\n    },\n    {\n        .name           = TYPE_ARM_EXAMPLE_MACHINE,\n        .parent         = TYPE_MACHINE,\n        .instance_size  = sizeof(ARMExampleMachineState),\n        .class_size     = sizeof(ARMExampleMachineClass),\n        .abstract       = true, \n    }\n};<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li>FUNKTION arm_example_machine_class_init<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_machine_class_init(ObjectClass *oc, void *data)\n{\n    MachineClass *mc = MACHINE_CLASS(oc);\n    ARMExampleMachineClass *smc = ARM_EXAMPLE_MACHINE_CLASS(oc);\n    smc->board_rev = 0x920092;\n    arm_example_machine_class_common_init(mc, smc->board_rev);\n};<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li style=\"font-size: 25px; font-weight: 300; font-family: Montserrat, Montseraat; line-height: 1em; letter-spacing: normal; text-transform: none; outline-style: initial; outline-width: 0px; color: var( --e-global-color-nvprimaryaccent );\" data-elementor-setting-key=\"title\" data-pen-placeholder=\"Type Here...\">FUNKTION arm_example_machine_class_common_init<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_machine_class_common_init (MachineClass *mc, uint32_t board_rev) {\n    mc->desc = \"ARM EXAMPLE MACHINE (64-bit)\";\n    mc->init = arm_example_machine_init;\n    mc->default_ram_size = board_ram_size(board_rev);\n    mc->default_ram_id = \"ram\";\n};<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li style=\"font-size: 25px; font-weight: 300; font-family: Montserrat, Montseraat; line-height: 1em; letter-spacing: normal; text-transform: none; outline-style: initial; outline-width: 0px; color: var( --e-global-color-nvprimaryaccent );\" data-elementor-setting-key=\"title\" data-pen-placeholder=\"Type Here...\">FUNKTION arm_example_machine_init<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_machine_init(MachineState *machine) {\n    ARMExampleMachineClass *mc = ARM_EXAMPLE_MACHINE_GET_CLASS(machine);\n    ARMExampleMachineState *s = ARM_EXAMPLE_MACHINE(machine);\n    uint32_t board_rev = mc->board_rev;\n    uint32_t vcram_size;\n    uint64_t ram_size = board_ram_size(board_rev);\n    if (machine->ram_size != ram_size) {\n            char *size_str = size_to_str(ram_size);\n            error_report(\"Invalid RAM size, should be %s\", size_str);\n            g_free(size_str);\n            exit(1);\n        }\n    memory_region_add_subregion_overlap(get_system_memory(), 0,\n                                             machine->ram, 0);\n    \/* Setup the SoC *\/\n    object_initialize_child(OBJECT(machine), \"soc\", &s->soc, \"arm-example-soc\");\n    object_property_add_const_link(OBJECT(&s->soc), \"ram\", OBJECT(machine->ram));\n    object_property_set_int(OBJECT(&s->soc), \"board-rev\", board_rev, &error_abort);\n    qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);\n    vcram_size = object_property_get_uint(OBJECT(&s->soc), \"vcram-size\",\n                                          &error_abort);\n    setup_boot(machine, 0,\n               machine->ram_size - vcram_size);\n}<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li style=\"font-size: 25px; font-weight: 300; font-family: Montserrat, Montseraat; line-height: 1em; letter-spacing: normal; text-transform: none; outline-style: initial; outline-width: 0px; color: var( --e-global-color-nvprimaryaccent );\" data-elementor-setting-key=\"title\" data-pen-placeholder=\"Type Here...\">FUNKTION setup_boot<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void setup_boot(MachineState *machine, int processor_id, \n                        size_t ram_size) \n{\n    ARMExampleMachineState *s = ARM_EXAMPLE_MACHINE(machine);\n    s->bdinfo.board_id = 0; \/\/ TODO: Change this, if required\n    s->bdinfo.ram_size = ram_size;\n    if (machine->firmware) {    \n        int r = load_image_targphys(machine->firmware, FIRMWARE_ADDR, ram_size - FIRMWARE_ADDR);\n        if (r < 0) {\n            error_report(\"Failed to load firmware from %s\", machine->firmware);\n            exit(1);\n        }\n        s->bdinfo.entry = FIRMWARE_ADDR;\n        s->bdinfo.firmware_loaded = true;\n    }\n    arm_load_kernel(&s->soc.cpu[0].core, machine, &s->bdinfo);\n}<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li style=\"font-size: 25px; font-weight: 300; font-family: Montserrat, Montseraat; line-height: 1em; letter-spacing: normal; text-transform: none; outline-style: initial; outline-width: 0px; color: var( --e-global-color-nvprimaryaccent );\" data-elementor-setting-key=\"title\" data-pen-placeholder=\"Type Here...\">FUNKTION board_ram_size&nbsp; &nbsp;<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static uint64_t board_ram_size(uint32_t board_rev)\n{\n    assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); \/* Only new style *\/\n    return 256 * MiB << FIELD_EX32(board_rev, REV_CODE, MEMORY_SIZE);\n}<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li>\n<h6>KONSTANTEN<\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>#define BOARDSETUP_ADDR (ARM_EXAMPLE_RAM_START_ADDR + 0x20)\n#define FIRMWARE_ADDR 0x8000 \/\/ TODO: Change this if needed\n#define NAME_SIZE 20\nFIELD(REV_CODE, REVISION,           0, 4);\nFIELD(REV_CODE, TYPE,               4, 8);\nFIELD(REV_CODE, PROCESSOR,         12, 4);\nFIELD(REV_CODE, MANUFACTURER,      16, 4);\nFIELD(REV_CODE, MEMORY_SIZE,       20, 3);\nFIELD(REV_CODE, STYLE,             23, 1);\nstruct ARMExampleMachineState {\n    \/*< private >*\/\n    MachineState parent_obj;\n    \/*< public >*\/\n    ARMExample_SoCState soc;\n    struct arm_boot_info bdinfo;\n    \/\/ MemoryRegion ram;\n};\ntypedef struct ARMExampleMachineState ARMExampleMachineState;\nstruct ARMExampleMachineClass {\n    \/*< private >*\/\n    MachineClass parent_obj;\n    \/*< public >*\/\n    uint32_t board_rev;\n    \/\/ MemoryRegion ram;\n};\ntypedef struct ARMExampleMachineClass ARMExampleMachineClass;\n#define TYPE_ARM_EXAMPLE_MACHINE       MACHINE_TYPE_NAME(\"arm-example-common\")\nDECLARE_OBJ_CHECKERS(ARMExampleMachineState, ARMExampleMachineClass,\n                     ARM_EXAMPLE_MACHINE, TYPE_ARM_EXAMPLE_MACHINE)<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li>\n<h6>HEADER-DATEIEN<\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>#include \"qemu\/osdep.h\"\n#include \"qapi\/error.h\"\n#include \"hw\/arm\/arm-example.h\"\n#include \"qemu\/cutils.h\"\n#include \"qemu\/units.h\"\n#include \"hw\/registerfields.h\"\n#include \"qemu\/error-report.h\"\n#include \"hw\/arm\/boot.h\"\n#include \"hw\/boards.h\"\n#include \"qemu\/module.h\"\n#include \"qom\/object.h\"\n#include \"hw\/loader.h\"<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<p data-renderer-start-pos=\"8063\">Andere entsprechende Dateien sind folgende:<\/p>\n<ul>\n<li>\n<p data-renderer-start-pos=\"14325\"><em data-renderer-mark=\"true\">arm_example.h<\/em><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"14325\"><em data-renderer-mark=\"true\">arm_example_soc.h<\/em><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"14325\"><em data-renderer-mark=\"true\">arm_example_soc.c<\/em><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"14384\"><em data-renderer-mark=\"true\">arm_example_peripherals.h<\/em><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"14413\"><em data-renderer-mark=\"true\">arm_example_peripherals.c<\/em><\/p>\n<\/li>\n<\/ul>\n<ul>\n<li>MODIFY arm_example.h<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"14464\" class=\"translation-block\">Es ist erforderlich, eine <strong>enum<\/strong> zu implementieren, das die Anzahl der CPUs, Ger\u00e4te, Zeitgeber und anderer maschinenspezifischer Ger\u00e4te enth\u00e4lt. Wir k\u00f6nnen es  <em>ARMExampleConfiguration<\/em> nennen.<\/p>\n<p data-renderer-start-pos=\"14638\" class=\"translation-block\">Es besteht auch Bedarf an einer <strong>enum<\/strong>, die die gesamte Speicherkarte des zu implementierenden Ger\u00e4ts enth\u00e4lt. Es wird empfohlen, die gesamte Memory Map zu implementieren, die im Referenzhandbuch der zu implementierenden Maschine oder Entwicklungsplatine angegeben ist. Wir k\u00f6nnen sie  <em>ARMExampleMemoryMap<\/em> nennen.<\/p>\n<p data-renderer-start-pos=\"14930\" class=\"translation-block\">Die letzte zu implementierende <strong>enum<\/strong> kann die IRQs darstellen. Wie bereits erw\u00e4hnt, k\u00f6nnen die IRQs im Referenzhandbuch des jeweiligen Ger\u00e4ts nachgelesen werden. Wir k\u00f6nnen es <em>ARMExampleIRQs<\/em> nennen.<\/p>\n<ul>\n<li>MODIFY arm_example_soc.h<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"15148\">Diese Header-Datei enth\u00e4lt die Header-Dateien der Peripherieger\u00e4te sowie der Steuerteile. Die Konstanten f\u00fcr den Namen der Maschine werden deklariert, und eine Struktur stellt den Zustand von SoC dar.<\/p>\n<p data-renderer-start-pos=\"15329\">Sie k\u00f6nnen die oben erw\u00e4hnte Struktur im nachstehenden Codeschnipsel sehen:<\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>struct ARMExample_SoCState {\n    \/*< private >*\/\n    DeviceState parent_obj;\n    \/*< public >*\/\n    uint32_t enabled_cpus;\n    struct {\n        ARMCPU core;\n    } cpu[ARM_EXAMPLE_SOC_NCPUS];\n    BCM2835PeripheralState peripherals; \/\/ TODO: Change this implementation later\n    BCM2836ControlState control;        \/\/ TODO: Change this implementation later\n};<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li>MODIFY arm_example_soc.c<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"15781\">Diese Quelldatei konzentriert sich auf das Hinzuf\u00fcgen des SoC-Ger\u00e4ts zum QEMU-Ger\u00e4tebaum.<\/p>\n<p data-renderer-start-pos=\"15857\" class=\"translation-block\">Wenn es einem \u00e4hnlichen Pfad wie  <em>arm_example.c<\/em> folgt und Typen, eine Typenstruktur, Initialisierungs- und Implementierungsfunktionen definiert sowie die Deklaration von Konstanten.  Wie in dem anderen Beispiel f\u00fcr die Quelldatei wird der Durchgang von unten nach oben erfolgen.<\/p>\n<p data-renderer-start-pos=\"16103\"><em data-renderer-mark=\"true\">DEFINE_TYPES macro:<\/em><\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>DEFINE_TYPES(arm_example_types)<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"15781\">\n<h6><em data-renderer-mark=\"true\">Constant arm_example_types:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static const TypeInfo arm_example_types[] = {\n     {\n        .name           = TYPE_ARM_EXAMPLE_SOC,\n        .parent         = TYPE_DEVICE,\n        .instance_size  = sizeof(ARMExample_SoCState),\n        .instance_init  = s32g_init,\n        .class_size     = sizeof(ARMExample_SOCClass),\n        .class_init     = s32g_class_init,\n        .abstract       = false,\n    }\n};<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"15781\">\n<h6><em data-renderer-mark=\"true\">Funktion arm_example_class_init:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_class_init(ObjectClass *oc, void *data)\n{\n    DeviceClass *dc = DEVICE_CLASS(oc);\n    ARMExample_SOCClass *sc = ARM_EXAMPLE_SOC_CLASS(oc);\n    \/\/ dc->user_creatable = false; \/\/ TODO: Eliminate this one, if needed\n    sc->cpu_type = ARM_CPU_TYPE_NAME(\"cortex-a53\");\n    sc->core_count = ARM_EXAMPLE_NCPUS;\n    sc->peri_base = ARM_EXAMPLE_PERIPH_GR_0_ADDR; \/\/ peripheral base address\n    sc->clusterid = 0xf; \/\/ No idea from where is this one.\n    dc->realize = arm_example_soc_realize;\n}<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"15781\">\n<h6><em data-renderer-mark=\"true\">Funktion arm_example_soc_realize:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void s32g_soc_realize(DeviceState *dev, Error **errp)\n{\n    ARMExample_SoCState *s = ARM_EXAMPLE_SOC(dev);\n    if (!arm_example_soc_common_realize(dev, errp)) {\n        return;\n    }\n    if (!qdev_realize(DEVICE(&s->cpu[0].core), NULL, errp)) {\n        return;\n    }\n    \/* Connect irq\/fiq outputs from the interrupt controller. *\/\n    sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,\n            qdev_get_gpio_in(DEVICE(&s->cpu[0].core), ARM_CPU_IRQ));\n    sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,\n            qdev_get_gpio_in(DEVICE(&s->cpu[0].core), ARM_CPU_FIQ));\n}<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"15781\">\n<h6><em data-renderer-mark=\"true\">Funktion arm_example_soc_common_realize:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static bool arm_example_soc_common_realize(DeviceState *dev, Error **errp)\n{\n    ARMExample_SoCState *s = ARM_EXAMPLE_SOC(dev);\n    \/\/ ARMExample_SOCClass *sc = ARM_EXAMPLE_SOC_GET_CLASS(dev);\n    Object *obj;\n    obj = object_property_get_link(OBJECT(dev), \"ram\", &error_abort);\n    \/* START: UNCOMMENT WHEN PERIPHERALS IMPLEMENTED *\/\n    object_property_add_const_link(OBJECT(&s->peripherals), \"ram\", obj);\n    if (!sysbus_realize(SYS_BUS_DEVICE(&s->peripherals), errp)) {\n        return false;\n    }\n    \/\/ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,\n                            \/\/ sc->peri_base, 1);\n    \/* END: UNCOMMENT WHEN PERIPHERALS IMPLEMENTED *\/                            \n    return true;                      \n}  <\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"15781\">\n<h6><em data-renderer-mark=\"true\">Funktion arm_example_init:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_init(Object *obj)\n{\n    ARMExample_SoCState *s = ARM_EXAMPLE_SOC(obj);\n    ARMExample_SOCClass *sc = ARM_EXAMPLE_SOC_GET_CLASS(obj);\n    int n;\n    for (n = 0; n < sc->core_count; n++)\n    {\n        object_initialize_child(obj, \"cpu[*]\", &s->cpu[n].core, sc->cpu_type);\n    }\n    if (sc->core_count > 1) {\n        qdev_property_add_static(DEVICE(obj), &arm_example_soc_enabled_cores_property);\n        qdev_prop_set_uint32(DEVICE(obj), \"enabled-cpus\", sc->core_count);\n    }\n    if (sc->ctrl_base) {\n        object_initialize_child(obj, \"control\", &s->control,\n                                TYPE_BCM2836_CONTROL); \/\/ TODO: Change this, if required\n    }\n    object_initialize_child(obj, \"peripherals\", &s->peripherals,\n                            TYPE_BCM2835_PERIPHERALS); \/\/ TODO: Change this, if required\n    object_property_add_alias(obj, \"board-rev\", OBJECT(&s->peripherals),\n                              \"board-rev\");\n    object_property_add_alias(obj, \"vcram-size\", OBJECT(&s->peripherals),\n                              \"vcram-size\");\n} <\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"15781\">\n<h6><em data-renderer-mark=\"true\">Konstanten:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>typedef struct ARMExample_SOCClass {\n    \/*< private >*\/\n    DeviceClass parent_class;\n    \/*< public >*\/\n    const char *name;\n    const char *cpu_type;\n    unsigned core_count;\n    hwaddr peri_base;\n    hwaddr ctrl_base;\n    int clusterid;\n} ARMExample_SOCClass;\n#define ARM_EXAMPLE_SOC_CLASS(klass) \n    OBJECT_CLASS_CHECK(ARMExample_SOCClass, (klass), TYPE_ARM_EXAMPLE_SOC)\n#define ARM_EXAMPLE_SOC_GET_CLASS(obj) \n    OBJECT_GET_CLASS(ARMExample_SOCClass, (obj), TYPE_ARM_EXAMPLE_SOC)\nstatic Property arm_example_soc_enabled_cores_property =\n    DEFINE_PROP_UINT32(\"enabled-cpus\", ARMExample_SoCState, enabled_cpus, 0);<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"15781\">\n<h6><em data-renderer-mark=\"true\">Header-Dateien:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>#include \"qemu\/osdep.h\"\n#include \"qapi\/error.h\"\n#include \"qemu\/module.h\"\n#include \"hw\/arm\/arm_example_soc.h\"\n#include \"hw\/arm\/arm_example.h\" \/\/ Maybe this one could and should be replaced\n#include \"hw\/sysbus.h\"\n#include \"hw\/qdev-properties.h\"<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li style=\"font-size: 25px; font-weight: 300; font-family: Montserrat, Montseraat; line-height: 1em; letter-spacing: normal; text-transform: none; outline-style: initial; outline-width: 0px; color: var( --e-global-color-nvprimaryaccent ); -webkit-text-stroke-color: #000000; stroke: #000000;\" data-elementor-setting-key=\"title\" data-pen-placeholder=\"Type Here...\">MODIFY arm_example_peripherals.h<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"20580\" class=\"translation-block\">In der folgenden Datei haben wir uns f\u00fcr eine vereinfachte Implementierung der Datei  <em>include\/hw\/arm\/bcm2835_peripherals.h<\/em> entschieden, vor allem wenn es um die enthaltenen Header geht  Es besteht die M\u00f6glichkeit, entweder eigene arm_example_ic.h, arm_example_systmr.h, arm_example_fb.h und arm_example_mbox.h zu implementieren oder die urspr\u00fcnglichen Header der eingangs erw\u00e4hnten Originalimplementierung zu verwenden.<\/p>\n<ul>\n<li>MODIFY arm_example.h<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"20580\"><em data-renderer-mark=\"true\" style=\"color: var( --e-global-color-secondary ); font-family: var( --e-global-typography-secondary-font-family ), Montseraat; font-weight: var( --e-global-typography-secondary-font-weight ); background-color: var(--nv-site-bg); font-size: var(--bodyfontsize); letter-spacing: var(--bodyletterspacing); text-transform: var(--bodytexttransform);\">ARMExamplePeripheralState struct:<\/em><\/p>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp> struct ARMExamplePeripheralState {\n    \/* < private > *\/\n    SysBusDevice parent_obj;\n    \/* < public > *\/\n    MemoryRegion peri_mr, peri_mr_alias, gpu_bus_mr, mbow_mr;\n    MemoryRegion ram_alias[4];\n    qemu_irq irq, fiq;\n    ARMExampleICState ic;\n    ARMExampleSystemTimerState systmr;\n    ARMExampleMboxState mboxes;\n    ARMExampleFBState fb;\n};<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\">\n<h6><em data-renderer-mark=\"true\">Konstanten:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>#define TYPE_ARM_EXAMPLE_PERIPHERALS \"arm-example-peripherals\"\nOBJECT_DECLARE_SIMPLE_TYPE(ARMExamplePeripheralState, ARM_EXAMPLE_PERIPHERALS)<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\">\n<h6><em data-renderer-mark=\"true\">Headers:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>#include \"hw\/sysbus.h\"\n#include \"exec\/memory.h\"\n#include \"qom\/object.h\"\n#include \"hw\/intc\/arm_example_ic.h\"\n#include \"hw\/timer\/arm_example_systmr.h\"\n#include \"hw\/misc\/unimp.h\"\n#include \"hw\/display\/arm_example_fb.h\"\n#include \"hw\/misc\/arm_example_mbox.h\"<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li style=\"font-size: 25px; font-weight: 300; font-family: Montserrat, Montseraat; line-height: 1em; letter-spacing: normal; text-transform: none; outline-style: initial; outline-width: 0px; color: var( --e-global-color-nvprimaryaccent );\" data-elementor-setting-key=\"title\" data-pen-placeholder=\"Type Here...\">MODIFY arm_example_peripherals.c<\/li>\n<\/ul>\n<ul>\n<li data-renderer-start-pos=\"20580\"><em data-renderer-mark=\"true\">type_init macro:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>type_init(arm_example_peripherals_register_types)<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\"><em data-renderer-mark=\"true\">Funktion arm_example_peripherals_register_types:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_peripherals_register_types(void) \n{\n    type_register_static(&arm_example_peripherals_type_info);\n}<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\"><em data-renderer-mark=\"true\">Constant arm_example_peripherals_type_info:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static const TypeInfo arm_example_peripherals_type_info = {\n    .name = TYPE_ARM_EXAMPLE_PERIPHERALS,\n    .parent = TYPE_SYS_BUS_DEVICE,\n    .instance_size = sizeof(ARMExamplePeripheralState),\n    .instance_init = arm_example_peripherals_init,\n    .class_init = arm_example_peripherals_class_init,\n};<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\"><em data-renderer-mark=\"true\">Funktion arm_example_peripherals_class_init:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_peripherals_class_init (ObjectClass *oc, void *data)\n{\n    DeviceClass *dc = DEVICE_CLASS(oc);\n    dc->realize = arm_example_peripherals_realize;\n} <\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\"><em data-renderer-mark=\"true\">Funktion arm_example_peripherals_class_init:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_peripherals_realize (DeviceState *dev, Error **errp)\n{\n    ARMExamplePeripheralState *s = ARM_EXAMPLE_PERIPHERALS(dev);\n    Object *obj;\n    MemoryRegion *ram;\n    Error *err = NULL;\n    uint64_t ram_size, vcram_size;\n    int n;\n    obj = object_property_get_link(OBJECT(dev), \"ram\", &error_abort);\n    ram = MEMORY_REGION(obj);\n    ram_size = memory_region_size(ram);\n    \/* Interrupt Controller *\/\n    if (!sysbus_realize(SYS_BUS_DEVICE(&s->ic), errp)) {\n        return;\n    }\n    \/* Sys Timer *\/\n    if (!sysbus_realize(SYS_BUS_DEVICE(&s->systmr), errp)) {\n        return;\n    }\n    \/* Framebuffer *\/\n    vcram_size = object_property_get_uint(OBJECT(s), \"vcram-size\", &err);\n    if (err) {\n        error_propagate(errp, err);\n        return;\n    }\n    if (!object_property_set_uint(OBJECT(&s->fb), \"vcram-base\",\n                                  ram_size - vcram_size, errp)) {\n        return;\n    }\n    if (!sysbus_realize(SYS_BUS_DEVICE(&s->fb), errp)) {\n        return;\n    }\n    memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_FB << MBOX_AS_CHAN_SHIFT,\n                sysbus_mmio_get_region(SYS_BUS_DEVICE(&#038;s->fb), 0));\n    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fb), 0,\n                       qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));\n} <\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\"><em data-renderer-mark=\"true\">Function arm_example_peripherals_init:<\/em><\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>static void arm_example_peripherals_init (Object *obj)\n{\n    ARMExamplePeripheralState *s = ARM_EXAMPLE_PERIPHERALS(dev);\n    \/* Memory region for peripheral devices, which we export to our parent *\/\n    memory_region_init(&s->peri_mr, obj,\"arm-example-peripherals\", 0x1000000);  \n    \/\/ TODO: Change this line above, if needed\n    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_mr);\n    \/* Interrupt Controller *\/\n    object_initialize_child(obj, \"ic\", &s->ic, TYPE_ARM_EXAMPLE_IC);\n    \/* SYS Timer *\/\n    object_initialize_child(obj, \"systimer\", &s->systmr,\n                            TYPE_ARM_EXAMPLE_SYSTIMER);\n} <\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>#include \"qemu\/osdep.h\"\n#include \"qapi\/error.h\"\n#include \"qemu\/module.h\"\n#include \"hw\/arm\/arm_example_peripherals.h\"\n#include \"hw\/arm\/arm_example.h\"\n#include \"sysemu\/sysemu.h\"<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<ul>\n<li data-renderer-start-pos=\"20580\">\n<h6><em data-renderer-mark=\"true\">Header-Dateien:<\/em><\/h6>\n<\/li>\n<\/ul>\n<pre data-line=\"\">\t\t\t\t<code readonly=\"true\">\n\t\t\t\t\t<xmp>#include \"qemu\/osdep.h\"\n#include \"qapi\/error.h\"\n#include \"qemu\/module.h\"\n#include \"hw\/arm\/arm_example_peripherals.h\"\n#include \"hw\/arm\/arm_example.h\"\n#include \"sysemu\/sysemu.h\"<\/xmp>\n\t\t\t\t<\/code>\n<\/pre>\n<h2>Auftretende Probleme<\/h2>\n<p data-renderer-start-pos=\"20580\">Wenn Sie ein erfahrener Programmierer sind, sind Sie wahrscheinlich von Zeit zu Zeit auf Inkompatibilit\u00e4ten bei den Zeilenenden gesto\u00dfen. Das Problem tritt auf, wenn Sie Code auf einem Windows-Host in Visual Studio-Code \u00e4ndern und den QEMU-Code in einem Linux-Container ausf\u00fchren m\u00f6chten. Es wird einige Fehlermeldungen \u00fcber '\/r'-Inkompatibilit\u00e4ten geben.<\/p>\n<h2>Tests und Ergebnisse<\/h2>\n<ul>\n<li id=\"Testing\" data-renderer-start-pos=\"25180\">\n<h5>Testen<\/h5>\n<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"25189\">Wir k\u00f6nnen die Tests entweder mit GDB oder mit einem Kernel durchf\u00fchren und QEMU normal ausf\u00fchren, wobei der spezifische Rechner aktiviert ist. Bei der Verwendung eines Kernel-Images ist es wichtig, das richtig kompilierte Image zu verwenden, das die Speicherzuordnung und die IRQs der implementierten Ger\u00e4te ber\u00fccksichtigt.<\/p>\n<ul>\n<li id=\"Results\" data-renderer-start-pos=\"25484\">\n<h5>Ergebnisse<\/h5>\n<\/li>\n<\/ul>\n<p data-renderer-start-pos=\"25493\">Wenn Sie die zuvor vorgestellten Schritte befolgen und die zugeh\u00f6rigen Materialien verwenden, sollte ein erfahrener Programmierer in der Lage sein, eine voll funktionsf\u00e4hige ARM-basierte Maschine in QEMU zu implementieren.<\/p>\n<h2>Schlussfolgerung<\/h2>\n<p data-renderer-start-pos=\"25705\">Auch wenn es nicht ideal ist, gibt es eine Alternative zu echter Hardware, insbesondere in Zeiten, in denen die Lieferkette f\u00fcr Chips schwierig ist oder sogar das Problem auftritt, dass das physische Ger\u00e4t nicht in der Produktion vorhanden ist.<\/p>\n<p data-renderer-start-pos=\"25952\">Zusammenfassend l\u00e4sst sich sagen, dass die Aufgabe, die vor uns liegt, einsch\u00fcchternd erscheinen mag: die Virtualisierung einer tats\u00e4chlichen Maschine zu implementieren und ihre realen Auswirkungen in einer virtuellen Umgebung zu emulieren, aber diese Abstraktion sollte den Weg f\u00fcr eine noch gr\u00f6\u00dfere Anerkennung von QEMU als wertvolles Werkzeug ebnen.<\/p>\n<p data-renderer-start-pos=\"26217\">Wenn die Idee der Hardware-Emulation popul\u00e4r genug ist, k\u00f6nnte es n\u00fctzlich sein, ein generisches Tool zu entwickeln, das die M\u00f6glichkeit bietet, zumindest die g\u00e4ngigen Teile von ARM-Maschinen auf einfachere Weise zu implementieren als durch Kodierung oder mit einer Code-als-Dokumentation-Situation wie im Fall des QEMU-Quellcodes umzugehen. Es besteht die M\u00f6glichkeit, dass sogar eine GUI-L\u00f6sung die Innovation im Embedded-Bereich noch weiter beschleunigen k\u00f6nnte.<\/p>\n<h2>Referenzen<\/h2>\n<ul data-indent-level=\"1\">\n<li>\n<p data-renderer-start-pos=\"26895\">S. Sopha, <em data-renderer-mark=\"true\">Adding a custom ARM platform to QEMU 5.2.0<\/em>, 2021. Available: <a tabindex=\"0\" role=\"button\" href=\"https:\/\/web.archive.org\/web\/20220709202327\/https:\/\/souktha.github.io\/software\/qemu-port\/\" data-testid=\"inline-card-resolved-view\">Adding a custom ARM platform to QEMU 5.2.0<\/a><\/p>\n<\/li>\n<\/ul>\n<h2>Weitere Artikel anschauen:<\/h2>","protected":false},"excerpt":{"rendered":"<p>Considering the current developments in the global market, especially having the issue of a Global Chip Shortage, there are some issues to be addressed when having to deploy software on an Embedded platform, but the platform itself is missing. The issue posed is no small undertaking, especially for companies deploying software for different platforms and&hellip;&nbsp;<a href=\"https:\/\/digitalgateamg.com\/de\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\" class=\"\" rel=\"bookmark\">Weiterlesen &raquo;<span class=\"screen-reader-text\">QEMU-Entwicklung<\/span><\/a><\/p>","protected":false},"author":12,"featured_media":10186,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[],"coauthors":[],"class_list":["post-10158","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.1 (Yoast SEO v26.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>QEMU Development - DigitalGate Custom Electronics<\/title>\n<meta name=\"description\" content=\"Read the article to find out how Global Chip Shortage affects QEMU development, what you can do about it and how to do it.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/digitalgateamg.com\/de\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"QEMU Development\" \/>\n<meta property=\"og:description\" content=\"Read the article to find out how Global Chip Shortage affects QEMU development, what you can do about it and how to do it.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/digitalgateamg.com\/de\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\" \/>\n<meta property=\"og:site_name\" content=\"DigitalGate Custom Electronics\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/DigitalGateamg\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-08-17T09:26:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-08T14:46:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1-1024x1024.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Digital Gate\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Digital Gate\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"17\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Digital Gate\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\"},\"author\":{\"name\":\"Digital Gate\",\"@id\":\"https:\/\/digitalgateamg.com\/#\/schema\/person\/27511cb01dbba51abd9b489e6adc2fce\"},\"headline\":\"QEMU Development\",\"datePublished\":\"2022-08-17T09:26:05+00:00\",\"dateModified\":\"2023-08-08T14:46:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\"},\"wordCount\":1945,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/digitalgateamg.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png\",\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\",\"url\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\",\"name\":\"QEMU Development - DigitalGate Custom Electronics\",\"isPartOf\":{\"@id\":\"https:\/\/digitalgateamg.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png\",\"datePublished\":\"2022-08-17T09:26:05+00:00\",\"dateModified\":\"2023-08-08T14:46:20+00:00\",\"description\":\"Read the article to find out how Global Chip Shortage affects QEMU development, what you can do about it and how to do it.\",\"breadcrumb\":{\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage\",\"url\":\"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png\",\"contentUrl\":\"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png\",\"width\":3676,\"height\":2451,\"caption\":\"QEMU development during Global Chip Shortage\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/digitalgateamg.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"QEMU Development\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/digitalgateamg.com\/#website\",\"url\":\"https:\/\/digitalgateamg.com\/\",\"name\":\"DigitalGate Custom Electronics\",\"description\":\"Embedded Software and Hardware Solutions\",\"publisher\":{\"@id\":\"https:\/\/digitalgateamg.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/digitalgateamg.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/digitalgateamg.com\/#organization\",\"name\":\"DigitalGate Amg S.A.\",\"url\":\"https:\/\/digitalgateamg.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/digitalgateamg.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2021\/10\/logo-firma.png\",\"contentUrl\":\"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2021\/10\/logo-firma.png\",\"width\":370,\"height\":370,\"caption\":\"DigitalGate Amg S.A.\"},\"image\":{\"@id\":\"https:\/\/digitalgateamg.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/DigitalGateamg\/\",\"https:\/\/www.linkedin.com\/company\/sc-digitalgate-amg-srl\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/digitalgateamg.com\/#\/schema\/person\/27511cb01dbba51abd9b489e6adc2fce\",\"name\":\"Digital Gate\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/digitalgateamg.com\/#\/schema\/person\/image\/cf8ad43aefc829ce3a5afa607f56c6f6\",\"url\":\"https:\/\/digitalgateamg.com\/wp-content\/litespeed\/avatar\/46f85298923a63b5939c9a06d38c2790.jpg?ver=1776247194\",\"contentUrl\":\"https:\/\/digitalgateamg.com\/wp-content\/litespeed\/avatar\/46f85298923a63b5939c9a06d38c2790.jpg?ver=1776247194\",\"caption\":\"Digital Gate\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"QEMU Development - DigitalGate Custom Electronics","description":"Read the article to find out how Global Chip Shortage affects QEMU development, what you can do about it and how to do it.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/digitalgateamg.com\/de\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/","og_locale":"de_DE","og_type":"article","og_title":"QEMU Development","og_description":"Read the article to find out how Global Chip Shortage affects QEMU development, what you can do about it and how to do it.","og_url":"https:\/\/digitalgateamg.com\/de\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/","og_site_name":"DigitalGate Custom Electronics","article_publisher":"https:\/\/www.facebook.com\/DigitalGateamg\/","article_published_time":"2022-08-17T09:26:05+00:00","article_modified_time":"2023-08-08T14:46:20+00:00","og_image":[{"width":1024,"height":1024,"url":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1-1024x1024.png","type":"image\/png"}],"author":"Digital Gate","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Digital Gate","Gesch\u00e4tzte Lesezeit":"17\u00a0Minuten","Written by":"Digital Gate"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#article","isPartOf":{"@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/"},"author":{"name":"Digital Gate","@id":"https:\/\/digitalgateamg.com\/#\/schema\/person\/27511cb01dbba51abd9b489e6adc2fce"},"headline":"QEMU Development","datePublished":"2022-08-17T09:26:05+00:00","dateModified":"2023-08-08T14:46:20+00:00","mainEntityOfPage":{"@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/"},"wordCount":1945,"commentCount":0,"publisher":{"@id":"https:\/\/digitalgateamg.com\/#organization"},"image":{"@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage"},"thumbnailUrl":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png","articleSection":["Uncategorized"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/","url":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/","name":"QEMU Development - DigitalGate Custom Electronics","isPartOf":{"@id":"https:\/\/digitalgateamg.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage"},"image":{"@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage"},"thumbnailUrl":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png","datePublished":"2022-08-17T09:26:05+00:00","dateModified":"2023-08-08T14:46:20+00:00","description":"Read the article to find out how Global Chip Shortage affects QEMU development, what you can do about it and how to do it.","breadcrumb":{"@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#primaryimage","url":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png","contentUrl":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png","width":3676,"height":2451,"caption":"QEMU development during Global Chip Shortage"},{"@type":"BreadcrumbList","@id":"https:\/\/digitalgateamg.com\/blog\/2022\/08\/17\/qemu-development-during-the-chip-shortage\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/digitalgateamg.com\/"},{"@type":"ListItem","position":2,"name":"QEMU Development"}]},{"@type":"WebSite","@id":"https:\/\/digitalgateamg.com\/#website","url":"https:\/\/digitalgateamg.com\/","name":"DigitalGate Custom Electronics","description":"Embedded Software and Hardware Solutions","publisher":{"@id":"https:\/\/digitalgateamg.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/digitalgateamg.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/digitalgateamg.com\/#organization","name":"DigitalGate Amg S.A.","url":"https:\/\/digitalgateamg.com\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/digitalgateamg.com\/#\/schema\/logo\/image\/","url":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2021\/10\/logo-firma.png","contentUrl":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2021\/10\/logo-firma.png","width":370,"height":370,"caption":"DigitalGate Amg S.A."},"image":{"@id":"https:\/\/digitalgateamg.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/DigitalGateamg\/","https:\/\/www.linkedin.com\/company\/sc-digitalgate-amg-srl\/"]},{"@type":"Person","@id":"https:\/\/digitalgateamg.com\/#\/schema\/person\/27511cb01dbba51abd9b489e6adc2fce","name":"Digital Gate","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/digitalgateamg.com\/#\/schema\/person\/image\/cf8ad43aefc829ce3a5afa607f56c6f6","url":"https:\/\/digitalgateamg.com\/wp-content\/litespeed\/avatar\/46f85298923a63b5939c9a06d38c2790.jpg?ver=1776247194","contentUrl":"https:\/\/digitalgateamg.com\/wp-content\/litespeed\/avatar\/46f85298923a63b5939c9a06d38c2790.jpg?ver=1776247194","caption":"Digital Gate"}}]}},"jetpack_featured_media_url":"https:\/\/digitalgateamg.com\/wp-content\/uploads\/2022\/08\/blog-2-1.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/posts\/10158","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/comments?post=10158"}],"version-history":[{"count":0,"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/posts\/10158\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/media\/10186"}],"wp:attachment":[{"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/media?parent=10158"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/categories?post=10158"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/tags?post=10158"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/digitalgateamg.com\/de\/wp-json\/wp\/v2\/coauthors?post=10158"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}