ev3dev / brickstrap

Tool for bootstrapping Debian and creating bootable image files for embedded systems
MIT License
35 stars 26 forks source link

Enable other architectures than arm, native builds #21

Closed cmacq2 closed 8 years ago

cmacq2 commented 8 years ago

Add utility functions to prepare brickstrap for:

The code also takes advantage of the work done on paths (BR_ARCH variable is used).

dlech commented 8 years ago

You are going to have to explain to me why we need a separate $BR_ARCH from $ARCH.

Also, why do we need "native" builds? The point of brickstrap is to bootstrap a foreign architecture. It seems like if you wanted something native with similar functionality, you should use LXC instead.

I like having a function that translates debian arch to qemu arch and plugs it in. I don't think we need so much guessing though. If $QEMU_STATIC already exists, use it, if not, assign a default value based on the debian arch ($ARCH). Then you can add $QEMU_STATIC to your config file or pass it from the command line if you want to use a custom qemu.

cmacq2 commented 8 years ago

The distinction between the two is that BR_ARCH (which is properly namespaced) would be set by brickstrap when it parses its commandline options, but ARCH is arbitrary (it could come from env, or it could come from config).

A bit of background: BR_ARCH is originally a remnant of the work done on path layers from before the component-based plan. In that scenario you'd have something like an -A option to pass an architecture variable to be used as BR_ARCH for path lookup, and here's the interesting bit: potentially doubling as an indicator of what ARCH should be.

Still even without the path layers, it could be quite useful to set BR_ARCH and/or BR_SUITE via commandline options -- that way you do not need to maintain separate config components if you are fairly confident about a single generic multistrap.conf file.

In any case BR_ARCH can be taken out if you prefer that.

dlech commented 8 years ago

Yes, let's leave out BR_ARCH until we are really sure that we need it.

cmacq2 commented 8 years ago

Also, why do we need "native" builds? The point of brickstrap is to bootstrap a foreign architecture.

That rather depends on your view of what 'foreign' entails, or whether you accept the premise that brickstrap can only work sanely for 'foreign' architectures.

There are a few observations to be made here:

  1. You can have other embedded devices which happen to run the same arch as your own development environment. Think using the R.Pi desktop to generate a custom R.Pi image. Or using the R.Pi as a dev tool for working with other embedded ARM boards. Or developing images for embedded Intel stuff on your Intel laptop...
  2. Whenever you do run into this case it would be a bit silly to use QEMU as it's entirely superfluous in this case.
  3. It could very well be useful to generate bootable images matching your build host architecture, say a VMDK disk image for booting as a VM.

Or to put it a bit glibly: bash, Perl and Debian in general run perfectly fine on all sorts of architectures, so why should brickstrap get in the way by insisting on more QEMU than strictly required? :)

dlech commented 8 years ago

OK, I'm with you now on the "native" business. Could we use update-binfmt --find to do the magic of finding the correct qemu? I just did a quick test and update-binfmts --find $native_binary returned and empty string (newline) and update-binfmts --find $armel_binary returned /usr/bin/qemu-arm-static.

cmacq2 commented 8 years ago

Could we use update-binfmt --find to do the magic of finding the correct qemu?

This requires we know what binary to call it on. I suppose we could assume that $ROOTDIR/usr/bin/dpkg is pretty much a given and so we could use that, after multistrap.

