[OE-core] [PATCH 1/2] baremetal-helloworld: Create recipe for baremetal examples on QEMU

Alejandro Enedino Hernandez Samaniego alejandro at enedino.org
Tue Jan 28 07:19:23 UTC 2020


Hey Khem,

On Mon, Jan 27, 2020, 12:51 PM Khem Raj <raj.khem at gmail.com> wrote:

> On Mon, Jan 27, 2020 at 2:01 AM Alejandro Enedino Hernandez Samaniego
> <alejandro at enedino.org> wrote:
> >
> > Create HelloWorld examples that run on several of the QEMU architectures
> > supported by the build system.
> >
> > This recipe can be used by anyone to understand how baremetal
> applications
> > can be built using OpenEmbedded and how the wiring to set them up could
> be.
> >
> > This should also facilitate creating/extending the OE testing
> infrastructure
> > to allow baremetal applications or RTOSs to be tested in the same way
> that
> > Linux currently is.
> >
> > This can easily be extended to work on other MACHINES in the future.
> >
> > To run this example:
> >
> > # Source the oe environment as usual
> > $ source oe-init-buildenv
> >
> > # Set TCLIBC to either newlib or baremetal
> > $ echo "TCLIBC = \"newlib\"" >> ./conf/local.conf
> >
> > # Use one of the supported architectures (qemuarm64, qemuarm or
> qemuarmv5)
> > $ echo "MACHINE = \"qemuarm64\"" >> ./conf/local.conf
> >
> > # Build
> > $ bitbake baremetal-helloworld
> >
> > # Launch QEMU
> > $ runqemu
> >
> > runqemu - INFO - Running bitbake -e ...
> > runqemu - INFO - Continuing with the following parameters:
> > KERNEL: [tmp/deploy/images/qemuarm64/baremetal-helloworld-qemuarm64.bin]
> > MACHINE: [qemuarm64]
> > FSTYPE: [bin]
> > ROOTFS: [tmp/deploy/images/qemuarm64/baremetal-helloworld-qemuarm64.bin]
> > CONFFILE:
> [tmp/deploy/images/qemuarm64/baremetal-helloworld-qemuarm64.qemuboot.conf]
> >
> > Hello OpenEmbedded!
> >
> > Signed-off-by: Alejandro Enedino Hernandez Samaniego <
> alejandro at enedino.org>
> > ---
> >  .../baremetal-examples/baremetal-helloworld_git.bb | 114
> +++++++++++++++++++++
> >  1 file changed, 114 insertions(+)
> >  create mode 100644 meta/recipes-extended/baremetal-examples/
> baremetal-helloworld_git.bb
> >
> > diff --git a/meta/recipes-extended/baremetal-examples/
> baremetal-helloworld_git.bb b/meta/recipes-extended/baremetal-examples/
> baremetal-helloworld_git.bb
> > new file mode 100644
> > index 0000000..aab48b1
> > --- /dev/null
> > +++ b/meta/recipes-extended/baremetal-examples/
> baremetal-helloworld_git.bb
> > @@ -0,0 +1,114 @@
> > +SUMMARY = "Baremetal examples to work with the several QEMU
> architectures supported on OpenEmbedded"
> > +HOMEPAGE = "https://github.com/aehs29/baremetal-helloqemu"
> > +LICENSE = "CC-BY-SA-4.0"
>
> I think MIT or Apache-2.0 would be much nicer.
>

I agree but this wasn't by choice, the original code written for the
versatile architecture was licensed on CC-BY-SA, which AFAIC wouldn't be
compatible with those, this is the best I could come up with since this
way, something that uses this could use GPLv3 if there's a better way let
me know


> > +LIC_FILES_CHKSUM = "file://LICENSE;md5=4084714af41157e38872e798eb3fe1b1"
> > +
> > +SRCREV = "fe81742f1159725408dd7305e40e7bd4dfd1e264"
> > +
> > +SRC_URI = "git://
> github.com/aehs29/baremetal-helloqemu.git;protocol=https "
> > +
> > +S = "${WORKDIR}/git"
> > +B = "${WORKDIR}/build"
> > +
> > +# These examples are not meant to be built when using either musl or
> glibc
> > +COMPATIBLE_HOST_libc-musl_class-target = "null"
> > +COMPATIBLE_HOST_libc-glibc_class-target = "null"
>
> Perhaps check for TARGET_OS instead of LIBC
>

We had decided this to avoid bitbake world errors, if you think TARGET_OS
is better I'm okay with that.



