oxidecomputer / hubris

A lightweight, memory-protected, message-passing kernel for deeply embedded systems.
Mozilla Public License 2.0
2.96k stars 169 forks source link

a beginner-friendly “getting started” tutorial #282

Open jfhbrook-at-work opened 2 years ago

jfhbrook-at-work commented 2 years ago

I'm a hobbyist tinkerer who likes to play with microcontrollers and small computers like arduinos, raspis and feathers. I began reading the documentation for hubris hoping to get a taste for what running a rust-based microkernel on something like the new rp2040 feather would feel like and I'll admit that I'm overwhelmed by all the low level systems details and lack of hand-holding! I'm sure the choice to eschew virtual addressing - for instance - was an important one architecturally, but I'm at the stage where I want to flash my feather and blink an LED and I'm not clear on where to go for that.

I think what I would like to see is a concrete tutorial based on something you could buy from adafruit or sparkfun and something simple like blinking an LED, detecting a button press or buzzing a peizo. I would be tempted to copy something else structurally, or at least drawing inspo from the arduino and circuitpython projects.

I get if this is a low priority - oxide's goals don't seem to hinge on the hobbyist market - and I certainly don't want to be demanding, but I think it would make it a lot more approachable for me specifically ;) and hopefully I'm not the only one.

Thanks! Hope this is helpful!

jfhbrook-at-work commented 2 years ago

@jfhbrook (I was logged into my work account oops)

cbiffle commented 2 years ago

