Portable Position-Independent Code (PIC) bootloader and firmware for ARM Cortex-M0 and Cortex-M4

Disclaimer 2024-05-07

Although PIC was a very interesting trek in the deep embedded territory, I’m not that confident about the benefits as of today, 2024-05-07. See the comment below from “manne”.  He discovered that even though some aspects of my solution works, it is basically unusable in the comprehensive scale. Therefore, for the time being, I am discouraging people from using PIC in real-world applications, and only exploring the subject for academic interest. I will write later more in-depth analysis of shortcomings and will also propose some compiler changes to tackle the main issue and also some some generic PIC optimizations.

Rest of the text is kept for posterity.

How to implement Position-Independent Code for microcontroller (MCUs) is a question which has been asked countless and countless of times all over the Internet. The answers and “solutions” are usually whippersnappering comments dropping a couple of key terms they probably just googled up without any kind of intrinsic knowledge about how the system should be working.

Sometimes the answer is “OK I got it working” followed by eternal silence from people asking clarifications. In other words, it looks like the task is very difficult and once people get it to work, it is so valuable they want to hide the details. In a way I cannot blame them much; it took me 6 months of half-time work every now and then to understand everything.

So, some 6 months ago I set myself a goal: “Create a portable solution where an intelligent bootloader can boot firmware images from any address in flash on Cortex-M0 or Cortex-M4 platform.” Finally, as of today 2022-01-16, I consider I have solved the problem in an intelligent and understandable way.

Funnily, I think I am the only person on planet Earth who has made available readily working example code and documented the code in a way I am doing now in this post.

Those impatient can explore the fully working STM32CubeIde codes at GitHub, for Cortex-M0: https://github.com/usvi/F070RB-BL-FW  and for Cortex-M4: https://github.com/usvi/L432KC-BL-FW  . (One might ask why one would use this kind of bloated stock configuration for developing on MCUs. Believe me, I’m doing it here only for pedagogical reasons. This way it is easier for noobs having the needed evaluation boards to verify that the code is working.)

The set of code I have created is a proof-of-concept, working for the C language. There might, and I underline, might be unforeseen problems when amount of global variable gets absurdly high. In any case, comments and criticism is more than welcome.

If you are ready to dive into the deep end of Cortex-M boot process, PIC constructs, esoteric debugging and linker script optimizations, continue reading…

Continue reading “Portable Position-Independent Code (PIC) bootloader and firmware for ARM Cortex-M0 and Cortex-M4”

Dynamically generated MCU binary image header (Arm Cortex-M4)

Every seasoned embedded systems engineer faces at some point of their career a problem about needing to put a header to their built firmware image binaries. This header usually contains at least information about what device the image is for and what version number the image is. Checksums are also common.

There are multiple ways of implementing the header. One solution is to just glue it on top of the image and peel it off while updating the firmware via IAP or external programmer means.

Another approach is to place it actually in firmware flash, to a known location, possibly even start of the image, but use a bootloader to jump past the header.

There is however yet another solution I’m going to demonstrate. It is about generating the header template directly into the flash image, and even surprisingly in a way that the MCU can start executing actually from the beginning of the header (template). An external tool is used later to fill in checksum data.

But before continuing, heres a big fat warning:

WE ARE MANIPULATING VECTOR TABLE OFFSETS WHICH IS CONSIDERED DANGEROUS PRACTICE REGARDING ULTIMATE RELIABILITY OF THE RUNNING CODE. YOU HAVE BEEN WARNED.

There. Now lets go on.

We will be working on our trusty old STM32 Nucleo-L432KC and STM32CubeIDE. Example codes are available at https://github.com/usvi/L432KC-dynamic-header .

Continue reading “Dynamically generated MCU binary image header (Arm Cortex-M4)”

Debugging tricky (Arm Cortex-M4) code with register values

Sometimes you may run into problems when debugging tricky code. This is the case especially with microcontroller code if you are implementing a bootloader+firmware image solution. Debugger started in bootloader goes haywire and displays garbage or nothing at all when jumping to firmware.

Normally one should invest some time in getting debugger symbols aligned properly with source code, but if there are for example some barring deficiencies in environment or debugger UI, one can still figure out a bit more what is going on by using spare register values. Following shows a somewhat obvious, but still possibly helpful technique in brief for aforementioned debugging situations.

UPDATE 2021-08-16:
To get the job actually done, see my follow-up post

But in any case, the rest of the earlier post is here for posterity.

Continue reading “Debugging tricky (Arm Cortex-M4) code with register values”

Complicatedly authorizing WhatsApp Web clients for VMware ESXi (6.7) Android x86 7.1

UPDATE 2023-07-20: I wrote earlier that WhatsApp might have broken this functionality. But actually my installation has been working just fine after I emptied my 70GB Firefox profile.