It should be a fallback, however, if the user want to supply their own custom QEMU they should be able to (think dev builds of QEMU that they've not registered with the system binfmt configuration).

Also with this method validation of QEMU cannot be fully completed until after multistrap (that's when we'll know for certain whether or not QEMU is required and therefore that's when we can check it's available).


As an aside our support for using QEMU is basically this: cp ${QEMU_STATIC} ${ROOTDIR}/usr/bin/, which is a bit awkward, it would be better if we could avoid rooting around in what is ultimately going to be /usr/bin of the target system...

dlech commented 8 years ago

It should be a fallback, however, if the user want to supply their own custom QEMU they should be able to

Of course.

...bit awkward...

How else would you use qemu? From what I have read, this is "the way" that you do it for a chroot. There is already other essential "rooting around" in the rootfs too, for example /usr/sbin/policy-rc.d. These things are necessary for the chroot to work properly and this is why tar-exclude exists - so they aren't included in the actual image file.

cmacq2 commented 8 years ago

How else would you use qemu?

I've not extensively researched this extensively but I think it would be nicer if QEMU could be confined to, say, /brickstrap/qemu/ and PATH/LD_LIBRARY_PATH could be used to make sure QEMU is found. That way you wouldn't have the rare-but-possible case that someone installs a QEMU as part of the multistrap which you then proceed to overwrite with a host QEMU and do not package up as part of the tarball. It's an edge case resulting from the fact that some of the QEMU interpreters cover multiple architectures in the same binary...

Also, this:

/usr/sbin/policy-rc.d

May not be strictly required. At any rate the Debian install I type this on doesn't have a /usr/sbin/policy-rc.d ...

dlech commented 8 years ago

Well, I'm going to say "if it ain't broke, don't fix it". qemu is working the way it is, so let's not change it unless we absolutely have to.

And FWIW, /usr/sbin/policy-rc.d is required only if you are using sysv init. There's plenty of other mucking around, like ssh host files, flash-kernel stuff if you are using flash-kernel, etc.

cmacq2 commented 8 years ago

I agree: there's certainly not a pressing need to go fix this now. In any case this PR is not the place to explore this. More for a follow up thing if (a) it ever becomes a real issue, and (b) it can be made to work reliably in another way.


In the spirit of getting back to the issues covered by this PR: do you still want me to remove the shebang?

dlech commented 8 years ago

I'm ok with leaving it if you find it useful.

cmacq2 commented 8 years ago

I've prepared a new version based on your feedback.

To clarify a point on the guessing: BR_QEMU is meant as a commandline argument -Q. I think it should support 'shorthand' references to QEMU via architecture names, hence 'guessing'. This is in contrast to QEMU_STATIC which should either be a valid binary or not used at all.

Support for 'guessing' QEMU needs to be there as a last resort for robust support for native builds (without binfmt tools or QEMU) and in case binfmt tools fail us.

dlech commented 8 years ago

This is looking pretty good. Are you going to integrate this with the existing brickstrap.sh here or do that as a separate pull request?

Also, with the automatic guessing and such, I'm thinking we need to record which qemu - if any in the generated multistrap.conf (or another new file generated at the same time). If you want to select a custom qemu, then it only takes effect in the create-conf step. After that, it is fixed at whatever that value was. There can be multiple invocations of brickstrap on the same rootfs, so this info needs to be stored somewhere other than in an environment variable and we can't rely on the user or the automatic guessing to provide the same value each time. Have you given this any thought?

cmacq2 commented 8 years ago

This is looking pretty good. Are you going to integrate this with the existing brickstrap.sh here or do that as a separate pull request?

I am starting to think it would be easiest to do this in a separate PR once the component based path mechanism has landed and has been integrated properly, first.

I've been working on integration of the component based path mechanism inside brickstrap.sh itself, and it touches a lot of brickstrap.sh but doesn't really affect/force updates in the example projects (board definitions); by contrast the integration of this PR doesn't affect brickstrap.sh itself all that much but it probably should be accompanied by an update to the board definitions (to take advantage of the namespaced functions for chroot features instead of variables).

Doing things that way you can first fold the board definitions into a single tree, and then later retouch the unified tree to update it to match with this PR.

cmacq2 commented 8 years ago

Have you given this any thought?

I hadn't, not really. I suppose you are right. Recording this in multistrap.conf is probably not a good idea because it's not really the right place to look for it: multistrap itself doesn't care or know about QEMU, and we never actually read/parse the generated multistrap.conf (it's just re-generated each time create-conf is executed). That means it would be one-way information that's stored in an obscure location and not all that easily retrieved from within brickstrap on subsequent invocations.

What we can do is generate a shell snippet in a file underneath $ROOTDIR or something like this, say $ROOTDIR/brickstrap/config_history.cfg:

echo "BRP_PREVIOUS_QEMU='$QEMU_STATIC'" >> "$ROOTDIR/brickstrap/config_history.cfg"

We'd do this during the invocation of brp_setup_qemu_in_rootfs().

Additionally we attempt to source this file after we source config, and we overwrite variables like this:

. "$ROOTDIR/brickstrap/config_history.cfg" && rm -f "$ROOTDIR/brickstrap/config_history.cfg"
if [ -z "$QEMU_STATIC" -a -z "$BR_QEMU" -a -n "$BRP_PREVIOUS_QEMU" ]; then
   QEMU_STATIC="$BRP_PREVIOUS_QEMU"
fi 

... And so we re-inject the previous environment/config into the current one, provided that the current environment doesn't already specify a (new) setting for QEMU.

dlech commented 8 years ago

This sounds like a good idea. As we progress, I have a feeling that there are going to be some more variables that need do be saved between invocations.

I think it would be nice if during the initial setup, you can run brickstrap create-rootfs (or brickstrap all) once with full arguments and then after that, any invocation of brickstrap shell or brickstrap create-image just need the -d option to specify the root file system. All other options are "remembered" because they are part of the rootfs.

If you don't have anything else to add here, go ahead an squash your commits and I will merge and we can move on to the next PR.

cmacq2 commented 8 years ago

Rebased to squash the two commits into one and provide a fresh, unified commit message.

dlech commented 8 years ago

Thanks!