> > +# This will be translated automatically to the architecture and
> > +# machine that QEMU uses on OE, e.g. -machine virt -cpu cortex-a57
> > +# but the examples can also be run on other architectures/machines
> > +# such as vexpress-a15 by overriding the setting on the machine.conf
> > +COMPATIBLE_MACHINE = "qemuarmv5|qemuarm|qemuarm64"
> > +
> > +BAREMETAL_QEMUARCH ?= ""
> > +BAREMETAL_QEMUARCH_qemuarmv5 = "versatile"
> > +BAREMETAL_QEMUARCH_qemuarm = "arm"
> > +BAREMETAL_QEMUARCH_qemuarm64 = "aarch64"
> > +
>
> this setting should be abstracted into something like  baremetal.bbclass
>
>
> > +
> > +EXTRA_OEMAKE_append = " QEMUARCH=${BAREMETAL_QEMUARCH}"
> > +
> > +do_configure(){
> > +    # Avoid building on the source directory
> > +    cp ${S}/* ${B}
> > +}
>
> copying sources to B why is that needed ?
>
>
> > +
> > +do_install(){
> > +    install -d ${D}/${datadir}
> > +    install -m 755 ${B}/hello_baremetal_${BAREMETAL_QEMUARCH}.bin
> ${D}/${datadir}/hello_baremetal_${MACHINE}.bin
> > +    install -m 755 ${B}/hello_baremetal_${BAREMETAL_QEMUARCH}.elf
> ${D}/${datadir}/hello_baremetal_${MACHINE}.elf
> > +}
> > +
> > +# Make sure there are no race conditions when
> > +# assembling compiling and linking steps
> > +PARALLEL_MAKE = ""
> > +
>
> hmmm bad example to start of.
>
> > +# Borrowed from meta-freertos
> > +inherit rootfs-postcommands
> > +inherit deploy
> > +do_deploy[dirs] = "${DEPLOYDIR} ${DEPLOY_DIR_IMAGE}"
> > +do_rootfs[dirs] = "${DEPLOYDIR} ${DEPLOY_DIR_IMAGE}"
> > +DEPLOYDIR = "${IMGDEPLOYDIR}"
> > +IMAGE_LINK_NAME ?= "baremetal-helloworld-image-${MACHINE}"
> > +IMAGE_NAME_SUFFIX ?= ""
> > +
> > +do_deploy(){
> > +    install ${D}/${datadir}/hello_baremetal_${MACHINE}.bin
> ${DEPLOYDIR}/${IMAGE_LINK_NAME}.bin
> > +    install ${D}/${datadir}/hello_baremetal_${MACHINE}.elf
> ${DEPLOYDIR}/${IMAGE_LINK_NAME}.elf
> > +}
> > +
> > +do_image(){
> > +    :
> > +}
> > +
> > +FILES_${PN} += " \
> > +    ${datadir}/hello_baremetal_${MACHINE}.bin \
> > +    ${datadir}/hello_baremetal_${MACHINE}.elf \
> > +"
> > +
> > +python do_rootfs(){
> > +    from oe.utils import execute_pre_post_process
> > +    from pathlib import Path
> > +
> > +    # Write empty manifest testdate file
> > +    deploy_dir = d.getVar('DEPLOYDIR')
> > +    link_name = d.getVar('IMAGE_LINK_NAME')
> > +    manifest_name = d.getVar('IMAGE_MANIFEST')
> > +
> > +    Path(manifest_name).touch()
> > +    if os.path.exists(manifest_name) and link_name:
> > +        manifest_link = deploy_dir + "/" + link_name + ".manifest"
> > +        if os.path.lexists(manifest_link):
> > +            os.remove(manifest_link)
> > +        os.symlink(os.path.basename(manifest_name), manifest_link)
> > +    execute_pre_post_process(d, d.getVar('ROOTFS_POSTPROCESS_COMMAND'))
> > +}
> > +
>
>
> these all should be abstracted
>

Ok, of all the above, my intention is to create a class that abstracts
this, it actually already is a class on meta-freertos, even the code below,
but I have WIP on testimage, oe-selftest, FreeRTOS and for the next couple
of days I'll have a lot on my plate and I'm trying to split the work in
chunks, so it doesn't break other WIP and at the same time I get things
done, I agree its not ideal, but its less confusing for me to have a single
class for now (the meta-freertos one), along with these recipes already
being built for the test cases and once I can upstream the work, all this
will be abstracted in a class in oe-core, I can file a bug in bugzilla and
take it to keep track of this if that helps.

v2 fixes:
Copying sources
Paralell make


> > +# QEMU generic FreeRTOS parameters
> > +QB_DEFAULT_KERNEL = "${IMAGE_LINK_NAME}.bin"
> > +QB_MEM = "-m 256"
> > +QB_OPT_APPEND = "-nographic"
> > +QB_DEFAULT_FSTYPE = "bin"
> > +QB_DTB = ""
> > +
>
> this setting perhaps should be in machine conf ?
>

Those are already on the machine.conf, these are overriding the Linux
configurations so QEMU loads the baremetal application correctly , e.g.
FSTYPE=bin


> > +# This next part is necessary to trick the build system into thinking
> > +# its building an image recipe so it generates the qemuboot.conf
> > +addtask do_deploy after do_write_qemuboot_conf before do_build
> > +addtask do_rootfs before do_deploy after do_install
> > +addtask do_image after do_rootfs before do_build
> > +inherit qemuboot
> > +
> > +# Based on image.bbclass to make sure we build qemu
> > +python(){
> > +    # do_addto_recipe_sysroot doesnt exist for all recipes, but we need
> it to have
> > +    # /usr/bin on recipe-sysroot (qemu) populated
> > +    def extraimage_getdepends(task):
> > +        deps = ""
> > +        for dep in (d.getVar('EXTRA_IMAGEDEPENDS') or "").split():
> > +        # Make sure we only add it for qemu
> > +            if 'qemu' in dep:
> > +                deps += " %s:%s" % (dep, task)
> > +        return deps
> > +    d.appendVarFlag('do_image', 'depends',
> extraimage_getdepends('do_addto_recipe_sysroot'))
> > +    d.appendVarFlag('do_image', 'depends',
> extraimage_getdepends('do_populate_sysroot'))
> > +}
> > --
> > 2.7.4
> >
> > --
> > _______________________________________________
> > Openembedded-core mailing list
> > Openembedded-core at lists.openembedded.org
> > http://lists.openembedded.org/mailman/listinfo/openembedded-core
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openembedded.org/pipermail/openembedded-core/attachments/20200127/16a16ea7/attachment-0001.html>


More information about the Openembedded-core mailing list