While we don't currently have a tutorial beyond the getting-started section of the README, and we don't support the RP2040 (though I'd love to port it -- assuming they implemented the Cortex-M0 with an MPU, of course!), we do maintain some demo apps that will at least blink an LED on something you can buy off the shelf. The app/demo-stm32f4-discovery works on stm32f407 and stm32f411-based discovery boards, which are pretty cheap on Digikey. Thanks to @luqmana it should also work on the stm32f3 discovery board, which seems to be popular in the Rust embedded community. The app/demo-stm32h7-nucleo image works on the STM32H743/53 Nucleo board, which has recently become hard to get in the States but sometimes crops up.

Down the road I'd love to have a good beginner tutorial.

In the meantime, if you haven't taken a look at RTIC, it's pretty neat and definitely does have a tutorial.

jfhbrook-at-work commented 2 years ago

I was told by someone on twitter that hubris supports microcontrollers "such as the rp2040" so it likely meets those hardware requirements - for what it's worth.

mx-shift commented 2 years ago

That was almost certainly me. I was referencing rp2040 in contrast to Raspberry Pi 4. RP2040 isn't currently supported but could be with modest effort while Raspberry Pi 4 is a Cortex-A device with an MMU which is a very different beast that Hubris isn't designed for.

jfhbrook commented 2 years ago

Yup, we're thinking about the same conversation. I figured it was something along these lines but thanks for the clarification!

I mostly bring up the rp2040 because I coincidentally happen to have an rp2040 feather. I don't think I have anything stm-related and I'm unlikely to buy new toys just to test out hubris, but if you end up trying to support the rp2040 in the future I'm happy to test it out for y'all, lmk. Otherwise I'll try to take a look at the demos if only to satisfy my curiosity. Thanks!

Dygear commented 2 years ago

Hello everyone, I was pointed here after having a conversation on Twitter about porting Hubris to the RP2040 devices and indeed the Adafruit Feather RP2040 in particular. To answer cliffle's question (I won't at anyone on the Oxide team, as I'm sure they have better things to do right now with their hardware bring up and getting their systems to market in the next 3 - 6 months.), Yes the RP2040 does indeed include an MPU Source: RP2040 Datasheet, Page 77 - 2.4.6. MPU.

There has also been some recent movement, on Christmas day in fact, when @thejpster released the Rust rp2040-hal. Meaning that we don't actually need to write our own from scratch. We can also add Feather Wings (Think: HATS or Hardware Attached on Top) to the Feather that would for example allow for PoE and Ethernet (From @xorbit). Along with the Adafruit Infineon Trust M Breakout Board - STEMMA QT / Qwiic we should be able to get some sense of trust from the device as well. Lastly a connection to the computer via serial, in my case that computer would be a Raspberry Pi 4 to keep it all in the family.

My goal for the project would be to build the entire system in Rust. I believe this would require some porting of the PoE Father Wing code, as well as a driver for the Infineon breakout board. This would also mean that the communication protocols would need a rust driver as well. I have not done a deep drive into all of these code bases, so I could be way off here. I'm also not sure that we can use the Infineon board to verify the firmware running on the Feather.

The end results would be a hopefully useful product, what would effectively be a portable BMC. A device that you could SSH into, and get a console into the target system using serial port connection between the Feather and the target system that is then exposed back to the client over the SSH connection. HPE calls their version of this iLO. Given that this is not in any way integrated into the system, perhaps rLO for Remote / Raspberry / Rust Lights Out. Extra points if we can figure out how to make it power the Pi and control it's power state. I mean it could be done with Digital Loggers' 4 Outlet Power Relay but that's probably cheating. There is maybe enough power on the PoE rail from the Feather Wing to power a Raspberry Pi Z2W, but that's probably abusive.

Risk factors, I'm fairly new to Rust Programming and even more so Embedded Rust so I'm not the best person to lead this type of project, but I'm happy to document any progress I do make. The other problem is time. I am currently working on a very large product where I am the only programmer. Given all of that, it should be helpful for people who want to understand how to use Hubris on RP2040 devices and at the end of it all they might just get something that is useful as well.

thejpster commented 2 years ago

The problem with the 2040 for these purposes is that it has an unencrypted external flash. This means it's trivial to get the chip to load untrusted code at boot up, and your only 'fix' is probably to cover the SoC and the flash in a can and a lot of potting (effectively putting them into a single package). An external TPM won't help given you can so easily modify the flash contents to ignore any boot up checks.

Also a CM0+ is only Armv6-M and can't do Compare-and-Swap atomic operations, so look for anything using core::sync::atomic that isn't a plain load or store.

Finally, the 2040 HAL is written in the usual style with singletons, and the safety model doesn't hold if you build an application by linking a dozen individual binary applications together. So you'll probably need to write a new one.

But I agree it's a super cheap devkit with excellent availability and would make an interesting starting point for playing with Hubris.

xorbit commented 2 years ago

As the creator of the PoE-FeatherWing, I of course love @Dygear's idea. :) I mainly targeted CircuitPython when I created it, but to be honest I have been frustrated with the low quality of the CircuitPython driver code for the W5500. I spent a lot of time trying to improve it but when I worked on it last I still felt like it was duct taped together. Don't know if it has improved since then, I haven't looked recently.

Anyway, I have had an interest in Rust on embedded and Hubris is a great effort in that regard, because I'd love to see some professional quality framework available for those of us who want to develop applications quickly but want reliability foremost so the hobby codebases won't do.

So I'd be thrilled if Hubris could become a main platform for the PoE-FeatherWing for serious applications. I might be able to contribute to driver code if this became a thing, but I don't really have any real experience yet with Rust and Hubris, so I would need some serious hand holding. It would be great if someone in the know could set up the scaffolding for such a project and those of us learning could help fill things in from there.

As for micro to use, I don't think RP2040 is the way to go. Since security is such an important aspect of Hubris, it seems weird to just throw it away on exposed flash because the maker community loves the name "Raspberry Pi". I think there are better targets. Since STM32 is already supported well, I'd suggest using a Feather STM32F405 Express instead.

jfhbrook commented 2 years ago

I am so happy people are talking about this seriously 🥰

On Sat, Jan 1, 2022 at 3:15 PM Patrick Van Oosterwijck < @.***> wrote:

As the creator of the PoE-FeatherWing, I of course love @Dygear https://github.com/Dygear's idea. :) I mainly targeted CircuitPython when I created it, but to be honest I have been frustrated with the low quality of the CircuitPython driver code for the W5500. I spent a lot of time trying to improve it but when I worked on it last I still felt like it was duct taped together. Don't know if it has improved since then, I haven't looked recently.

Anyway, I have had an interest in Rust on embedded and Hubris is a great effort in that regard, because I'd love to see some professional quality framework available for those of us who want to develop applications quickly but want reliability foremost so the hobby codebases won't do.

So I'd be thrilled if Hubris could become a main platform for the PoE-FeatherWing for serious applications. I might be able to contribute to driver code if this became a thing, but I don't really have any real experience yet with Rust and Hubris, so I would need some serious hand holding. It would be great if someone in the know could set up the scaffolding for such a project and those of us learning could help fill things in from there.

As for micro to use, I don't think RP2040 is the way to go. Since security is such an important aspect of Hubris, it seems weird to just throw it away on exposed flash because the maker community loves the name "Raspberry Pi". I think there are better targets. Since STM32 is already supported well, I'd suggest using a Feather STM32F405 Express https://github.com/oxidecomputer/hubris instead.

— Reply to this email directly, view it on GitHub https://github.com/oxidecomputer/hubris/issues/282#issuecomment-1003611809, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAOBQAA2DMEUKBMLKHIHL3UT5OHDANCNFSM5JD5QQOQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

Dygear commented 2 years ago

thejpster:

The problem with the 2040 for these purposes is that it has an unencrypted external flash. This means it's trivial to get the chip to load untrusted code at boot up, and your only 'fix' is probably to cover the SoC and the flash in a can and a lot of potting (effectively putting them into a single package). An external TPM won't help given you can so easily modify the flash contents to ignore any boot up checks.

xorbit:

As for micro to use, I don't think RP2040 is the way to go. Since security is such an important aspect of Hubris, it seems weird to just throw it away on exposed flash because the maker community loves the name "Raspberry Pi". I think there are better targets. Since STM32 is already supported well, I'd suggest using a Feather STM32F405 Express instead.

First of all, thank you @thejpster for replying to this thread. Your experience is invaluable here. I totally get your point, I would love something that follows the true goal of this parent project where we could get an artifact that is actually secure / verifiable by default. Maybe I don't understand the problem space enough, or products that are out there in the wild to say that we could actually get to a fully secure system with Commodity off the Shelf (COTS) Hardware. xorbit brings up an interesting point below your quote that maybe the RP2040 is not the way to go. The Feather STM32F405 has 1MB of flash built into the chip itself. But all of these chips are available for flashing at any time by entering the UF2 boot loader on the RP2040 family, or DFU Mode on the SMT32F405 -- So maybe security is just not going to be possible if we want to make it easy to use, or these products in general are just not suitable for purpose in lieu of another option that could work?

thejpster:

Also a CM0+ is only Armv6-M and can't do Compare-and-Swap atomic operations, so look for anything using core::sync::atomic that isn't a plain load or store.

(I'm answering these in order, point by point learning as I go, so you can see my opinion change as I write this and new information is presented to me.)

The RP2040's Cortex M0+ lack of core::sync::atomic is probably more the nail in the coffin than anything else however. The Cortex M4 in the STM suggested by Oxbit should however work? I'm leaning on you heavily @thejpster as you have infinitely more experience in this area than I do and I massively value your input here.

thejpster:

Finally, the 2040 HAL is written in the usual style with singletons, and the safety model doesn't hold if you build an application by linking a dozen individual binary applications together. So you'll probably need to write a new one.

I should probably reframe the question here. Do you know of any COTS hardware that we could buy that would meet the requirements of security? I would love to build that on that. I think it would make an interesting project to happen to build in board daylight not only for the learning experience, but because of the inevitable mistakes (that are again learning experiences.)

thejpster:

But I agree it's a super cheap devkit with excellent availability and would make an interesting starting point for playing with Hubris.

On the hardware side, that's pretty much the goal. Excellent availability, easy for newer people to work with, cheap to buy. The Bill of Materials (BOM) cost of the Feather (Be it the RP2040 or the SMT32F405) plus the PoE WeatherWing from xorbit, plus the "TPM" (Massive grain of salt and a pinch of sarcasm here.) would all be under $100. Having an artifact at the end that is useable by building a pseudo product shows a design to market cycle that most people don't get to see as well.

On the software side, composing Hubris onto the hardware and being able to demonstrate the principals of the software. We may not adhere to them entirely due to the nature of the hardware choices. I would like to show some extension here, where we add a module to blink the Neopixel (Present on both the RP2040 and SMT32F4 Feather) when certain events happen. Or a module that looks for the devices's public IP address and updates a DNS record in Google Domains using their DynDNS API. Or go completely rouge and make it a network implant with Zero Teir's protocol and be able to route packets onto any network as could happen with any of these Commerical BMCs.

xorbit:

As the creator of the PoE-FeatherWing, I of course love @Dygear's idea. :) I mainly targeted CircuitPython when I created it, but to be honest I have been frustrated with the low quality of the CircuitPython driver code for the W5500. I spent a lot of time trying to improve it but when I worked on it last I still felt like it was duct taped together. Don't know if it has improved since then, I haven't looked recently.

I actually own the PoE-FeatherWing, I'm very happy with it thank you for making such an awesome product. Ironically it is using CircuitPython but I haven't had any issues with it.

xorbit:

Anyway, I have had an interest in Rust on embedded and Hubris is a great effort in that regard, because I'd love to see some professional quality framework available for those of us who want to develop applications quickly but want reliability foremost so the hobby codebases won't do.

That is what draws me towards Rust. I've built much of my software in other languages over the past 20 years, with 2021 being the year that I actually put Rust into production. I am so surprised how such a low level language has so many nice things from higher level languages. I love that Rust doesn't compile if it's not correct. I actually enjoy the strictness because I never have to wonder if I did the correct thing or not and find out at runtime many hours, days, weeks or months later. I really want to see higher quality driver code and I can't think of another language that would make a better choice here.

xorbit:

So I'd be thrilled if Hubris could become a main platform for the PoE-FeatherWing for serious applications. I might be able to contribute to driver code if this became a thing, but I don't really have any real experience yet with Rust and Hubris, so I would need some serious hand holding. It would be great if someone in the know could set up the scaffolding for such a project and those of us learning could help fill things in from there.

Contributing code would be extraordinarily helpful. I would need all of the help I could get as well.

thejpster commented 2 years ago

But all of these chips are available for flashing at any time

You can usually write protect the start of flash, which is where you put your bootloader. If you also disable JTAG, there's then very little you can do to execute code which the bootloader hasn't approved (without decapping the chip or trying to glitch the power supply to inject faults or flip bits). If you have a Cortex-M33 or -M55 you even get a second level of execution privilege and the ability to 'hide' peripherals from the 'non-secure' mode most code runs in. So even if you got run-time from some input handing bug, you still couldn't even read the bootloader or its private key.

All these things are irrelevant when the flash chip can simply be swapped, as on the 2040.

The RP2040's Cortex M0+ lack of core::sync::atomic...

Only Compare and Swap, which is used for some lockless sharing algorithms. Normal atomic loads and stores are supported. You'd have to review the Hubris code to see if CAS is used - I haven't looked.

Look, if it's a fun hobby project and if upstream wants the patches, the 2040 is a nice chip to use and dirt cheap.

If you want a chip with communications and secure, the Nordic nRF9160 is a Cortex-M33 with an LTE narrow-band cellular radio.

If you want a basic ARM microcontroller with on board flash, the STM32 family is fine. The ST Nucleo dev boards that are already supported (AIUI) are not expensive, but the bare chips are like gold dust at the moment (because they are used in cars and other products, and there's a global chip shortage).

mx-shift commented 2 years ago

I would love something that follows the true goal of this parent project where we could get an artifact that is actually secure / verifiable by default.

This is not the goal of Hubris. Hubris's goal is reliability with task isolation being a key part. Using Hubris for an RoT/BMC/etc depends on a higher-level system design where Hubris is merely one part and application-specific tasks must be written. Oxide's focus in development is toward our RoT and SP use cases for our product but that should not limit the use cases or hardware support for Hubris.

I'd like to see a PR adding RP2040 support to Hubris mainly because it provides an ubiquitous hobbyist board that more easily gets people in a place to tinker with Hubris. I plan to use Hubris for my own hobby projects going forward and none of them are related to RoT or BMC applications.

Dygear commented 2 years ago

kc8apf:

I would love something that follows the true goal of this parent project where we could get an artifact that is actually secure / verifiable by default.

This is not the goal of Hubris. Hubris's goal is reliability with task isolation being a key part. Using Hubris for an RoT/BMC/etc depends on a higher-level system design where Hubris is merely one part and application-specific tasks must be written. Oxide's focus in development is toward our RoT and SP use cases for our product but that should not limit the use cases or hardware support for Hubris.

My apologies for the mischaracterization of the goals for this project. My vision was far to narrow to one of it's applications. I've since re-read the Hubris Reference.

thejpster:

But all of these chips are available for flashing at any time

You can usually write protect the start of flash, which is where you put your bootloader. If you also disable JTAG, there's then very little you can do to execute code which the bootloader hasn't approved (without decapping the chip or trying to glitch the power supply to inject faults or flip bits). If you have a Cortex-M33 or -M55 you even get a second level of execution privilege and the ability to 'hide' peripherals from the 'non-secure' mode most code runs in. So even if you got run-time from some input handing bug, you still couldn't even read the bootloader or its private key.

All these things are irrelevant when the flash chip can simply be swapped, as on the 2040.

I did not know that you could write protect the start of flash as an option. But as you said on the RP2040 class of devices, having exposed chips that can simply be flashed with an external device makes that a fairly moot point. Your later point of the Nordic nRF9160 is an interesting chip as the (1MB of) flash is not easily accessible without decapping to get direct access to it. That actually lead me to the SparkFun Thing Plus - nRF9160 I've ordered two of these to play around with (It's available on Digikey).

thejpster:

The RP2040's Cortex M0+ lack of core::sync::atomic...

Only Compare and Swap, which is used for some lockless sharing algorithms. Normal atomic loads and stores are supported. You'd have to review the Hubris code to see if CAS is used - I haven't looked.

I still have not had the chance, I'll come back to this later.

thejpster:

Look, if it's a fun hobby project and if upstream wants the patches, the 2040 is a nice chip to use and dirt cheap.

It indeed looks like some at Oxide might want that, even if it is for projects outside of the walls of Oxide:

kc8apf:

I'd like to see a PR adding RP2040 support to Hubris mainly because it provides an ubiquitous hobbyist board that more easily gets people in a place to tinker with Hubris. I plan to use Hubris for my own hobby projects going forward and none of them are related to RoT or BMC applications.

I agree, the RP2040 seems to be a great chip to start out with for many people to learn with, while also being fast enough for actual workloads. The ecosystem around it already, perhaps a byproduct of the Raspberry Pi reputation, really inspires confidence that this chip is going to be around and available for a long while to come.

thejpster:

If you want a chip with communications and secure, the Nordic nRF9160 is a Cortex-M33 with an LTE narrow-band cellular radio.

If you want a basic ARM microcontroller with on board flash, the STM32 family is fine. The ST Nucleo dev boards that are already supported (AIUI) are not expensive, but the bare chips are like gold dust at the moment (because they are used in cars and other products, and there's a global chip shortage).

Now that I've found the Sparkfun board linked above, and in the feather form factor no less, I would love to also work on the nRF9160 support. Maybe not at the first system however as it seems like a much more complicated chip. That is a chip that I would love to use professionally. It scratches all of the itches that I've had in the last few years.

thejpster commented 2 years ago

https://github.com/42-technology-ltd/nrfxlib may be of use if you want to use the modem. I guess you'd put that lib in a task and send messages to the task to do things over the network - connect, open a TCP socket, send data, etc.

thejpster commented 2 years ago

Oh and I did look and Hubris doesn't seem to do any CAS, only store and load. But a build for thumbv6m will tell you for certain.

Dygear commented 2 years ago

thejpster

https://github.com/42-technology-ltd/nrfxlib may be of use if you want to use the modem. I guess you'd put that lib in a task and send messages to the task to do things over the network - connect, open a TCP socket, send data, etc.

That will be very helpful in the future. I ordered the board from Sparkfun. I have it with me now. I made a product with the Adafruit Feather FONA 32u4 and the (Adafruit Ultimate GPS FeatherWing)[https://www.adafruit.com/product/3133] on top. It was kind of shocking how accurate that stack was, from my testing the GPS was accurate enough to tell what lane I was diving in. The limitation and part of the reason why it was discontinued is that the FONA board is 2G only. But it was shocking how much you could get out of a 32K of flash, 2K of RAM and an 8MHz CPU. The SparkFun Thing Plus - nRF9160 is that in a single sandwich, AND has LTE. I'm pretty excited to start using that.

thejpster:

Oh and I did look and Hubris doesn't seem to do any CAS, only store and load. But a build for thumbv6m will tell you for certain.

Installed by rustup target add thumbv6m-none-eabi for those playing along at home.

Apple MacBook Pro M1 Pro (16-inch 2021) macOS Monterey Version 12.1, the following commands made a working build system for hubris. I did not have brew installed at the time, but I did have Xcode, so that might be a clean state step that may need to be completed.

This builds the Demo STM32F4 & STM32F3 Discovery binary. It should be noted that the Discovery kit with STM32F303VC MCU is the same board used by the Rust Embedded Book. Helpfully, I have one of these at home already so I'll try loading onto that board once I get home. I did not however have the ‎STLINK-V3SET‎ that I believe is required for debugging. It's actually the STLink V2 But that seems to be out of stock everywhere, hopefully the V3 works just as well.

rumpuslabs commented 2 years ago

Going back to the original topic of this issue; my STM32H7B3I-DK just arrived (the only Hubris-supported board I could find in stock) and I'd be happy to write some kind of getting started guide as I work through getting it running. Open to suggestions as to location, format, content etc.

mx-shift commented 2 years ago

https://hubris.oxide.computer/reference/ is generated from the AsciiDoc files in https://github.com/oxidecomputer/hubris/tree/master/doc. A PR that adds a "Getting Started" section seems like a reasonable approach.

On Thu, Feb 24, 2022 at 2:59 AM Tim Bates @.***> wrote:

Going back to the original topic of this issue; my STM32H7B3I-DK just arrived (the only Hubris-supported board I could find in stock) and I'd be happy to write some kind of getting started guide as I work through getting it running. Open to suggestions as to location, format, content etc.

— Reply to this email directly, view it on GitHub https://github.com/oxidecomputer/hubris/issues/282#issuecomment-1049738113, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACIEHF64ALVPGSXVZDQZP5TU4YFQVANCNFSM5JD5QQOQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

KorvinSzanto commented 2 years ago

I know this isn't the rp2040 but for what it's worth I was able to get hubris running on this stm32 nucleo I got for $40 within a day https://www.amazon.com/dp/B01I8XLEM8 using the demo-stm32f4-discovery demo as described in the readme.