We have arrived to the last part of our ESXi WhatsApp saga. This blog post will tell a very cumbersome way of authorizing WhatsApp Web clients so you can enjoy the benefits of the application with you preferred computer and browser. Follow on!

This post is the last part (so far) in the 3-part series:

Installing Android x86 7.1 on VMware ESXi 6.7

Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1

Complicatedly Authorizing WhatsApp Web clients for VMware ESXi (6.7) Android x86 7.1

Continue reading “Complicatedly authorizing WhatsApp Web clients for VMware ESXi (6.7) Android x86 7.1”

Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1

The journey continues. In this blog post we learn how to get WhatsApp installed on our freshly installed Android x86 7.1 . This article exists for 2 reasons:

  1. To offer completeness in our efforts to get virtualized WhatsApp instances to authorize regular WhatsApp web clients
  2. To show the minor differences there are involved in the process compared to normal WhatsApp install

This is the second article in our 3 article series:

Installing Android x86 7.1 on VMware ESXi 6.7

Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1

Complicatedly authorizing WhatsApp Web clients for VMware ESXi (6.7) Android x86 7.1

Again, as always, lets get started.

Continue reading “Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1”

Installing Android x86 7.1 on VMware ESXi 6.7

I am one of those people who are perfectly fine with old style dumb 3G phones. But unfortunately some people are reluctant to communicate nowadays with regular phone calls, SMS or IRC, so I basically need to keep Android at hand for running WhatsApp.

Recently I found a way to run Android x86 7.1 on VMware ESXi 6.7. After a lot of teeth grinding, I was able to get WhatsApp running inside it. And after enormous test and debug efforts, I was even able to authorize WhatsApp Web clients. But with a lot of hoop-running. Extremely lot.

I chose Android x86 7.1 because it seems to be working completely for my desired purposes without (much) graphical glitches. For example 8.1 has horrible glitches which actually make many parts of initial setup widgets invisible 😀 . I chose VMware ESXi 6.7 as host because it is of the most stable main branch of the hypervisor. Host hardware is Intel NUC8i7HVK with 32GB RAM.

This is the list of articles of the whole operation (split due to big amount of screenshots):

Installing Android x86 7.1 on VMware ESXi 6.7

Installing WhatsApp on VMware ESXi (6.7) Android x86 7.1

Complicatedly authorizing WhatsApp Web clients for VMware ESXi (6.7) Android x86 7.1

Props to this external blog post for guiding me to the right direction. But now lets get started with our own stuff.

Continue reading “Installing Android x86 7.1 on VMware ESXi 6.7”

How to FIX Windows update error 8050800C about Windows Defender Definition Update

Did you receive the 8050800C error from Windows update while trying to get the Windows Defender updates? I did with my Windows 7 Pro 64.  Lots of sites tell a lot of stupid things to try, things that are only there to make the site catch more Google hits to serve more ads. Nobody seems to test their stuff anymore. I did. And I have a working, tested solution.

Executive summary of fix:

  1. Download the the Windows Defender update file manually (mpas-fe.exe, available from https://www.microsoft.com/en-us/wdsi/definitions )
  2. Start Windows in safe mode
  3. Run the downloaded exe in safe mode and reboot (or optionally run the exe with Windows Update Service disabled)
  4. It’s fixed!

For more details and illustrated guide, read more below.

Continue reading “How to FIX Windows update error 8050800C about Windows Defender Definition Update”

Chair-bombing at work

About a month back or so I got to the office in the morning as usual. I sat down on my office chair. For a while things were as any other morning. Then I started to hear eerie music with a weird male voice-over. I had difficulties locating the source first. I checked under the laptop, behind it, under the table. Then I noticed that the sound came from bottom of my chair.

Trigger mechanism for the office chair.

I took a look and.. just whoa! You cannot make this up. My workmates had rigged my office chair. Ingenious! They had used some USB powered promotional video board to play the weird video file. Then they had removed the power cords, soldered them to a micro switch and attached it to the base of my chair with electrical tape. They told me they had used quite a while in fine-tuning this installation. Good work, it actually worked very nice.

Continue reading “Chair-bombing at work”

Xerox laser toner cartridges programmed to fail

A few years back I ran into a problem with a Xerox 7700 laser printer. The print quality had been OK, but suddenly the printer reported that a toner cartridge had to be changed and refused to print anymore. After checking up on prices it seemed like we needed to spend 200 EUR to buy a new cartridge.

I googled around a bit and found out interesting piece of information. It seemed like the toner cartridges had some kind of memory units regarding print counts. Once the counter reaches zero, the cartridge stops printing. At this point I decided to hack the cartridge back to a working state.

1. First I removed the toner cartridge from the printer.

Continue reading “Xerox laser toner cartridges programmed to fail”