Thoughts of the FSFE Community

Monday, 23 April 2018

Another Summer of Code with Smack

vanitasvitae's blog » englisch | 17:15, Monday, 23 April 2018

I’m very happy to announce that once again I will participate in the Summer of Code. Last year I worked on OMEMO encrypted Jingle Filetransfer for the XMPP client library Smack. This year, I will once again contribute to the Smack project. A big thanks goes out to Daniel Gultsch and Conversations.im, who act as an umbrella organization.

My new project will be an implementation of XEP-0373 and XEP-0374 OpenPGP for XMPP + Instant Messaging. The projects description can be found here.

Now I will enjoy my last few free days before the hard work begins. I will keep you updated :)

Happy Hacking!

Thursday, 19 April 2018

DataworksSummit Berlin - Wednesday morning

Inductive Bias | 06:50, Thursday, 19 April 2018

Data strategy - cloud strategy - business strategy: Aligning the three was one of the main themes (initially put forward in his opening keynote by CTO of Hortonworks Scott Gnau) thoughout this weeks Dataworks Summit Berlin kindly organised and hosted by Hortonworks. The event was attended by over 1000 attendees joining from 51 countries.

The inspiration hat was put forward in the first keynote by Scott was to take a closer look at the data lifecycle - including the fact that a lot of data is being created (and made available) outside the control of those using it: Smart farming users are using a combination of weather data, information on soil conditions gathered through sensors out in the field in order to inform daily decisions. Manufacturing is moving towards closer monitoring of production lines to spot inefficiencies. Cities are starting to deploy systems that allow for better integration of public services. UX is being optimized through extensive automation.

When it comes to moving data to the cloud, the speaker gave a nice comparison: To him, explaining the difficulties that moving to the cloud brings is similar to the challenges that moving "stuff" to external storage in the garage brings: It opens questions of "Where did I put this thing?", but also about access control, security. Much the same way, cloud and on-prem integration means that questions like encryption, authorization, user tracking, data governance need to be answered. But also questions like findability, discoverability and integration for analysis purposes.

The second keynote was given by Mandy Chessell from IBM introducing Apache Atlas for metadata integration and governance.

In the third keynote, Bernard Marr talked about the five promises of big data:

  • Informing decisions based on data: The goal here should be to move towards self service platforms to remove the "we need a data scientist for that" bottleneck. That in turn needs quite some training and hand-holding for those interested in the self-service platforms.
  • Understanding customers and customer trends better: The example given was a butcher shop that would install a mobile phone tracker in his shop window in order to see which advertisement would make more people stop by and look closer. As a side effect he noticed an increase in people on the street in the middle of the night (coming from pubs nearby). A decision was made to open at that time, offer what people were searching for at that time according to Google trends - by now that one hour in the night makes a sizeable portion of the shop's income. The second example given was Disney already watching all it's Disney park visitors through wrist bands, automating line management at popular attractions - but also deploying facial recognition watching audiences watch shows in figure out how well those shows are received.
  • Improve the customer value proposition: The example given was the Royal Bank of Scotland moving closer to it's clients, informing them through automated means when interest rates are dropping, or when they are double insured - thus building trust and transparency. The other example given was that of a lift company building sensors into lifts in order to be able to predict failures and repair lifts when they are least used.
  • Automate business processes: Here the example was that of a car insurance that would offer dynamic rates if people would let themselves monitor during driving. Those adhering to speed limits, avoiding risky routes and times would get lower rates. Another example was that of automating the creation of sports reports e.g. for tennis matches based on sensors deployed, or that of automating Forbes analyst reports some of which get published without the involvement of a journalist.
  • Last but not least the speaker mentioned the obvious business case of selling data assets - e.g. selling aggregated and refined data gathered through sensors in the field back to farmers. Another example was the automatic detection of events based on sounds detected - e.g. gun shots close to public squares and selling that back to the police.


After the keynotes were over breakout sessions started - including my talk about the Apache Way. It was good to see people show up to learn how all the open source big data projects are working behind the scences - and how they themselves can get involved in contributing and shaping these projects. I'm looking forward to receiving pictures of feather shaped cookies.

During lunch there was time to listen in on how Santander operations is using data analytics to drive incident detection, as well as load prediction for capacity planning.

After lunch I had time for two more talks: The first explained how to integrate Apache MxNet with Apache NiFi to bring machine learning to the edge. The second one introduced Apache Beam - an abstraction layer above Apache Flink, Spark and Google's platform.

Both, scary and funny: Walking up to the Apache Beam speaker after his talk (having learnt at DataworksSummit that he is PMC Chair of Apache Beam) - only to be greeted with "I know who *you* are" before even getting to introduce oneself...

Tuesday, 17 April 2018

Extending L4Re/Fiasco.OC to the Letux 400 Notebook Computer

Paul Boddie's Free Software-related blog » English | 23:31, Tuesday, 17 April 2018

In my summary of the port of L4Re and Fiasco.OC to the Ben NanoNote, I remarked that progress had been made on supporting other products and hardware peripherals. In fact, such progress occurred more rapidly than I had thought possible, and I have been able to extend the work to support the Letux 400 notebook computer. It is perhaps worth describing the Letux 400 in a bit more detail because it has an interesting place in the history of netbook computers.

Some History

Back in the early 21st century, laptop computers were becoming increasingly popular at the expense of desktop computers, but as laptops began to take the place of desktops in homes and workplaces, this gradually led each successive generation of laptops to sacrifice portability and affordability in favour of larger, faster, higher-resolution screens and general hardware specifications more competitive with the desktop offerings they sought to replace. Laptops were becoming popular but also bigger, heavier and more expensive.

Things took an interesting turn in 2006 with the introduction of the XO-1 from the One Laptop per Child (OLPC) initiative. With rather different goals to those of the mainstream laptop vendors, the focus was to deliver a relatively-inexpensive yet robust portable computer for use by schoolchildren, many of whom might be living in places with limited infrastructure where increasingly power-hungry mainstream laptops would have been unsuitable, even unusable.

One unexpected consequence of the introduction of the XO-1 was the revival in interest in modestly-performing portable computing hardware. People were actually interested in a computer that did the things they needed, rather than having to buy something designed for gamers, software developers, or corporate “power users” (of both the pretend and genuine kinds). Rather than having to haul increasingly big and heavy laptops and all the usual accessories in a big dedicated bag, they liked the idea of slipping a smaller, lighter device into their everyday bag, as had probably been the idea with subnotebooks while they were still a thing.

Thus, the Asus Eee PC came about, regarded as the first widely-available netbook of recent times (acknowledging the earlier Psion netBook, of course), bringing with it the attention of large-volume manufacturers and economies of scale. For “lightweight tasks”, netbooks were enough for many people: a phenomenon that found itself repeating with tablets, particularly as recreational usage of technology became more important to buyers and evolved in certain ways.

Now, one thing that had been a big part of the OLPC initiative’s objectives was a $100 price point. At first, despite fairly radical techniques being used to reduce cost, and despite the involvement of a major original equipment manufacturer in the production of the XO-1, that price point of $100 was out of reach. Even the Eee PC retailed for a few hundred dollars.

This is where a product known as the Skytone Alpha 400 enters the picture. Some vendors, rebranding this product, offered it as possibly the first $100 laptop – or netbook – to be made available for sale. One of the vendors offers it as the Letux 400, and it has been available for as little as €125 during its retail lifespan. Noting that it has rather similar hardware to the Ben NanoNote, but has a more conventional physical profile and four times as much RAM, my brother bought one to investigate a few years ago. That is how I eventually ended up embarking on this experiment.

Extending Recent Work

There are many similarities between the JZ4720 system-on-a-chip (SoC) used in the Ben and the JZ4730 used in the Letux 400. However, it can be said that the JZ4720 is much better understood. The JZ4740 and closely-related devices like the JZ4720 have appeared in a number of different devices, documentation has surfaced for these products, and vendor source code has always been available, typically using or implicitly documenting most of the hardware.

In contrast, limited documentation is known to exist for the JZ4730, and the available vendor source code has not always described every detail of the hardware, even though the essential operations and register details appear to be present. Having looked at the Linux kernel sources that support the JZ4730, together with U-Boot source code, the similarities and differences between the JZ4720 and JZ4730 began to take shape in my mind.

I took an optimistic approach that mostly paid off. The Fiasco.OC kernel needs augmenting with the details of the JZ4730, but these are similar in some ways to the JZ4720 and familiar otherwise. For instance, the JZ4730 has a 32-bit “operating system timer” (OST) that curiously does not appear in the JZ4740 but does appear in more recent products such as the JZ4780. Bearing such things in mind, the timer and interrupt support was easily enough added.

One very different thing about the JZ4730 is that it does not seem to support the “set” and “clear” register locations that are probably common to most modern SoCs. Typically, one might want to update a hardware-related register to change a peripheral’s configuration, and it must have become apparent to hardware designers that such updates mostly want to either set or clear bits. Normally in a program, to achieve such things involves reading a value, performing a logical operation that combines the value with a description of the bits to be set or cleared, and then the value is written back to where it came from. For example:

define bits to set
load value from location (exposing a hardware register, perhaps)
logical-or value with bits
store result in location

Encapsulating this in a single instruction avoids potential issues with different things competing to update the location at the same time, if the hardware permits this, and just offers something that is more efficient and convenient, anyway. Separate locations are provided for “set” and “clear” operations, and the original location is provided to read and to overwrite the hardware register’s value. Sometimes, such registers might only support read-only access, in fact. But the JZ4730 does not support such additional locations, and so we have to do things the hard way when updating registers and doing things like clearing and setting bits.

One odd thing that caught me out was a strange result from the special “exception base” (EBASE) register that does not seem to return zero for the CPU identifier, something that the bootstrap code in L4Re expects. I suppressed this test and made the kernel always return zero when it asks for this identifier. To debug such things, I could not use the screen as I had done with the Ben since the bootloader does not configure it on the Letux. Fortunately, unlike the Ben, the Letux provides a few LEDs to indicate things like keyboard and network status, and these can be configured and activated to communicate simple status information.

Otherwise, the exercise mostly involved me reworking some existing code I had (itself borrowing somewhat from existing driver code) that provides driver support for the Letux hardware peripherals. The clock and power management (CPM) arrangement is familiar but different from the JZ4720; the LCD driver can actually be used as is; the general-purpose input/output (GPIO) arrangement is different from the JZ4720 and, curiously enough once again, perhaps more similar to the JZ4780 in some ways. To support the LCD panel’s backlight, a pulse-width modulation (PWM) driver needed to be added, but this involves very little code.

I also had to deal with the mistakes I made myself when not concentrating hard enough. Lots of testing and re-testing occurred. But in the space of a weekend or so, I had something to show for all the previous effort plus this round’s additional effort.

The Letux 400 and Ben NanoNote running the "spectrum" example

The Letux 400 and Ben NanoNote running the "spectrum" example

Here, you can see what kind of devices we are dealing with! The Letux 400 is less than half the width of a normal-size keyboard (with numeric keypad), and the Ben NanoNote is less than half the width of the Letux 400. Both of them were inexpensive computing devices when they were introduced, and although they may not be capable of running “modern” desktop environments or Web browsers, they offer computing facilities that were, once upon a time, “workstation class” in various respects. And they did, after all, run GNU/Linux when they were introduced.

And that is why it is attractive to consider running other “proper” operating system technologies on them now. Maybe we can revisit the compromises that led to the subnotebook and the netbook, perhaps even the tablet, where devices that are not the most powerful still have a place in fulfilling our computing needs.

Apache Breakfast

Inductive Bias | 07:39, Tuesday, 17 April 2018

In case you missed it but are living in Berlin - or are visiting Berlin/ Germany this week: A handful of Apache people (committers/ members) are meeting over breakfast on Friday morning this week. If you are interested in joining, please let me know (or check yourself - in the archives of the mailing list party@apache.org)

FOSS Backstage - Schedule online

Inductive Bias | 07:27, Tuesday, 17 April 2018

In January the CfP for FOSS Backstage opened. By now reviews have been done, speakers notified and a schedule created.

I'm delighted to find both - a lot of friends from the Apache Software Foundation but also a great many speakers that aren't affiliated with the ASF among the speakers.

If you want to know how Open Source really works, if you want to get a glimpse behind the stage, do not wait for too long to grab your ticket now and join us in summer in Berlin/ Germany.

If project management is only partially of your interest, we have you covered as well: For those interested in storing, searching and scaling data analysis, Berlin Buzzwords is scheduled to take place in the same week. For those interested in Tomcat, httpd, cloud and iot, Apache Roadshow is scheduled to happen on the same days as FOSS Backstage - and your FOSS Backstage ticket grants you access to Apache Roadshow as well.

If you're still not convinced - head over to the conference website and check out the talks available yourself.

Monday, 16 April 2018

Porting L4Re and Fiasco.OC to the Ben NanoNote (Summary)

Paul Boddie's Free Software-related blog » English | 20:36, Monday, 16 April 2018

As promised, here is a summary of the work involved in porting L4Re and Fiasco.OC to the Ben NanoNote. First of all, a list of all the articles with some brief descriptions of what they cover:

  1. Familiarisation with L4Re and Fiasco.OC on the MIPS Creator CI20, adding some missing pieces
  2. Setting up and introducing a suitable compiler for the Ben, also describing the hardware in the kernel
  3. Handling instructions unsupported by the JZ4720 (the Ben’s SoC) in the kernel
  4. Describing the Ben and dealing with unsupported instructions in the L4Re portion of the system
  5. Configuring the memory layout and attempting to bootstrap the kernel
  6. Making the kernel support the MIPS architecture revision used by the JZ4720, also fixing the interrupt system description
  7. Investigating context/thread switching and fixing an inadvertently-introduced fault in the unsupported instruction handling
  8. Configuring user space examples and getting a simple framebuffer demonstration working
  9. Getting the framebuffer driver, GUI multiplexer, and “spectrum” example working

As I may have noted a few times in the articles, this work just builds on previous work done by a number of people over the years, obviously starting with the whole L4 microkernel effort, the development of Fiasco.OC, L4Re and their predecessors, and the work done to port these components to the MIPS architecture. On the l4-hackers mailing list, Adam Lackorzynski was particularly helpful when I ran into obstacles, and Sarah Hoffman provided some insight into problems with the CI20 just as it was needed.

You really don’t have to read all the articles or even any of them! The point of this article is to summarise the work and perhaps make similar porting efforts a bit more approachable for others in the same position: anyone having a vague level of familiarity with L4Re/Fiasco.OC or similar systems, also having a device that might be supported, and being somewhat familiar with writing code that drives hardware.

Practical Details

It might be useful to give certain practical details here, if only to indicate the nature of the development and testing routine employed in this endeavour. First of all, I have been using a chroot containing the Debian “unstable” distribution for the i386 architecture. Although this was essential for a time when building the software for the CI20 and trying to take advantage of Debian’s cross-compiler packages, any fairly recent version of Debian would probably be fine because I ended up using a Buildroot toolchain to be able to target the Ben. You could probably choose any Free Software distribution and reproduce what I have done.

The distribution of patches contains instructions regarding preparation and the building of the software. It isn’t too useful to repeat that information here, but the following things need doing:

  1. Installing packages for build tools
  2. Obtaining or building a cross-compiler
  3. Checking out the source code for L4Re and Fiasco.OC from its repository
  4. Applying the patches
  5. Configuring and building the kernel
  6. Configuring and building the runtime environment
  7. Copying the payload to a memory card
  8. Booting the device

Some scripts have been included in the patch distribution, one of which should do the tricky job of applying patches to the repository checkout according to the chosen device configuration. Because a centralised version control system (Subversion) has been used to publish the L4Re and Fiasco.OC sources, I had to find a way of working with my own local changes. Consequently, I wrote a few scripts to maintain bundles of changes associated with certain files, and I then managed these bundles in a different version control system. Yes, this effectively meant versioning the changes themselves!

Things would be simpler with a decentralised version control system because local commits would be convenient, and upstream updates would be incorporated into the repository separately and merged with local changes in a controlled fashion. One of the corporate participants has made a Git repository for Fiasco.OC available, which may alleviate some issues, although I am increasingly finding larger Git repositories to be unusable on my modest hardware, and I also tend to disagree with everybody deciding to put everything on GitHub.

Fixing and Building

Needing to repeatedly build, test, go back and fix, I found myself issuing the same command sequences a lot. When working with the kernel, I tended to enter the kernel build directory, which I called “mybuild”, edit the kernel sources, and then re-run the make command:

cd mybuild
vi ../src/kern/mips/exception.S # edit a familiar file with vim
make

Having built a new kernel, I would then need to build a new payload to deploy, which meant ascending the directory hierarchy and building an image in the L4Re section of the sources:

cd ../../../l4
make O=mybuild uimage E=mips-qi_lb60-spectrum-example

Given a previously-built “user space”, this would bundle the new kernel together with code that might be able to test it. Of particular importance is the bootstrap code which launches the kernel: without that, there is no point in even trying to test the kernel!

I found that re-building L4Re components seemed to require a general build to be performed:

make O=mybuild

If that proved successful, an image would then be built and tested. In general, focusing on either the kernel or some user space component meant that there was rarely a need to build a new kernel and then build much of the user space.

Work Summary

The patches accumulated during this process cover a range of different areas of functionality. Looking at them organised by functional area, instead of in the more haphazard fashion presented throughout the series of articles, allows for a more convenient review of the work actually needed to get the job done.

Build System Adjustments and Various Fixes

As early as my experiments with the CI20, I experienced the need to fix some things that didn’t work on my system, either due to some Debian peculiarities or differences in compiler behaviour:

  • l4util-mips-thread.diff (fixes a symbol visibility issue with certain compiler versions)
  • mips-gcc-cpload.diff (fixes the initialisation of certain L4Re components)
  • no-at.diff (allows the build to work on Debian for the i386 architecture)

Other adjustments are required to let the build system do its job, setting paths for other components and for the toolchains:

  • conf-makeconf-boot.diff (lets the L4Re build system find things like the kernel, modules and hardware descriptions)
  • qi_lb60-gcc-buildroot-fiasco.diff (changes the compiler and architecture settings)
  • qi_lb60-gcc-buildroot-l4re.diff (changes the compiler, architecture and soft-float settings)

The build system also needs directing towards new drivers, and various files need to be excluded or changed:

  • ingenic-mips-drivers-top.diff (enables drivers added by this work)
  • qi_lb60-fbdrv.diff (changes the splash image for the framebuffer driver)
  • qi_lb60-l4re.diff (includes a temporary fix disabling a Mag plugin)

The first of these is important to remember when adding drivers since it changes the l4/pkg/drivers/Control file and defines the driver “packages” provided by each of the driver libraries. These package definitions help the build system work out which other parts of the system need to be consulted when building a particular driver.

Supporting MIPS32r1 Devices

Throughout the kernel and L4Re, changes need making to support the earlier architecture version provided by the JZ4720. The bulk of the following patch files deals with such changes:

  • qi_lb60-fiasco.diff
  • qi_lb60-l4re.diff

Maybe I will try and break out the architecture version changes into specific patch files, provided this does not result in the original source files ending up being patched by multiple patch files. My aim has been to avoid patches having to be applied in a particular order, and that starts to happen when multiple patches modify the same file.

Describing the Ben NanoNote

The kernel needs some knowledge of the Ben with regard to timers and interrupts. Meanwhile, L4Re needs to set the Ben up correctly when booting. Both sections of the system need an awareness of how memory is going to be used, and extra configuration options need to be provided to merely allow the selection of the Ben for building. Currently, the following patch files include things concerned with such matters:

  • qi_lb60-fiasco.diff (contains timer, interrupt and memory details, plus configuration system changes)
  • qi_lb60-l4re.diff (contains bootstrap and memory details, plus configuration system changes)
  • qi_lb60-platform.diff (platform definitions for the Ben in L4Re)

One significant objective here is to be able to offer the Ben as a “first class” configuration option and have the build system do the right thing, setting up all the components and code regions that the Ben needs to function.

Introducing Driver Code

To be able to activate the framebuffer on the Ben, driver code needs introducing for a few peripherals provided by the JZ4720: CPM (clock/power management), GPIO (general-purpose input/output) and LCD (liquid crystal display, or similar). A few different patch files cover these areas:

  • ingenic-mips-cpm.diff (CPM support for JZ4720 and JZ4780)
  • ingenic-mips-gpio.diff (GPIO support for JZ4720 and JZ4780)
  • qi_lb60-lcd.diff (LCD support for JZ4720)

The JZ4780 support is intended for the CI20 and will not be used with the Ben. However, it is convenient to incorporate support for these different platforms in the same patch file in each instance.

Meanwhile, the LCD driver should work with a range of JZ4700-series devices (labelled as JZ4740 in the patches). While focusing on getting things working, the only panel supported by this work was that provided by the Ben. Since then, support has been made slightly more general, just as was done with the Linux kernel support for products employing this particular SoC family and, subsequently, for panels in general. (Linux has moved towards a “device tree” approach for specifying things like panels and displays, although this is arguably just restating things that were once C-coded structures in another, rather peculiar, format.)

To support these drivers, some useful code has been copied from elsewhere in L4Re:

  • drivers_frst-register-block.diff

This provides a convenient abstraction for registers that is exposed via an include directive:

#include <l4/drivers/hw_mmio_register_block.h>

Indeed, it is worth focusing on the LCD driver briefly. The code has its origins in existing driver code written for the Ben that I adapted to get working as part of a simple “bare metal” payload. I have maintained a separation between the more intricate hardware configuration and aspects that deal with the surrounding software. As part of L4Re, the latter involves obtaining access to memory using the appropriate API calls and invoking other drivers.

In L4Re, there is a kind of framework for LCD drivers, and the existing drivers seem to be written in C rather than C++. Reminiscent of Linux, there is a mechanism for exporting driver operations using a well-defined data structure, and this permits the “probing” of drivers to see if they can be enabled and if meaningful information can be obtained about things like the supported resolution, colour depth and pixel format. To make the existing code compatible with L4Re, a fair amount of the work involves translating the information already known (and used) in the hardware configuration activity to a form that other L4Re components can understand and use.

Originally, for the GPIO driver, I had intended it to operate as part of the Io server framework. Components using GPIO functionality would then employ the appropriate API to configure and interact with the exposed input and output pins. Unfortunately, this proved rather cumbersome, and so I decided to take a simpler approach of providing the driver as an abstraction that a program would use together with explicitly-requested memory. I did decide to preserve the general form of the API for this relocated abstraction, however, meaning that various classes and methods are provided that behave in the same way as those “left behind” in the Io server framework.

Thus, a program would itself request access to the GPIO-related memory, and it would then use GPIO-related abstractions to “do the right thing” with this memory. One would envisage that such a program would not be a “normal”, unprivileged program as such, but instead be more like a server or driver in its own right. Indeed, the LCD driver employs these abstractions to use SPI-based signalling with the LCD panel, and it uses the same techniques to configure the LCD clock frequencies using the CPM-related memory and CPM-related abstractions.

Although the GPIO driver follows existing conventions, the CPM driver has no obvious precedent in L4Re, but I adopted some of the conventions employed in the GPIO driver, adding more specialised methods and functions to expose functionality specific to the SoC. Since I had previously written a CPM driver for the JZ4780, the main objective was to make the JZ4720/JZ4740 driver resemble the existing driver as much as possible.

Introducing and Configuring Example Programs

Throughout the series of articles, I was working towards running one specific example program, making some new ones on the way for testing purposes. These additional programs are provided together with their configuration, accompanied by suitable configurations for existing examples and components, by the following patch files:

  • ingenic-mips-modules.diff (example program definitions)
  • qi_lb60-examples.diff (example program implementations and configuration details)

The additional programs (defined in l4/conf/modules.list) are as follows:

  • mips-qi_lb60-lcd-example (implemented by qi_lb60_lcd, configured by the mips-qi_lb60-lcd files)
  • mips-qi_lb60-lcd-driver-example (implemented by qi_lb60_lcd_driver, configured by the mips-qi_lb60-lcd-driver files)

Configurations are provided for the existing examples and components as follows:

  • mips-qi_lb60-fbdrv-example (configured by the mips-qi_lb60-fbdrv files)
  • mips-qi_lb60-spectrum-example (configured by the mips-qi_lb60-spectrum files)

All configurations reside in the l4/conf/examples directory. All new examples reside in the l4/pkg/examples/misc directory.

Further Work

In the final article in the series, I mentioned a few ideas for further work based on that described above:

Since completing the above work, I have already made some progress on the first two of these topics. More on that in an upcoming post!

Research on the sustainability of participation in FSFE

Giacomo Poderi | 14:45, Monday, 16 April 2018

I’m a sociologist and I currently work as a researcher at IT University of Copenhagen, where I am responsible for “Infrastructuring SuStainable Playbour“ (ISSP): a project I received funding for from the EU/H2020 framework, under the Marie Skłodowska-Curie Action – Individual Fellowship fund.

This project investigates the sustainability of collaborative spaces, as commons, and it focuses on participants’ continuous contribution to the maintenance and development of such ‘places’.

The research involves three case studies, and . . . → Read More: Research on the sustainability of participation in FSFE

Thursday, 12 April 2018

Akademy 2018 hotel and flight booked!

TSDgeos' blog | 22:45, Thursday, 12 April 2018

I just booked my flights and hotel for Akademy 2018.

If you're planning to come you should too! [1]

You can find information about the recommended accommodation here.

See you in Viena!

[1] unless you're applying for sponsored travel+accommodation

Disconnecting from Facebook

Ramblings of a sysadmin (Posts about planet-fsfe) | 11:30, Thursday, 12 April 2018

About 5 months ago I moved away from Whatsapp (owned by Facebook) to Signal and today I moved away from Facebook itself. It has been on my to do list for a while already. Watching Zondag met Lubach this week gave me the final push to put my Facebook account removal at the top of my to do list. Arjen Lubach even created a Facebook event (quite funny) called "Bye Bye Facebook", which was scheduled for yesterday evening at 20.00. He stuck to his word and removed his own account. What made it funnier was that his event was not very easy to find using the search function, which usually works fine.

After a quick online search, I found the official help page "How do I permanently delete my account?". It refers to a "Download a copy of your info" page, which I did first (since generating this download might take a while). After having received the download link via e-mail and having downloaded my information, I followed the "Let us know" link to really remove my account.

The account removal dialog:

/img/posts/2018/04/12-disconnecting-from-facebook/permanently_delete_account_dialog.thumbnail.png

And the confirmation dialog:

/img/posts/2018/04/12-disconnecting-from-facebook/permanently_delete_account_confirmation.thumbnail.png

The top of my timeline (this morning). Strangely enough my "Bye Bye Facebook" post went missing. I'll just "assume" this was because I put a link to an event in there, which is in the past...

/img/posts/2018/04/12-disconnecting-from-facebook/timeline.thumbnail.png

Now I just have to wait 2 weeks and my account should "permanently" be deleted. Disconnecting from Facebook seems like a big deal, but really isn't. I still can be reached IRL (In Real Life), by sending me an e-mail or by messaging me (using Signal) or calling me. For reading news I still rely on my ttrss instance, luckily I've never used social media for that purpose.

If you are craving the social media experience and want privacy (yes, the two can be combined), I suggest you try (or look in to) the following:

They all offer the ability to join an existing instance or create one yourself. I'll be creating several for my friends and family, if they want me to ;-)

Tip: look through the details of the 'data export'. It creeped me out quite a bit. They were nice enough to make it easily readable and even made it into a simple website (index.html)

Wednesday, 11 April 2018

Tutorial: Writing your first view from scratch (C++20 / P0789)

Posts on Hannes Hauswedell's homepage | 11:45, Wednesday, 11 April 2018

C++17 was officially released last year and the work on C++20 quickly took off. A subset of the Concepts TS was merged and the first part of the Ranges TS has been accepted, too. Currently the next part of the Ranges TS is under review: “Range Adaptors and Utilities”. It brings the much-hyped “Views” to C++, but maybe you have been using them already via the Range-V3 library? In any case you might have wondered what you need to do to actually write your own view. This is the first in a series of blog posts describing complete view implementations (not just adaptations of existing ones).

Introduction (skip this if you have used views before)

Ranges are an abstraction of “a collection of items”, or “something iterable”. The most basic definition requires only the existence of begin() and end(), their comparability and begin being incrementable, but more refined range concepts add more requirements.

The ranges most commonly known are containers, e.g. std::vector. Containers are types of ranges that own the elements in the collection, but in this blog post we are more interested views.

What are views?

Views are ranges that usually (but not always!) performs an operation on another range. They are lazy-evaluated stateful algorithms on ranges that present their result again as a range. And they can be chained to combine different algorithms which can be done via the | operator like on the UNIX command line.

Ok, sounds cool, what does this mean in practice?

Well, you can, e.g. take a vector of ints, apply a view that computes the square of every element, and then apply a view that drops the first two elements:

1  std::vector<int> vec{1, 5, 6, 8, 5};
2  auto v = vec | view::transform([] (int const i) { return i*i; }) | view::drop(2);
3  std::cout << *std::begin(v) << '\n'; // prints '36'

And the point here is that only one “squaring-operation” actually happens and that it happens when we dereference the iterator, not before (because of lazy evaluation!).

What type is v? It is some implementation defined type that is guaranteed to satisfy certain range concepts: the View concept and the InputRange concept. The view concept has some important requirements, among them that the type is “light-weight”, i.e. copy’able in constant time. So while views appear like containers, they behave more like iterators.

If you are lost already, I recommend you check out some of the following resources

Prerequisites

The following sections assume you have a basic understanding of what a view does and have at least tried some of the toy examples yourself.

DISCLAIMER: Although I have been working with views and range-v3 for a while now, I am surprised by things again and again. If you think I missed something important in this article I would really appreciate feedback!

In general this post is aimed at interested intermediate C++ programmers, I try to be verbose with explanations and also provide many links for further reading.

You should have a fairly modern compiler to test the code, I test with GCC7 and Clang5 and compile with -std=c++17 -Wall -Wextra.

I refer to constraints and concepts in some of the examples. These are not crucial for the implementation so if they are entirely unfamiliar to you, just skip over them. If you use GCC on the other hand, you can uncomment the respective sections and add -fconcepts to your compiler call to activate them.

While the views we are implementing are self-contained and independent of the range-v3 library, you should get it now as some of our checks and examples require it.

And you should be curious of how to make your own view, of course 😄

Adapting existing views

Our task in this post is to write a view that works on input ranges of uint64_t and always adds the number 42, i.e. we want the following to work:

 1  int main()
 2  {
 3      std::vector<uint64_t> in{1, 4, 6, 89, 56, 45, 7};
 4 
 5      for (auto && i : in | view::add_constant)
 6          std::cout << i << ' ';
 7      std::cout << '\n'; // should print: 43 46 48 131 98 87 49
 8 
 9      // combine it with other views:
10      for (auto && i : in | view::add_constant | ranges::view::take(3))
11          std::cout << i << ' ';
12      std::cout << '\n'; // should print: 43 46 48
13  }

Most of the time it will be sufficient to adapt an existing view and whenever this is feasible it is of course recommended. So the recommended solution to the task is to just re-use ranges::view::transform:

 1  #include <iostream>
 2  #include <range/v3/view/transform.hpp>
 3  #include <range/v3/view/take.hpp>
 4 
 5  namespace view
 6  {
 7  auto const add_constant = ranges::view::transform([] (uint64_t const in)
 8                                                    {
 9                                                       return in + 42;
10                                                    });
11  }
12 
13  int main()
14  {
15      std::vector<uint64_t> in{1, 4, 6, 89, 56, 45, 7};
16 
17      for (auto && i : in | view::add_constant)
18          std::cout << i << ' ';
19      std::cout << '\n'; // should print: 43 47 64 131 98 87 49
20 
21      // combine it with other views:
22      for (auto && i : in | view::add_constant | ranges::view::take(3))
23          std::cout << i << ' ';
24      std::cout << '\n'; // should print: 43 47 64
25  }

As you can see, it’s very easy to adapt existing views!

But it’s not always possible to re-use existing views and the task was to get our hands dirty with writing our own view. The official manual has some notes on this, but while abstractions are great for code-reuse in a large library and make the code easier to understand for those that know what lies behind them, I would argue that they can also obscure the actual implementation for developers new to the code base who need to puzzle together the different levels of inheritance and template specialisation typical for C++ abstractions.

So in this post we will develop a view that does not depend on range-v3, especially not the internals.

The components of a view

What is commonly referred to as a view usually consists of multiple entities:

  1. the actual class (template) that meets the requirements of the View concept and at least also InputRange concept; by convention of the range-v3 library it is called view_foo for the hypothetical view “foo”.
  2. an adaptor type which overloads the () and | operators that facilitate the “piping” capabilities and return an instance of 1.; by convention of range-v3 it is called foo_fn.
  3. an instance of the adaptor class that is the only user-facing part of the view; by convention of range-v3 it is called foo, in the namespace view, i.e. view::foo.

If the view you are creating is just a combination of existing views, you may not need to implement 1. or even 2., but we will go through all parts now.

The actual implementation

preface

1 #include <range/v3/all.hpp>
2 #include <iostream>
3 
4 template <typename t>
5 using iterator_t = decltype(std::begin(std::declval<t &>()));
6 
7 template <typename t>
8 using range_reference_t = decltype(*std::begin(std::declval<t &>()));
  • As mentionend previously, including range-v3 is optional, we only use it for concept checks – and in production code you will want to select concrete headers and not “all”.
  • The iterator_t metafunction retrieves the iterator type from a range by checking the return type of begin().
  • The range_reference_t metafunction retrieves the reference type of a range which is what you get when dereferencing the iterator. It is only needed in the concept checks. 1
  • Both of these functions are defined in the range-v3 library, as well, but I have given minimal definitions here to show that we are not relying on any sophisticated magic somewhere else.

view_add_constant

We start with the first real part of the implementation:

1 template <typename urng_t>
2 //     requires (bool)ranges::InputRange<urng_t>() &&
3 //              (bool)ranges::CommonReference<range_reference_t<urng_t>, uint64_t>()
4 class view_add_constant : public ranges::view_base
5 {
  • view_add_constant is a class template, because it needs to hold a reference to the underlying range it operates on; that range’s type urng_t is passed in a as template parameter.
  • If you use GCC, you can add -fconcepts and uncomment the requires-block. It enforces certain constraints on urng_t, the most basic constraint being that it is an InputRange. The second constraint is that the underlying range is actually a range over uint64_t (possibly with reference or const).
  • Please note that these constraints are specific to the view we are just creating. Other views will have different requirements on the reference type or even the range itself (e.g. it could be required to satisfy RandomAccessRange).
  • We inherit from view_base which is an empty base class, because being derived from it signals to some library checks that this class is really trying to be a view (which is otherwise difficult to detect sometimes); in our example we could also omit it.
1 private:
2     /* data members == "the state" */
3     struct data_members_t
4     {
5         urng_t urange;
6     };
7     std::shared_ptr<data_members_t> data_members;
  • The only data member we have is (the reference to) the original range. It may look like we are saving a value here, but depending on the actual specialisation of the class template, urng_t may also contain & or const &.
  • Why do we put the member variables inside an extra data structure stored in a smart pointer? A requirement of views is that they be copy-able in constant time, e.g. there should be no expensive operations like allocations during copying. An easy and good way to achieve implicit sharing of the data members is to put them inside a shared_ptr. Thereby all copies share the data_members and they get deleted with the last copy. 2
  • In cases where we only hold a reference, this is not strictly required, but in those cases we still benefit from the fact that storing the reference inside the smart pointer makes our view default-constructible. This is another requirement of views – and having a top-level reference member prevents this. [Of course you can use a top-level pointer instead of a reference, but we don’t like raw pointers anymore!]
  • Other more complex views have more variables or “state” that they might be saving in data_members.
 1     /* the iterator type */
 2     struct iterator_type : iterator_t<urng_t>
 3     {
 4         using base = iterator_t<urng_t>;
 5         using reference = uint64_t;
 6 
 7         iterator_type() = default;
 8         iterator_type(base const & b) : base{b} {}
 9 
10         iterator_type operator++(int)
11         {
12             return static_cast<base&>(*this)++;
13         }
14 
15         iterator_type & operator++()
16         {
17             ++static_cast<base&>(*this);
18             return (*this);
19         }
20 
21         reference operator*() const
22         {
23             return *static_cast<base>(*this) + 42;
24         }
25     };
  • Next we define an iterator type. Since view_add_constant needs to satisfy basic range requirements, you need to be able to iterate over it. In our case we can stay close to the original and inherit from the original iterator.
  • For the iterator to satisfy the InputIterator concept we need to overload the increment operators so that their return type is of our class and not the base class. The important overload is that of the dereference operation, i.e. actually getting the value. This is the place where we interject and call the base class’s dereference, but then add the constant 42. Note that this changes the return type of the operation (::reference); it used to be uint64_t & (possibly uint64_t const &), now it’s uint64_t → A new value is always generated as the result of adding 42.
  • Note that more complex views might require drastically more complex iterators and it might make sense to define those externally. In general iterators involve a lot of boilerplate code, depending on the scope of your project it might make sense to add your own iterator base classes. Using CRTP also helps re-use code and reduce “non-functional” overloads.

We continue with the public interface:

1 public:
2     /* member type definitions */
3     using reference         = uint64_t;
4     using const_reference   = uint64_t;
5     using value_type        = uint64_t;
6 
7     using iterator          = iterator_type;
8     using const_iterator    = iterator_type;
  • First we define the member types that are common for input ranges. Of course our value type is uint64_t as we only operate on ranges over uint64_t and we are just adding a number. As we mentioned above, our iterator will always generate new values when dereferenced so the reference types are also value types.
  • Note: Other view implementation might be agnostic of the actual value type, e.g. a view that reverses the elements can do so independent of the type. AND views might also satisfy OutputRange, i.e. they allow writing to the underlying range by passing through the reference. To achieve this behaviour you would write using reference = range_reference_t<urng_t>;. The value type would then be the reference type with any references stripped (using value_type = std::remove_cv_t<std::remove_reference_t<reference>>;).
  • The iterator type is just the type we defined above.
  • In general views are not required to be const-iterable, but if they are the const_iterator is the same as the iterator and const_reference is the same as reference. 3
 1     /* constructors and deconstructors */
 2     view_add_constant() = default;
 3     constexpr view_add_constant(view_add_constant const & rhs) = default;
 4     constexpr view_add_constant(view_add_constant && rhs) = default;
 5     constexpr view_add_constant & operator=(view_add_constant const & rhs) = default;
 6     constexpr view_add_constant & operator=(view_add_constant && rhs) = default;
 7     ~view_add_constant() = default;
 8 
 9     view_add_constant(urng_t && urange)
10         : data_members{new data_members_t{std::forward<urng_t>(urange)}}
11     {}
  • The constructors are pretty much standard. We have an extra constructor that initialises our urange from the value passed in. Note that this constructor covers all cases of input types (&, const &, &&), because more attributes can be stuck in the actual urng_t and because of reference collapsing.
 1     /* begin and end */
 2     iterator begin() const
 3     {
 4         return std::begin(data_members->urange);
 5     }
 6     iterator cbegin() const
 7     {
 8         return begin();
 9     }
10 
11     auto end() const
12     {
13         return std::end(data_members->urange);
14     }
15 
16     auto cend() const
17     {
18         return end();
19     }
20 };
  • Finally we add begin() and end(). Since we added a constructor for this above, we can create our view’s iterator from the underlying range’s iterator implicitly when returning from begin().
  • For some ranges the sentinel type (the type returned by end()) is not the same as the type returned by begin(), this is only true for BoundedRanges; the only requirement is that the types are comparable with == and !=. We need to take this into account here, that’s why the end function returns auto and not the iterator (the underlying sentinel is still comparable with our new iterator, because it inherits from the underlying range’s iterator).
  • As noted above, some views may not be const-iterable, in that case you can omit cbegin() and cend() and not mark begin() and end() as const.
  • Note that if you want your view to be stronger that an InputRange, e.g. also be a SizedRange or even a RandomAccessRange, you might want to define additional member types (size_type, difference_type) and additional member functions (size(), operator[]…). *Although strictly speaking the range “traits” are now deduced completely from the range’s iterator so you don’t need additional member functions on the range.*
1 template <typename urng_t>
2 //     requires (bool)ranges::InputRange<urng_t>() &&
3 //              (bool)ranges::CommonReference<range_reference_t<urng_t>, uint64_t>()
4 view_add_constant(urng_t &&) -> view_add_constant<urng_t>;
  • We add a user-defined type deduction guide for our view.
  • Class template argument deduction enables people to use your class template without having to manually specify the template parameter.
  • In C++17 there is automatic deduction, as well, but we need user defined deduction here, if we want to cover both cases of urng_t (value tpye and reference type) and don’t want to add more complex constructors.
1 static_assert((bool)ranges::InputRange<view_add_constant<std::vector<uint64_t>>>());
2 static_assert((bool)ranges::View<view_add_constant<std::vector<uint64_t>>>());
  • Now is a good time to check whether your class satisfies the concepts it needs to meet, this also works on Clang without the Concepts TS or C++20. We have picked std::vector<uint64_t> as an underlying type, but others would work, too.
  • If the checks fail, you have done something wrong somewhere. The compilers don’t yet tell you why certain concept checks fail (especially when using the range library’s hacked concept implementation) so you need to add more basic concept checks and try which ones succeed and which break to get hints on which requirements you are failing. A likely candidate is your iterator not meeting the InputIterator concept (old, but complete documentation).

add_constant_fn

Off to our second type definition, the functor/adaptor type:

 1 struct add_constant_fn
 2 {
 3     template <typename urng_t>
 4 //         requires (bool)ranges::InputRange<urng_t>() &&
 5 //                  (bool)ranges::CommonReference<range_reference_t<urng_t>, uint64_t>()
 6     auto operator()(urng_t && urange) const
 7     {
 8         return view_add_constant{std::forward<urng_t>(urange)};
 9     }
10 
11     template <typename urng_t>
12 //         requires (bool)ranges::InputRange<urng_t>() &&
13 //                  (bool)ranges::CommonReference<range_reference_t<urng_t>, uint64_t>()
14     friend auto operator|(urng_t && urange, add_constant_fn const &)
15     {
16         return view_add_constant{std::forward<urng_t>(urange)};
17     }
18 
19 };
  • The first operator facilitates something similar to the constructor, it enables traditional usage of the view in the so called function-style: auto v = view::add_constant(other_range);.
  • The second operator enables the pipe notation: auto v = other_range | view::add_constant;. It needs to be friend or a free function and takes two arguments (both sides of the operation).
  • Both operators simply delegate to the constructor of view_add_constant.

view::add_constant

Finally we add an instance of the adaptor to namespace view:

1 namespace view
2 {
3 
4 add_constant_fn constexpr add_constant;
5 
6 }

Since the adapter has no state (in contrast to the view it generates), we can make it constexpr. You can now use the adaptor in the above example.

We are done 😊

Here is the full code: view_add_constant.cpp

Post scriptum

I will follow up on this with a second tutorial, it will cover writing a view that takes arguments, i.e.

1 std::vector<uint64_t> in{1, 4, 6, 89, 56, 45, 7};
2 auto v = in | view::add_number(42);
3 // decide this at run-time     ^

If you found mistakes (of which I am sure there are some) or if you have questions, please comment below via GitHub, Gitea, Twitter or Mastodon!


  1. If you are confused that we are dealing with the “reference type” and not the “value type”, remember that member functions like at() and operator[] on plain old containers also always return the ::reference type.
  2. This is slightly different than in range-v3 where views only accept temporaries of other views, not of e.g. containers (containers can only be given as lvalue-references). This enables constant time copying of the view even without implicit sharing of the underlying range, but it mandates a rather complicated set of techniques to tell apart views from other ranges (the time complexity of a function is not encoded in the language so tricks like inheriting ranges::view are used). I find the design used here more flexible and robust.
  3. This might be confusing to wrap your head around, but remember that the const_iterator of a container is like an iterator over the const version of that container. The same is true for views, except that since the view does not own the elements its own const-ness does not “protect” the elements from being written to. Ranges behave similar to iterators in this regard, an iterator const on a vector can also be used to write to the value it points to. More on this in this range-v3 issue.

Thursday, 05 April 2018

Surveillance Valley – a review

agger's Free Software blog | 14:26, Thursday, 05 April 2018

Note: This post is a book review. I did not buy this book on Amazon, and if, after reading this post, you consider buying it, I strongly urge you not to buy it on Amazon. Amazon is a proprietary software vendor and, more importantly, a company with highly problematic business and labour practices. They should clean up their act and, failing that, we should all boykot them. 

Most of us have heard that the Internet started as a research project initiated by the ARPA, the Advanced Research Projects Agency, an agency under the US military conducting advanced research, especially focusing on counter-insurgency and future war scenarios. A common version of this story is that the Internet was originally intended to be a decentralized network, a network with no central hub necessary for its operation, where individual nodes might be taken out without disrupting the traffic, which would just reroute itself through other nodes. A TCP/IP network may indeed work like that, but the true origins of the Internet are far darker.

In the 1940′s and 50′s, Norbert Wiener’s theory of cybernetics became very popular. Wiener was a mathematician who worked for the American military during WWII. The gist of cybernetics is that all systems maintain themselves through feedback between their elements. If one could understand the nature of the feedback that keeps them stable, one could predict their future behaviour. The beauty of this theory is that systems could consist of human beings and machines, and it did not in fact matter if a given element was one or the other; as the systems were supposed to stabilize naturally just like ecosystems, it should be possible to set down mathematical equations they’d need to fulfill to serve their role in the system.

This theory was criticized, in fact even by Wiener himself, for reducing human beings to machines; and the analogy to ecosystems has proven false, as later biological research has shown that ecosystems do not tend to become stable – in fact, they are in constant change. In the 50s, however, this theory was very respected, and ARPA wanted to utilize it for counterinsurgency in Asian countries. For that purpose, they started a detailed anthropological study of tribes in Thailand, recording the people’s physical traits as well as a lot of information about their culture, habits and overall behaviour. The intention was to use this information in cybernetic equations in order to be able to predict people’s behaviour in wars like the Korea or, later, the Vietnam war.

In order to do this, they needed computation power – a lot of it. After the Soviets sent up the Sputnik and beat the Americans to space, there was an extraordinary surge of investments in scientific and engineering research, not least into the field of computers. In the early 60′s, psychologist and computer scientist J.R.C. Licklider proposed “The Intergalactic Network” as a way to provide sufficient computation power for the things that ARPA wanted to do – by networking the computers, so problems might be solved by more computers than the user was currently operating. In doing so, Licklider predicted remote execution, keyboard-operated screens as well as a network layout that was practically identical to (if much smaller than) the current Internet. Apart from providing the power to crunch the numbers needed to supposedly predict the behaviour of large populations for counterinsurgency purposes, the idea that such a network could be used for control and surveillance materialized very early.

In the 1990s, the foundations of the company currently known as Google was created in Stanford Research Institute, a university lab that had for decades been operating as a military contractor. The algorithmic research that gave us the well-known Page Rank algorithm was originally funded by grants from the military.

From the very beginning, Google’s source of income was mining the information in its search log. You could say that from the very beginning, Google’s sole business model has been pervasive surveillance, dividing its users into millions of buckets in order to sell as fine-tuned advertising as possible.

At the same time, Google has always been a prolific military contractor, selling upgraded versions of all kinds of applications to help the US military fight their wars. As an example, Google Earth was originally developed by Keyhole, Inc. with military purposes in mind – the military people loved the video game-like interface, and the maps and geographical features could be overlaid with all kinds of tactical information about targets and allieds in the area.

More controversially, the Tor project, the free software project so lauded by the Internet Freedom and privacy communities, is not what it has consistently described itself as. It is commonly known that it was originally commissioned by a part of the US Navy as an experimental project for helping their intelligence agents stay anonymous, but it is less known that Tor has, since its inception, been almost exclusively financed by the US government, among others through grants from the Pentagon and the CIA but mainly by BBG, the “Broadcasting Board of Governors”, which originated in the CIA.

The BBG’s original mission was to run radio stations like Voice of America and, more recently, Radio Free Asia, targeting the populations of countries that were considered military enemies of the US. Among other things, BBG has been criticized for simply being a propaganda operation, a part of a hostile operation against political adversaries:

Wherever we feel there is an ideological enemy, we’re going to have a Radio Free Something (…) They lean very heavily on reports by and about dissidents in exile. It doesn’t sound like reporting about what’s going on in a country. Often, it reads like a textbook on democracy, which is fine, but even to an American it’s rather propagandistic.

One could ask, what kind of interest could the BBG possibly have in privacy activism such as that supposedly championed by the Tor project? None, of course. But they might be interested in providing dissidents in hostile countries with a way to avoid censorship, maybe even to plot rebellion without being detected by the regime’s Internet surveillance. Radio Free Asia had for years been troubled by the Chinese government’s tendency to block their transmission frequencies. Maybe Tor could be used to blast a hole in the Great Chinese Firewall?

At the same time, Tor could be used by operatives from agencies like the CIA, the NSA or the FBI to hide their tracks when perusing e.g. Al Qaeda web sites.

But, if the US government promotes this tool to dissidents in Russia, China or Iran as a creation of the US government – why would they trust it? And, if an Al Qaeda site suddenly got a spike of visitors all using Tor – maybe they’d figure it out anyway, if Tor was known as a US government tool? Wouldn’t it be nice if millions of people used Tor because they thought they were “sticking it to the man” and “protecting their privacy”, giving legitimacy with respect to the dissidents and cover to the agents?

And so, Tor the Privacy Tool was born. People were told that if they used Tor and were careful, it was cryptographically impossible that anyone should know which sites they were visiting. Except for the fact that Tor has all the time had serious (unintentional) weaknesses which meant that hidden services might have their IP exposed and web site visitors might, with some probability, be identified even if they were using Tor correctly. And using Tor correctly is already very difficult.

Yes, someone like Edward Snowden who knew about its weaknesses and had considerable insight into its security issues could indeed use Tor safely to perform his leaks and communicate about them, for a short while. But advising people in repressive societies with no technical insight who may have their lives at stake doing really serious things to rely on this tool might be … completely irresponsible. Like sending someone in battle with a wooden toy gun.

And maybe, just maybe, the American government was happy enough letting these pesky privacy activists run around with their wooded toy gun, courtesy of Uncle Sam, instead of doing something stupid like demanding effective regulations. And who better to evangelize this wooden toy gun but Jacob Appelbaum, the now-disgraced Tor developer who toured the world pretending to “stick it to the Man”, all the while working for a military contractor and netting a $100,000 paycheck directly from the American government? Maybe, in that sense, Tor as a privacy tool was always worse than nothing.

These are just a few of the topics covered in Yasha Levine’s new book Surveillance Valley. Levine’s idea is to cover the military roots of the modern computer industry, and he does that in gory and unsettling detail.  Apart from cybernetics, ARPA, Google and Tor he also covers the influence of cybernetics on the counterculture and its later history of WIRED magazine and the Californian ideology. It also offers a critical examination of the consequences of Edward Snowden’s leaks.

This is not a flawless book; Levine has a point he wishes to get through, and in order to get there, he occasionally resorts “hatchet job” journalism, painting people’s motives in an artificially unfavourable light or not researching his accusations thoroughly enough. For instance, Levine accuses Dingledine and the Tor project of giving vulnerabilities to the government for possible exploitation before making them public. The example he gives to prove that assertion is wrong, and I guess he makes the mistake because his eagerness to nail them made him sloppy, and because Levine himself lacks the technical expertise to see why the vulnerability he mentions (TLS normalization, detectability of Tor traffic) couldn’t possibly have been unknown to others at the time.

But, apart from that, I wholeheartedly recommend the book. It tells a story about Silicon Valley that really isn’t told enough, and it points out some really unpleasant – but, alas, all too true – aspects of the technology that we have all come to depend on. Google, the “cool” and “progressive” do-good-company, in fact a military contractor that helps American drones kill children in Yemen and Afghanistan? As well as a partner in predictive policing and a collector of surveillance data that the NSA may yet try to use to control enemy populations in a Cybernetics War 2.0? The Tor Project as paid shills of the belligerent US foreign policy? And the Internet itself, that supposedly liberating tool, was originally conceived as a surveillance and control mechanism?

Yes, unfortunately – in spite of the book’s flaws, true on all counts. For those of us who love free software because we love freedom itself, that should be an eyeopener.

Nested Loops in Ansible

Evaggelos Balaskas - System Engineer | 10:09, Thursday, 05 April 2018

Recently I needed to create a Nested Loop in Ansible. One of the possible issues I had to consider, was the backward compatibility with both Ansible v1 and Ansible v2. A few days after, Ansible 2.5 introduced the the loop keyword and you can read a comprehensive blog entry here: Loop: Plays in the future, items in the past.

So here are my notes on the subject:

Variables

Below is a variable yaml file for testing purposes:

vars.yml

---
  days:
  - Monday
  - Tuesday
  - Wednesday
  - Thursday
  - Friday
  - Saturday
  - Sunday
  months:
  - January
  - February
  - March
  - April
  - May
  - June
  - July
  - August
  - September
  - October
  - November
  - December

Ansible v1

Let’s start with Ansible v1:

# ansible --version
ansible 1.9.6
  configured module search path = None

Playbook

Below a very simple ansible-playbook example that supports nested loops:

---
- hosts: localhost
  gather_facts: no

  vars_files:
    - vars.yml

  tasks:
   - name: "This is a simple test"
     debug:
       msg: "Day: {{ item[0] }} exist in Month: {{ item[1] }}"
     with_nested:
       - "{{ days }}"
       - "{{ months }}"

This playbook doesnt do much.
Prints a message for every day and every month.

Ansible-Playbook

Run locally the playbook by:

# ansible-playbook nested.yml -c local -l localhost -i "localhost," 

the output:

PLAY [localhost] ****************************** 

TASK: [This is a simple test] *****************
ok: [localhost] => (item=['Monday', 'January']) => {
    "item": [
        "Monday",
        "January"
    ],
    "msg": "Day: Monday exist in Month: January"
}
...
ok: [localhost] => (item=['Sunday', 'December']) => {
    "item": [
        "Sunday",
        "December"
    ],
    "msg": "Day: Sunday exist in Month: December"
}

PLAY RECAP *************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0

Messages

There are seven (7) days and twelve (12) months, so the output must print: 7*12 = 84 messages.

Counting the messages:

# ansible-playbook nested.yml -c local -l localhost -i "localhost," | egrep -c msg

84

Time

Measuring the time it needs to pass through the nested-loop:

time ansible-playbook nested.yml -c local -l localhost -i "localhost," &> /dev/null 
real 0m0.448s
user 0m0.406s
sys  0m0.040s

0.448s nice!

Ansible v2

Running the same playbook in latest ansible:

# ansible-playbook nested.yml -c local -l localhost

seems to still work!

Compatibility issues: Resolved!

Counting the messages

# ansible-playbook nested.yml | egrep -c msg

84

Time

# time ansible-playbook nested.yml &> /dev/null 
real 0m7.396s
user 0m7.575s
sys  0m0.172s

7.396s !!!

that is 7seconds more than ansible v1.

Complex Loops

The modern way, is to use the loop keyword with the nested lookup plugin:

---
- hosts: localhost
  gather_facts: no

  vars_files:
    - vars.yml

  tasks:
   - name: "This is a simple test"
     debug:
       msg: "Day: {{ item[0] }} exist in Month: {{ item[1] }}"
     loop: "{{ lookup('nested', days, month) }}"

Time

# time ansible-playbook lookup_loop.yml &> /dev/null 
real 0m7.975s
user 0m8.169s
sys  0m0.177s

7.623s

Tag(s): ansible

Tuesday, 03 April 2018

How to run Ansible2.5 on CentOS 5

Evaggelos Balaskas - System Engineer | 13:35, Tuesday, 03 April 2018

[notes based on a docker centos5]

# cat /etc/redhat-release

CentOS release 5.11 (Final)

Setup Enviroment

Install compiler:

# yum -y install gcc make

Install zlib headers:

# yum -y install zlib-devel

Install tools:

# yum -y install curl unzip

SSL/TLS Errors

If you are on a CentOS 5x machine, when trying to download files from the internet, you will get this error msg:

This is a brown out of TLSv1 support. TLSv1 support is going away soon, upgrade to a TLSv1.2+ capable client.

or

SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

that is because CentOS 5x has an old cipher suite that doesnt work with today’s standards.

OpenSSL

To bypass these SSL/TLS errors, we need to install a recent version of openssl.

# cd /root/

# curl -LO https://www.openssl.org/source/openssl-1.0.2o.tar.gz
# tar xf openssl*.tar.gz
# cd openssl*

# ./Configure shared linux-x86_64
# make
# make install

The output has a useful info:

OpenSSL shared libraries have been installed in:
  /usr/local/ssl

So, we have to update the system’s library paths, to include this one:

# echo "/usr/local/ssl/lib/" >> /etc/ld.so.conf
# /sbin/ldconfig

Python 2.7

Download the latest Python2.7

# cd /root/
# curl -LO https://www.python.org/ftp/python/2.7.14/Python-2.7.14.tgz
# tar xf Python*.tgz
# cd Python*

Install Python:

# ./configure --prefix=/opt/Python27 --enable-shared
# make
# make install

PATH

# export PATH=/opt/Python27/bin/:$PATH

# python -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 1.0.2o  27 Mar 2018

SetupTools

Download the latest setuptools

# cd /root/

# export PYTHONHTTPSVERIFY=0
# python -c 'import urllib; urllib.urlretrieve ("https://pypi.python.org/packages/72/c2/c09362ab29338413ab687b47dab03bab4a792e2bbb727a1eb5e0a88e3b86/setuptools-39.0.1.zip", "setuptools-39.0.1.zip")'

Install setuptools

# unzip setuptools*.zip
# cd setuptools*

# python2.7 setup.py build
# python2.7 setup.py install

PIP

Install PIP

# cd /root/

# easy_install pip

Searching for pip
Reading https://pypi.python.org/simple/pip/
Downloading https://pypi.python.org/packages/4b/5a/8544ae02a5bd28464e03af045e8aabde20a7b02db1911a9159328e1eb25a/pip-10.0.0b1-py2.py3-none-any.whl#md5=34dd54590477e79bc681d9ff96b9fd39
Best match: pip 10.0.0b1
Processing pip-10.0.0b1-py2.py3-none-any.whl
Installing pip-10.0.0b1-py2.py3-none-any.whl to /opt/Python27/lib/python2.7/site-packages
writing requirements to /opt/Python27/lib/python2.7/site-packages/pip-10.0.0b1-py2.7.egg/EGG-INFO/requires.txt
Adding pip 10.0.0b1 to easy-install.pth file
Installing pip script to /opt/Python27/bin
Installing pip3.6 script to /opt/Python27/bin
Installing pip3 script to /opt/Python27/bin

Installed /opt/Python27/lib/python2.7/site-packages/pip-10.0.0b1-py2.7.egg
Processing dependencies for pip
Finished processing dependencies for pip

Ansible

Now, we are ready to install ansible

# pip install ansible

Collecting ansible

/opt/Python27/lib/python2.7/site-packages/pip-10.0.0b1-py2.7.egg/pip/_vendor/urllib3/util/ssl_.py:339: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  SNIMissingWarning
  Using cached ansible-2.5.0-py2.py3-none-any.whl
Collecting paramiko (from ansible)
  Using cached paramiko-2.4.1-py2.py3-none-any.whl
Collecting cryptography (from ansible)
  Using cached cryptography-2.2.2-cp27-cp27m-manylinux1_x86_64.whl
Requirement already satisfied: setuptools in /opt/Python27/lib/python2.7/site-packages/setuptools-39.0.1-py2.7.egg (from ansible) (39.0.1)
Collecting PyYAML (from ansible)
  Using cached PyYAML-3.12.tar.gz
Collecting jinja2 (from ansible)
  Using cached Jinja2-2.10-py2.py3-none-any.whl
Collecting pyasn1>=0.1.7 (from paramiko->ansible)
  Using cached pyasn1-0.4.2-py2.py3-none-any.whl
Collecting bcrypt>=3.1.3 (from paramiko->ansible)
  Using cached bcrypt-3.1.4-cp27-cp27m-manylinux1_x86_64.whl
Collecting pynacl>=1.0.1 (from paramiko->ansible)
  Using cached PyNaCl-1.2.1-cp27-cp27m-manylinux1_x86_64.whl
Collecting six>=1.4.1 (from cryptography->ansible)
  Using cached six-1.11.0-py2.py3-none-any.whl
Collecting cffi>=1.7; platform_python_implementation != "PyPy" (from cryptography->ansible)
  Using cached cffi-1.11.5-cp27-cp27m-manylinux1_x86_64.whl
Collecting enum34; python_version < "3" (from cryptography->ansible)
  Using cached enum34-1.1.6-py2-none-any.whl
Collecting asn1crypto>=0.21.0 (from cryptography->ansible)
  Using cached asn1crypto-0.24.0-py2.py3-none-any.whl
Collecting idna>=2.1 (from cryptography->ansible)
  Using cached idna-2.6-py2.py3-none-any.whl
Collecting ipaddress; python_version < "3" (from cryptography->ansible)
  Using cached ipaddress-1.0.19.tar.gz
Collecting MarkupSafe>=0.23 (from jinja2->ansible)
  Using cached MarkupSafe-1.0.tar.gz
Collecting pycparser (from cffi>=1.7; platform_python_implementation != "PyPy"->cryptography->ansible)
  Using cached pycparser-2.18.tar.gz
Installing collected packages: pyasn1, six, pycparser, cffi, bcrypt, enum34, asn1crypto, idna, ipaddress, cryptography, pynacl, paramiko, PyYAML, MarkupSafe, jinja2, ansible
  Running setup.py install for pycparser ... done
  Running setup.py install for ipaddress ... done
  Running setup.py install for PyYAML ... done
  Running setup.py install for MarkupSafe ... done

Successfully installed MarkupSafe-1.0 PyYAML-3.12 ansible-2.5.0 asn1crypto-0.24.0 bcrypt-3.1.4 cffi-1.11.5 cryptography-2.2.2 enum34-1.1.6 idna-2.6 ipaddress-1.0.19 jinja2-2.10 paramiko-2.4.1 pyasn1-0.4.2 pycparser-2.18 pynacl-1.2.1 six-1.11.0

Version

# ansible --version

ansible 2.5.0
  config file = None
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/Python27/lib/python2.7/site-packages/ansible
  executable location = /opt/Python27/bin/ansible
  python version = 2.7.14 (default, Mar 31 2018, 20:00:21) [GCC 4.1.2 20080704 (Red Hat 4.1.2-55)]

Ansible v2

# ansible -m ping localhost


localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Ansible v1

or a previous version for testing

eg. 1.9.6

# pip install 'ansible==1.9.6'

# ansible --version

ansible 1.9.6
  configured module search path = None

# yum -y install python-simplejson

# ansible localhost -c local -m ping -i "localhost,"

localhost | success >> {
    "changed": false,
    "ping": "pong"
}

Possible Building Error

When building python from source, setup.py will try to look for /usr/local/ssl/ directory to find the libraries and included headers of openssl. Althouth it works from _ssl.c , it doesnt for _hashlib.c.

To fix this problem, you must manual edit the Python-2.7.14/setup.py

 869                 ssl_incs += ['/usr/local/ssl/include']
 870                 ssl_libs += ['/usr/local/ssl/lib']

the full code is:

 865         if have_any_openssl:
 866             if have_usable_openssl:
 867                 # The _hashlib module wraps optimized implementations
 868                 # of hash functions from the OpenSSL library.
 869                 ssl_incs += ['/usr/local/ssl/include']
 870                 ssl_libs += ['/usr/local/ssl/lib']
 871                 exts.append( Extension('_hashlib', ['_hashopenssl.c'],
 872                                        include_dirs = ssl_incs,
 873                                        library_dirs = ssl_libs,
 874                                        libraries = ['ssl', 'crypto']) )
 875             else:
 876                 print ("warning: openssl 0x%08x is too old for _hashlib" %
 877                        openssl_ver)
 878                 missing.append('_hashlib')

hope that helps!

Monday, 02 April 2018

Looking for a secure smartphone running only free software? Good luck!

Daniel's FSFE blog | 15:07, Monday, 02 April 2018

Motivation

On many occasions, I have seen myself and other members of the FSFE being asked which smartphones and mobile operating systems they can recommend to users who are looking for a free (owner-controlled) and secure smartphone that respects their freedom and privacy. I would like to share some of my thoughts about this complex topic. Please be warned, that it might be disappointing for those who might expect to get clear recommendations in the conclusion.

Operating Systems

In the following I want to briefly discussing pros and cons of a few mostly free mobile operating systems (skipping completely proprietary systems like iOS or Windows Phone). Mostly dead projects like B2G/FirefoxOS or Ubuntu Phone are not discussed either.

Stock Android

This is the binary Android distribution from Google and comes pre-installed on Google/Pixel devices.

  • Verified boot with locked bootloaders (but you have to trust the vendor)
  • Regular updates, once per month, available directly from upstream
  • Only available for Nexus/Pixel devices
  • Limited support period (18 months for Nexus devices, 3 years for Pixel devices) but clearly communicated
  • All supported devices require vast amounts of binary-only, proprietary firmware
  • Google Apps and Services are pre-installed and not removable.
  • Standard Android Security
  • Vendor-modified Android

    This is the Android distribution from typical OEMs like Samsung, HTC, LG, Sony, Huawei etc. that is based on Stock Android and customized by the OEM and in case of “branded” devices also by the network operator.

  • Ultimate choice of devices
  • Verified boot with locked bootloaders (but you have to trust the OEM), at least for most devices
  • Google Apps and Services are pre-installed and not removable.
  • Updates highly dependant on the OEM; often irregular, delayed or incomplete, sometimes no updates at all
  • Additional customizations by network operators often lead to further delayed updates
  • Often unclear support periods (depending on the vendor) and no formal EOL declaration
  • Almost all devices require binary-only, proprietary firmware (a few devices require not that much firmware, but most devices require a lot)
  • Standard Android Security
  • In many cases, the whole distribution is not directly available as a “factory image” from the vendor (depends on the vendor, but most of them do not provide such downloads). In most cases, flashing requires non-free software by the OEM that in turn only runs on non-free operating Systems such as Windows or OS X.
  • AOSP

    This is the source distribution of Android from Google.

  • Does not include Google Apps and Services
  • Regular updates, once per month, usually released shortly after new Stock Android builds
  • Limited support period (18 months for Nexus devices, 3 years for Pixel devices) but clearly communicated
  • Has to be self-compiled by the user (instructions only available for Nexus/Pixel devices as well as few 3rd party devices, e.g. some from Sony)
  • Verified boot with locked bootloaders and user-supplied keys (but only on Nexus/Pixel devices)
  • Almost all supported devices require vast amounts of binary-only, proprietary firmware
  • Copperhead OS

    A custom Android distribution provided by a community-oriented company. Based on AOSP with a strong focus on security.

  • Does not include Google Apps and Services
  • Some apps from AOSP have been replaced by more privacy-oriented alternatives (e.g. the calendar).
  • Much more than standard Android security: Hardened kernel and userland, privacy-friendly defaults
  • Binary downloads on website only for Nexus/Pixel devices and a development board
  • Regular updates, once per month (vendor promises to make them available within 24 hours after updates in AOSP became available)
  • Limited support period (18 months for Nexus devices, 3 years for Pixel devices) but clearly communicated
  • Verified boot with locked bootloaders and user-supplied keys (but only on Nexus/Pixel devices)
  • All supported smartphones require vast amounts of binary-only, proprietary firmware (the Hikey 960 does not, but it is not a smartphone)
  • All modifications are open source, but commercial redistribution is prohibited. Thus, the FSFE would not consider it free software.
  • Lineage OS

    A custom Android distribution based on AOSP but with heavy modifications. Developed by a large community of volunteers.

  • Does not include Google Apps and Services by default
  • Regular updates, but security patches are sometimes delayed or incomplete
  • Verified boot with locked bootloaders and user-supplied keys (but only on Nexus/Pixel devices) theoretically possible (but afaik no official instructions provided)
  • Backports security patches to Android versions which are not supported by Google anymore (but not forever)
  • Supports devices that are EOL by their original vendors since years, however, actual support period by LineageOS is not clear in advance and official EOL has often not been clearly communicated in the past.
  • Lower security than on standard Android due to userdebug builds by default
  • Broad support for a huge number of devices
  • All supported devices require binary-only, proprietary firmware (a few devices require not that much non-free firmware, but most devices require a lot)
  • OmniROM

    A custom Android distribution based on AOSP with moderate modifications. Developed by a community of volunteers.

  • Similar to Lineage OS with respect to the discussed properties
  • Slightly higher security because uses “eng” builds by default
  • Limited device support
  • Provides security updates usually only for the most recent branch
  • Replicant

    A custom Android distribution based on Lineage OS 13. Developed by very few community volunteers but strongly backed by many free software enthusiasts.

  • Does not include Google Apps and Services by default
  • Irregular updates, security patches are heavily delayed
  • All supported devices run completely without binary-only, proprietary firmware on the main processor (but on no device functionality such as GPS, Bluetooth, 3D acceleration is available and Wifi works only with one selected model of external USB adapters). Non-free firmware for baseband processor is still required.
  • None of the supported devices supports verified boot (all require an unlocked bootloader)
  • Even with a closed bootloader, many of the supported devices have severe security issues (e.g. storage is directly accessible via the insecure odin protocol)
  • postmarketOS

    A “classic” Linux distribution targeted also on legacy smartphones vastly considered obsolete. Developed by volunteeers. Based on Alpine Linux, thus very lightweight.

  • Nice and clear architectural design
  • Classic distro packages instead of app store
  • Not really useable yet, under heavy development
  • Regular updates, just like a normal Linux distribution
  • Choice between several UIs (most promising to me: Plasma Mobile), however, none of them seems Production-ready yet
  • Partial support for a large number of devices, but not a single device seems ready for daily usage as a smartphone
  • Verified boot with locked bootloaders and user-supplied keys theoretically possible (only on Nexus/Pixel devices) but afaik not implemented yet.
  • pureOS

    (I have no personal experience with this OS, thus the following information is just from my research)

    Another “classic” Linux distribution but primarily targeted at “Librem” devices by purism. Based on Debian Testing.

  • Convergence approach
  • Under heavy development, not available yet for phones
  • Support for GNOME and KDE Plasma Mobile planned
  • No information about planned support period available yet
  • Nothing concrete known about security features such as verified boot yet
  • Sailfish OS

    (I have no personal experience with this OS, thus the following information is just from my research)

    A Linux-based operating system that supports Android apps through an compatibility layer. Has an open core but a closed source UI that is based on QT5.

  • Not all parts are open source, using vendor-provided binaries requires purchasing a license
  • Very limited number of devices officially supported (as of now, only one Sony device is globally purchaseable)
  • Community-backed ports for many devices such as the Fairphone 2 are available
  • All supported devices (officially and by the community) require binary-only, proprietary firmware (a few devices require not that much non-free firmware, but most devices require a lot)
  • OS-independent freedom and security concerns

    Firmware vulnerabilities

    If you run non-free firmware that is required to operate most smartphones (which is always required except if you run Replicant and can live with severely degraded functionality) you are the mercy of the vendor to provide you with updates. However, there are critical vulnerabilities in some of these firmwares. But even in extreme cases such as the “Broadpwn” exploit (affects BCM43xx wifi chipsets found on more than a billion of devices), vendors often refuse to provide updated firmware if the affected devices are outside of the official support period.

    Bootloader freedom

    As far as I know, there are no modern smartphones which come preinstalled with a free bootloader or where the proprietary bootloader can be replaced. Few exception may be some (quite dated) devices supported by postmarketOS such as the Nokia N900.

    Hardware-backed security firmware

    Modern SoCs come with a TEE (Trusted Execution Environment) as part of their chip design. These separate systems are used for securely processing/storing credentials such as fingerprints or (parts of) device encryption keys. Usually, these subsystems are closed source. Thus, their proper operation is difficult to audit (although the developers of CopperheadOS claim to have succeeded in doing this [2]).

    Separation of SoC and baseband

    Many modern do not have a clear separation between the baseband processor (that runs the non-free radio firmware) and the SoC. This means, that you actually have to trust the firmware of the baseband firmware vendor. There is at least one known case of a backdoor built into the layer above that was detected on older Samsung devices and mitigated by Replicant developers [3].

    Other partitions with non-free binaries and data

    Some people may think that by re-flashing a ROM or factory image they return their device to the original state. However, todays smartphones often contain a bunch of partitions, but most of them remained untouched during flashing. For instance, here is a listing of partition names and corresponding flash partitions from a Nexus 5:

    DDR	->	/dev/block/mmcblk0p24
    aboot	->	/dev/block/mmcblk0p6
    abootb	->	/dev/block/mmcblk0p11
    boot	->	/dev/block/mmcblk0p19
    cache	->	/dev/block/mmcblk0p27
    crypto	->	/dev/block/mmcblk0p26
    fsc	->	/dev/block/mmcblk0p22
    fsg	->	/dev/block/mmcblk0p21
    grow	->	/dev/block/mmcblk0p29
    imgdata	->	/dev/block/mmcblk0p17
    laf	->	/dev/block/mmcblk0p18
    metadata	->	/dev/block/mmcblk0p14
    misc	->	/dev/block/mmcblk0p15
    modem	->	/dev/block/mmcblk0p1
    modemst1	->	/dev/block/mmcblk0p12
    modemst2	->	/dev/block/mmcblk0p13
    pad	->	/dev/block/mmcblk0p7
    persist	->	/dev/block/mmcblk0p16
    recovery	->	/dev/block/mmcblk0p20
    rpm	->	/dev/block/mmcblk0p3
    rpmb	->	/dev/block/mmcblk0p10
    sbl1	->	/dev/block/mmcblk0p2
    sbl1b	->	/dev/block/mmcblk0p8
    sdi	->	/dev/block/mmcblk0p5
    ssd	->	/dev/block/mmcblk0p23
    system	->	/dev/block/mmcblk0p25
    tz	->	/dev/block/mmcblk0p4
    tzb	->	/dev/block/mmcblk0p9
    userdata	->	/dev/block/mmcblk0p28
    

    Even if you flash the factory ROM provided by Google, it only touches a few of these partitions. The other parts remain unchanged. It is hard to find documentation on what the purpose of these partitions is and, depending on the device, there are many different partitions. Also, for partitions that usually don’t change I haven’t seen any list of hashes from OEMs. Therefore, if you buy a used phone you have to be aware that there is (1) no official way to reset these partitions to their factory state and (2) it’s hard to tell if any of these partitions have been modified. Most of these partitions can be modified if you have root access, therefore, if you ever executed something with root rights it could have tampered with one of those.

    Conclusion and recommendations

    Given the current situation, providing recommendations is hard as it highly depends on these factors:

    • your willingness to run non-free software (esp. firmware)
    • your trust in particular SoC vendors
    • your threat perceptions (e.g. do you see more threats from local or from remote attackers?)

    The options I would recommend are as follows (order is arbitrary and SailfishOS was not considered due to my lack of experience with it):

    • Get a device supported by Replicant (Samsung Galaxy S2, Galaxy S3 or Galaxy Note 1), live with the degraded functionality and the devices’ trivial local exploitability. If you can, support development towards newer LineageOS versions to get OS-level security updates with less delays in the future.
    • Get a recent (still-supported) Nexus/Pixel devices and run CopperheadOS on it. You will be secured as good as possible from local and OS-level remote attacks and get OS and firmware updates every month. However, you have to fully trust the SoC platform and its (non-separated) baseband firmware. In addition, you have to pollute the environment by switching to newer devices once your device runs out of support.
    • Support the Librem 5 campaign and hope purism will keep their promises for choosing libre-friendly hardware (if you ask me, they should concentrate on these issues, abandon pureOS and support postmarketOS instead).
    • Recycle an old device and support postmarketOS and other free software projects like Plasma Mobile to help building a free alternative to Android. This might become interesting if we succeed in lowering the dependencies on non-free firmware with the availability of devices like the Librem 5 (provided the vendor keeps their promises).

    References

    [1] https://blogs.fsfe.org/kuleszdl/2018/03/31/securing-copperheados-by-using-separate-encryptionlockscreen-passphrases/
    [2] https://github.com/copperhead/bugtracker/issues/451
    [3] https://www.fsf.org/blogs/community/replicant-developers-find-and-close-samsung-galaxy-backdoor

    Sunday, 01 April 2018

    OER figures with license meta-data in emacs-reveal

    Jens Lechtenbörger » English | 12:14, Sunday, 01 April 2018

    Do you teach or educate? Do you use somebody else’s educational resources or share your own creations?

    As described last year, I created an infrastructure called emacs-reveal to produce HTML presentations as Open Educational Resources (OER) from Org Mode text files in GNU Emacs for my own teaching. If you believe in the values of free software, I’m sure that you will find the values of OER appealing as well (despite the choice of “open” as main characteristic), whose licenses are supposed to permit 5 Rs, namely Retain, Reuse, Revise, Remix, Redistribute.

    While working on my own presentations, I found myself repeatedly copying figures along with proper licensing information between presentations, which clearly indicated that my workflow was less than ideal. Indeed, most image formats do not provide any means for the inclusion of licensing information, so such annotations must be copied separately from the image file itself. To get rid of time-consuming and error-prone copying, I decided to create one separate meta-data file with license information for each image. For those meta-data files I use an ad-hoc format based on accepted terminologies (Dublin Core and Creative Commons).

    In my presentations, I can now simply include the meta-data file, and proper licensing and attribution information will be displayed automatically. Moreover, licensing and attribution information is embedded as RDFa in generated HTML presentations, making it accessible on the Semantic Web. (For example, the Firefox plugin OpenLink Structured Data Sniffer can parse and display such RDFa data.)

    My figures are published in this GitLab repository, and my howto for emacs-reveal (source code) includes some figure examples. As an aside, if you are interested in OER or free software or both, I’d be happy to receive feedback on what I plan to present as motivation for a course on operating systems (source code) starting in June.

    Saturday, 31 March 2018

    Further securing Nexus devices running CopperheadOS by using separate Encryption/Lockscreen passphrases

    Daniel's FSFE blog | 20:25, Saturday, 31 March 2018

    Please note that this article has undergone a major revision. After receiving negative feedback about mixing different aspects in this article from the Copperhead CTO [1], I decided to discuss the more opinionated comparison with other systems in a separate article. [2]

    Motivation

    Some of you may be familiar with CopperheadOS. CopperheadOS is a security-oriented custom Android distribution that is based directly on AOSP (not on LineageOS or similar “heavy” forks). It is free from Google Apps and aims to be more secure than stock Android by incorporating various hardening patches.

    When CopperheadOS was announced in 2015, one great feature they wanted to provide was support for using separate passphrases/pins for device encryption and the lockscreen. Unfortunately, with the move to Android 7 (or 8 ) supporting this feature got infeasible. However, providing a long passphrase each time you want to unlock your phone is extremely incovinient. On the other hand, using a short passphrase or simple PIN is insecure, because if an attacker succeeds to read your key from the (unauditable hard to audit) TEE, it is trivial to get the key using brute force attacks.

    Officially, there is no way for using a separate encryption passphrase in neither AOSP or CopperheadOS atm. Luckily, I found a (rather complicated) method how it can be achieved on Nexus devices (according to discussion with CopperheadOS devs it is not applicable for Pixel devices). This article briefly describes this method (that in principle should also work for AOSP).

    Disclaimer

    All data and information provided in this article is for informational purposes only. The author makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this article and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.

    In no event the author we be liable for any loss or damage including without limitation, indirect or consequential loss or damage, or any loss or damage whatsoever arising from loss of data or profits arising out of, or in connection with, the use of this article.

    Enabling a secure boot time password in CopperheadOS

    In all Android versions since 4.0, a separate passphrase could be enabled via the terminal or ADB using the “vdc” command. There are also some apps in the F-Droid store which allow to to this even more comfortably. However, both approaches require root access. Since CopperheadOS has decided (for good reasons!) not to provide root access at all, it’s not possible to use the vdc call (or even those less secure apps that require a superuser service installed) in the vendor-supported CopperheadOS builds.

    You can overcome this limitation by using a self-compiled “userdebug”-build that allows root access via adb. However, you want to run such a build only temporarily and this is where things get more complicated. I spent way too much time in figuring out how to achieve a desirable result, thus, I can only share the principal steps how to achieve this for now:

    1. Modify the boardconfig for your device and edit the CMDLINE parameter so that it tries to disable SELinux (todo: provide the necessary string here). Note that this will be only effective in “userdebug” builds but ignored in “user” builds. There also seems to be a bug that it will still display “enforcing” in the system menu.
    2. Compile CopperheadOS using the official documentation and own release signing keys; backup the keys and the generated images.
    3. Compile second “release” build (using the same release keys!) but choose the variant “userdebug” to obtain an insecure, debug-enabled build. Backup the generated images as well. It is important that your “user” build is newer, since OTA downgrades are not allowed in many bootloaders.
    4. Unlock the bootloader (your data partition will get wiped!).
    5. Flash the userdebug build using the “flash-all” method.
    6. Re-flash the recovery partition, replacing it by the one from the normal “user” build. This is needed because the “userdebug” recovery is insecure as it provides root access without authentication! (Turned out to be not needed)
    7. Lock the bootloader (your data partition will get wiped again on the next boot).
    8. Boot into the insecure “userdebug” build.
    9. Set the simple lockscreen protection you would like to have for everyday use PIN/password (the lockscreen is rate-limited, so you can even use a simple PIN).
    10. Enable adb
    11. Connect via adb and use “su” to become root.
    12. Run the vdc command to set a complex passphrase for the boot-time password (vdc cryptfs changepw password your-new-super-secure-extraa-long-password).
    13. Reboot the device and verify that everything is working as expected.
    14. Reboot to recovery
    15. Verify that you have the secure recovery installed: (1) It welcomes you just with “no command” and you have to hold power+volup to get a menu. (2) The menu you get does not have the insecure options such as “mount /system”.
    16. Sideload the OTA image of your secure “user” build.
    17. Reboot to the normal OS (do not wipe!)

    To make sure you are running the secured build, you can enable adb, log in via adb and try calling “su” to make sure it does not exist.

    If I find the time I will update this article with more detailed instructions and describe how to work around the several build issues I encountered in CopperheadOS (you have to overcome them in order to build it) as well.

    Limitations

    Please be aware of the following limitations:

    • To change your password or key you have to build a new userdebug build and a new user build and flash them via OTA because the recovery does not accept older builds.
    • To do other operations which require root (e.g. a full backup via one of the methods described in one of my earlier posts [3]) you also have to go through this procedure of making two new builds.
    • Even if you have a separate and more secure boot password, your key remains in memory if you lock the device and could be subject to various attack vectors (unlike the newer FDE approach on Pixel devices, where the key is not in memory when your screen is locked)

    References

    [1] https://github.com/copperhead/bugtracker/issues/451
    [2] https://blogs.fsfe.org/kuleszdl/2018/04/02/looking-for-a-secure-smartphone-running-only-free-software-good-luck/
    [3] http://blogs.fsfe.org/kuleszdl/2016/11/02/android-data-backup/

    Working with Yaml and Jinja2 in Python3

    Evaggelos Balaskas - System Engineer | 18:17, Saturday, 31 March 2018

    YAML

    YAML is a human friendly data serialization standard, especially for configuration files. Its simple to read and use.

    Here is an example:

    ---
    # A list of tasty fruits
    fruits:
        - Apple
        - Orange
        - Strawberry
        - Mango

    btw the latest version of yaml is: v1.2.

    PyYAML

    Working with yaml files in python is really easy. The python module: PyYAML must be installed in the system.

    In an archlinux box, the system-wide installation of this python package, can be done by typing:

    $ sudo pacman -S --noconfirm python-yaml

    Python3 - Yaml Example

    Save the above yaml example to a file, eg. fruits.yml
    Open the Python3 Interpreter and write:

    $ python3.6
    Python 3.6.4 (default, Jan  5 2018, 02:35:40)
    [GCC 7.2.1 20171224] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from yaml import load 
    
    >>> print(load(open("fruits.yml")))
    {'fruits': ['Apple', 'Orange', 'Strawberry', 'Mango']}
    >>>
    

    an alternative way is to write the above commands to a python file:

    from yaml import load
    print(load(open("fruits.yml")))

    and run it from the console:

    $ python3 test.py
    {'fruits': ['Apple', 'Orange', 'Strawberry', 'Mango']}

    Instead of print we can use yaml dump:

    eg.

    import yaml
    
    yaml.dump(yaml.load(open("fruits.yml")))
    'fruits: [Apple, Orange, Strawberry, Mango]n'

    The return type of yaml.load is a python dictionary:

    type(load(open("fruits.yml")))
    <class 'dict'>

    Have that in mind.

    Jinja2

    Jinja2 is a modern and designer-friendly templating language for Python.

    As a template engine, we can use jinja2 to build complex markup (or even text) output, really fast and efficient.

    Here is an jinja2 template example:

    I like these tasty fruits:
    * {{ fruit }}

    where {{ fruit }} is a variable.
    Declaring the fruit variable with some value and the jinja2 template can generate the prefarable output.

    python-jinja

    In an archlinux box, the system-wide installation of this python package, can be done by typing:

    $ sudo pacman -S --noconfirm python-jinja

    Python3 - Jinja2 Example

    Below is a python3 - jinja2 example:

    import jinja2
    
    template = jinja2.Template("""
    I like these tasty fruits:
    * {{ fruit }}
    """)
    
    data = "Apple"
    print(template.render(fruit=data))

    The output of this example is:

    I like these tasty fruits:
    * Apple

    File Template

    Reading the jinja2 template from a template file, is a little more complicated than before. Building the jinja2 enviroment is step one:

    env = jinja2.Environment(loader=jinja2.FileSystemLoader("./"))

    and Jinja2 is ready to read the template file:

    template = env.get_template("t.j2")

    The template file: t.j2 is a litle diferrent than before:

    I like these tasty fruits:
    {% for fruit in fruits -%}
    * {{ fruit }}
    {% endfor %}

    Yaml, Jinja2 and Python3

    To render the template a dict of global variables must be passed. And parsing the yaml file the yaml.load returns a dictionary! So everything are in place.

    Compine everything together:

    from yaml import load
    from jinja2 import Environment, FileSystemLoader
    
    mydata = (load(open("fruits.yml")))
    
    env = Environment(loader=FileSystemLoader("./"))
    template = env.get_template("t.j2")
    
    print(template.render(mydata))

    and the result is:

    $ python3 test.py

    I like these tasty fruits:
    * Apple
    * Orange
    * Strawberry
    * Mango
    

    Wednesday, 28 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 9)

    Paul Boddie's Free Software-related blog » English | 22:07, Wednesday, 28 March 2018

    After all my effort modifying the Fiasco.OC kernel, adapting driver code for the Ben NanoNote to work in the L4 Runtime Environment (L4Re), I had managed to demonstrate programs that could access the framebuffer and thus show things on the screen. But my stated goal is to demonstrate the functioning of existing code and a range of different components, specifically the “spectrum” example, GUI multiplexer (Mag), and framebuffer driver (fb-drv), supported by additional driver functionality I have added myself.

    Still to do were the tasks of getting the framebuffer driver to access my LCD driver, getting Mag to work on top of that, and then getting the “spectrum” example to work as it had done with Fiasco.OC-UX. Looking back at this exercise now, I can see that it is largely a case of wiring up the components just as we saw earlier when I showed how to get access to the hardware through the Io server. But this didn’t prevent excursions into the code for some debugging operations or a few, more lasting, modifications.

    Making a Splash

    I had sought to test the entire stack consisting of the example, GUI multiplexer, framebuffer driver, and the rest of the software using a configuration derived from both the UX “spectrum” demonstration (found in l4/conf/examples/x86-fb.cfg) and the corresponding demonstration for ARM-based devices (found in l4/conf/examples/arm-rv-lcd.cfg). Unsurprisingly, this did not work, and so I started out stripping down my own example configuration in order to test the components individually.

    On the way, I learned a few things that I wished I’d realised earlier. The first one is pretty mundane but very important. In order to strip down the configuration, I had tried to comment out various components and had done so using the hash symbol (#), which vim had helped to make me believe was a valid comment symbol. In fact, in Lua, if the hash symbol can be used for “program metadata”, perhaps for the usual Unix scripting declaration, then its use may be restricted to such narrow purposes and no others (as far as I could tell from quickly looking through the documentation). Broader use of the symbol appears to involve it acting as the length operator.

    By making an assumption almost instinctively, due to the prevalence of the hash character as a comment symbol in Unix scripting, I was now being confronted with “Starting kernel …” and nothing more, making me think that I had really broken something. I had to take several steps back, consider what might really be happening, that the Ned task responsible for executing the configuration had somehow failed, and then come to the realisation that were I able to read the serial console output, I would be staring at a Lua syntax error!

    So, removing the configuration details that I didn’t want to test straight away, I set about testing the framebuffer driver all by itself. Here is the configuration file involved (edited slightly):

    local io_buses =
      {
        fbdrv = l:new_channel();
      };
    
    l:start({
      caps = {
          fbdrv = io_buses.fbdrv:svr(),
          icu = L4.Env.icu,
          sigma0 = L4.cast(L4.Proto.Factory, L4.Env.sigma0):create(L4.Proto.Sigma0),
        },
      },
      "rom/io -vvvv rom/hw_devices.io rom/mips-qi_lb60-fbdrv.io");
    
    local fbdrv_fb = l:new_channel();
    
    l:startv({
      caps = {
          vbus = io_buses.fbdrv,
          fb   = fbdrv_fb:svr(),
        },
      },
      "rom/fb-drv", "-c", "nanonote"); -- configuration passed to the LCD driver

    It was around this time that I discovered the importance of the naming of certain things, noted previously, and so in the accompanying Io configuration, the devices are added to a vbus called “fbdrv”. What this example should do is to run just the framebuffer driver (fb-drv) and the Io server.

    Now, you might be wondering what the point of running just the driver, without any client programs, might be. Well, I had noticed that the driver should show a “splash screen”, and so I eagerly anticipated seeing whatever the L4Re developers had decided to show to us upon the driver starting up. Unfortunately, all I got was a blank screen. That made me think some bad things about what might be happening in the code. Fortunately, it didn’t take me long to realise what the problem was, discovering the following (in l4/pkg/fb-drv/server/src/splash.cc):

      if (fb_info->width < SPLASHNAME.width)
        return;
      if (fb_info->height < SPLASHNAME.height)
        return;

    Meanwhile, in the source file providing the screen data (l4/pkg/fb-drv/server/data/splash1.c), I saw that the width and height of the image were given as being 480 pixels and 65 pixels respectively. The Ben’s screen is 320 pixels wide and 240 pixels high, thus preventing the supplied image from being shown.

    It seemed worthwhile trying to replace this image just to reassure myself that the driver was actually working. The supplied image was exported from GIMP and so I attempted to reproduce this by loading one of my own images into GIMP, cropping to 320×240, and saving as a C source file with run-length encoding, 3 bytes per pixel, just as the supplied image had been created. I then copied it into the appropriate package subdirectory (l4/pkg/fb-drv/server/data) and modified the Makefile (l4/pkg/fb-drv/server/src/Makefile), changing it to reference my image instead of the supplied one.

    I also needed to change a few other things in the Makefile, as it turned out, such as the definitions of the sources and libraries used by MIPS architecture devices. It was odd to encounter architecture-specific artefacts at this level in the system, but I suppose that different architectures tend to employ different kinds of display mechanisms: the x86 architecture and derivatives have their “legacy” devices; other architectures used in system-on-a-chip products have other peripherals and devices. Anyway, building the payload and booting the Ben gave me this:

    The Ben NanoNote showing my L4Re framebuffer driver splash screen

    The Ben NanoNote showing my L4Re framebuffer driver splash screen: rainbow lorikeets on a suburban lawn

    So, the framebuffer driver will happily run, showing its splash screen until something connects to it and gets something else onto the screen. Here, we just let it run by itself until it is time to switch off!

    Missing Inputs

    There was still one component to be tested before arriving at the “spectrum” example: the GUI multiplexer, Mag. But testing it alone did not necessarily seem to make sense, because unlike the framebuffer driver, Mag’s role is merely to arbitrate between different framebuffer clients. So testing it and some kind of example together seemed like the only workable strategy.

    I tried to test it with the “spectrum” example, but I only ever saw the framebuffer splash screen, so it seemed that either the example or Mag wasn’t working. But if it were Mag that wasn’t working, how would I be able to find my way to the problem? I briefly considered whether Mag had a problem with the display configuration, given that I had already seen such a problem, albeit a minor one, in the framebuffer driver.

    I chased references around the source code until I established that Mag was populating a fixed-length array of “factory” objects defined in one place (l4/pkg/mag-gfx/include/factory) whose members were statically defined in another place (l4/pkg/mag/server/src/screen.cc), each one indicating how to deal with a particular pixel format. Such objects being of type Mag_gfx::Mem::Factory are returned in the Mag main program (in pkg/mag/server/src/main.cc) when the following code is executed:

      Screen_factory *f = dynamic_cast<Screen_factory*>(Screen_factory::set.find(view_i.pixel_info));

    I had wondered whether f was being presented with a null value and thus stopping Mag right there, but since there was a suitable factory object being created for the Ben’s pixel format, it seemed rather unlikely. So, the only approach I had considered at this point was not a particularly convenient one: I would have to replicate Mag piece by piece until discovering which part of it caused it to fail.

    I set out with a simple example borrowing code from Mag that requests a memory region via a capability or channel, displaying some data on the screen. This managed to work. I then expanded the example, adding various data structures, copying functionality into the example directory from Mag, slowly reassembling what Mag had been all along. Things kept working, right until the point where I needed to set the example going as a server rather than have it wait in an infinite loop doing nothing. Then, the screen would very briefly show the splash image, then the bit patterns, and then go blank.

    But maybe Mag was going to clear the framebuffer anyway and thus the server loop was working? Perhaps this was what success actually looked like under these circumstances, which is to say that it did not involve seeing two brightly-coloured birds on a lawn. At this point, out of laziness, I had avoided integrating the plugins into my example, and that was the only remaining difference between it and Mag.

    I started to realise that maybe it was a matter of removing things from Mag and seeing if I could get it to work, and the obvious candidates for removal were the plugins. So I removed all the plugins as defined in the Makefile (found at pkg/mag/server/src/Makefile) and tested to see if it changed Mag’s behaviour. Sure enough, the screen went blank. I then added plugins back one by one, knowing by now that the mag-client_fb plugin was going to be required to get the example working.

    Well, it turned out that there was one plugin causing all the problems: mag-input-libinput. Removing that got the “spectrum” example to work:

    The Ben NanoNote showing the "spectrum" framebuffer example

    The Ben NanoNote showing the "spectrum" framebuffer example

    Given that I haven’t addressed the matter of supporting input devices, which for the Ben would mostly concern the keyboard, disabling this errant plugin seemed like a reasonable compromise for now.

    A Door Opens?

    There isn’t much left to be said, which perhaps makes the ending something of an anticlimax. But perhaps this is part of the point of the exercise, that the L4Re/Fiasco.OC combination now just seems to work on the Ben NanoNote, and that it could potentially in future be just another thing that this software supports. Of course, the Ben is such a relatively rare device that it isn’t likely to have many potential users, but the SoC family of which the JZ4720 is a part is employed by a number of different devices.

    If there haven’t been any privately-maintained ports of this software to those other devices, then this work potentially opens the door to its use on other handheld devices like the GCW Zero or any number of randomly-sourced pocket games consoles, portable media players, and even smartwatches and wearable devices, all of which have been vehicles for the SoC vendor’s products. The Letux 400 could probably be supported given the similarity of its own SoC, the JZ4730, to that used in the Ben.

    When the Ben was released, work had been done, first by the SoC vendor, then by the Qi Hardware people, to provide a functioning GNU/Linux system for the device. Clearly, there isn’t an overwhelming need for another kind of system if the intention is to just use the device with existing Free Software. But perhaps this is another component in this exercise: to make other technological solutions possible and to explore avenues that get ignored as everyone follows the mainstream. The Ben is hardly a mainstream product itself; why not use it to make other alternative choices?

    It seems interesting to consider writing other drivers for the Ben and to gain experience with microkernel-based systems design. The Genode framework might also be worth investigating, given its focus on becoming a system suitable for deployment to end-users. The Hurd was also ported in an exploratory fashion to one of the L4 implementations some time ago, and revisiting this might be possible, even simplifying the effort thanks to the evolution in features provided by implementations like Fiasco.OC.

    In any case, I hope that this account has been vaguely interesting and entertaining. If you managed to read it all, you deserve my sincere thanks for spending the time to do so. A summary of the work will probably follow, and the patches themselves are available on a page dedicated to the effort. Good luck with your own investigations into alternative Free Software operating systems!

    Tuesday, 27 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 8)

    Paul Boddie's Free Software-related blog » English | 21:22, Tuesday, 27 March 2018

    With some confidence that the effort put in previously had resulted in a working Fiasco.OC kernel, I now found myself where I had expected to be at the start of this adventure: in the position of trying to get an example program working that could take advantage of the framebuffer on the Ben NanoNote. In fact, there is already an example program called “spectrum” that I had managed to get working with the UX variant of Fiasco.OC (this being a kind of “User Mode Fiasco” which runs as a normal process, or maybe a few processes, on top of a normal GNU/Linux system).

    However, if this exercise had taught me nothing else, it had taught me not to try out huge chunks of untested functionality and then expect everything to work. It would instead be a far better idea to incrementally add small chunks of functionality whose correctness (or incorrectness) would be easier to see. Thus, I decided to start with a minimal example, adding pieces of tested functionality from my CI20 experiments that obtain access to various memory regions. In the first instance, I wanted to see if I could exercise control over the LCD panel via the general-purpose input/output (GPIO) memory region.

    Wiring Up

    At this point, I should make a brief detour into the matter of making peripherals available to programs. Unlike the debugging code employed previously, it isn’t possible to just access some interesting part of memory by taking an address and reading from it or writing to it. Not only are user space programs working with virtual memory, whose addresses need not correspond to the actual physical locations employed by the underlying hardware, but as a matter of protecting the system against program misbehaviour, access to memory regions is strictly controlled.

    In L4Re, a component called Io is responsible for granting access to predefined memory regions that describe hardware peripherals or devices. My example needed to have the following resources defined:

    • A configuration description (placed in l4/conf/examples/mips-qi_lb60-lcd.cfg)
    • The Io peripheral bus description (placed in l4/conf/examples/mips-qi_lb60-lcd.io)
    • A list of modules needing deployment (added as an entry to l4/conf/modules.list, described separately in l4/conf/examples/mips-qi_lb60-lcd.list)

    It is perhaps clearer to start with the Io-related resource, which is short enough to reproduce here:

    local hw = Io.system_bus()
    
    local bus = Io.Vi.System_bus
    {
      CPM = wrap(hw:match("jz4740-cpm"));
      GPIO = wrap(hw:match("jz4740-gpio"));
      LCD = wrap(hw:match("jz4740-lcd"));
    }
    
    Io.add_vbus("devices", bus)

    This is Lua source code, with Lua having been adopted as a scripting language in L4Re. Here, the important things are those appearing within the hw:match function call brackets: each of these values refers to a device defined in the Ben’s hardware description (found in l4/pkg/io/io/config/plat-qi_lb60/hw_devices.io), identified using the “hid” property. The “jz4740-gpio” value is used to locate the GPIO device or peripheral, for instance.

    Also important is the name used for the bus, “devices”, in the add_vbus function call at the bottom, as we shall see in a moment. Moving on from this, the configuration description for the example itself contains the following slightly-edited details:

    local io_buses =
      {
        devices = l:new_channel();
      };
    
    l:start({
      caps = {
          devices = io_buses.devices:svr(),
          icu = L4.Env.icu,
          sigma0 = L4.cast(L4.Proto.Factory, L4.Env.sigma0):create(L4.Proto.Sigma0),
        },
      },
      "rom/io -vvvv rom/hw_devices.io rom/mips-qi_lb60-lcd.io");
    
    l:start({
      caps = {
          icu = L4.Env.icu,
          vbus = io_buses.devices,
        },
      },
      "rom/ex_qi_lb60_lcd");

    Here, the “devices” name seemingly needs to be consistent with the name used in the caps mapping for the Io server, set up in the first l:start invocation. The name used for the io_buses mapping can be something else, but then the references to io_buses.devices must obviously be changed to follow suit. I am sure you get the idea.

    The consequence of this wiring up is that the example program, set up at the end, accesses peripherals using the vbus capability or channel, communicating with Io and requesting access to devices, whose memory regions are described in the Ben’s hardware description. Io acts as the server on this channel whereas the example program acts as the client.

    Is This Thing On?

    There were a few good reasons for trying GPIO access first. The most significant one is related to the framebuffer. As you may recall, as the kernel finished starting up, sigma0 started, and we could then no longer be sure that the framebuffer configuration initialised by the bootloader had been preserved. So, I could no longer rely on any shortcuts in getting information onto the screen.

    Another reason for trying GPIO operations was that I had written code for the CI20 that accessed input and output pins, and I had some confidence in the GPIO driver code that I had included in the L4Re package hierarchy actually working as intended. Indeed, when working with the CI20, I had implemented some driver code for both the GPIO and CPM (clock/power management) functionality as provided by the CI20′s SoC, the JZ4780. As part of my preparation for this effort, I had adapted this code for the Ben’s SoC, the JZ4720. It was arguably worthwhile to give this code some exercise.

    One drawback with using general-purpose input/output, however, is that the Ben doesn’t really have any conveniently-accessed output pins or indicators, whereas the CI20 is a development board with lots of connectors and some LEDs that can be used to give simple feedback on what a program might be doing. Manipulating the LCD panel, in contrast, offers a very awkward way of communicating program status.

    Experiments proved somewhat successful, however. Obtaining access to device memory was as straightforward as it had been in my CI20 examples, providing me with a virtual address corresponding to the GPIO memory region. Inserting some driver code employing GPIO operations directly into the principal source file for the example, in order to keep things particularly simple and avoid linking problems, I was able to tell the panel to switch itself off. This involves bit-banging SPI commands using a number of output pins. The consequence of doing this is that the screen fades to white.

    I gradually gained confidence and decided to reserve memory for the framebuffer and descriptors. Instead of attempting to use the LCD driver code that I had prepared, I attempted to set up the descriptors manually by writing values to the structure that I knew would be compatible with the state of the peripheral as it had been configured previously. But once again, I found myself making no progress. No image would appear on screen, and I started to wonder whether I needed to do more work to reinitialise the framebuffer or maybe even the panel itself.

    But the screen was at least switched on, indicating that the Ben had not completely hung and might still be doing something. One odd thing was that the screen would often turn a certain colour. Indeed, it was turning purple fairly consistently when I realised my mistake: my program was terminating! And this was, of course, as intended. The program would start, access memory, set up the framebuffer, fill it with a pattern, and then finish. I suspected something was happening and when I started to think about it, I had noticed a transient bit pattern before the screen went blank, but I suppose I had put this down to some kind of ghosting or memory effect, at least instinctively.

    When a program terminates, it is most likely that the memory it used gets erased so as to prevent other programs from inheriting data that they should not see. And naturally, this will result in the framebuffer being cleared, maybe even the descriptors getting trashed again. So the trivial solution to my problem was to just stop my program from terminating:

    while (1);

    That did the trick!

    The Build-Up

    Accessing the LCD peripheral directly from my example is all very well, but I had always intended to provide a display driver for the Ben within L4Re. Attempting to compile the driver as part of the general build process had already identified some errors that had been present in what effectively had been untested code, migrated from my earlier work and modified for the L4Re APIs. But I wasn’t about to try and get the driver to work in one go!

    Instead, I copied more functionality into my example program, giving things like the clock management functionality some exercise, using my newly-enabled framebuffer output to test the results from various enquiries about clock frequencies, also setting various frequencies and seeing if this stopped the program from working. This did lead me on another needlessly-distracting diversion, however. When looking at the clock configuration values, something seemed wrong: they were shifted one bit to the left and therefore provided values twice as large as they should have been.

    I emitted some other values and saw that they too were shifted to the left. For a while, I wondered whether the panel configuration was wrong and started adjusting all sorts of timing-related values (front and back porches, sync pulses, video-related things), reading up about how the panel was configured using the SPI communications described above. It occurred to me that I should investigate how the display output was shifted or wrapped, and I used the value 0×80000001 to put bit values at the extreme left and right of the screen. Something was causing the output to be wrapped, apparently displaced by 9 pixels or 36 bytes to the left.

    You can probably guess where this is heading! The panel configuration had not changed and there was no reason to believe that it was wrong. Similarly, the framebuffer was being set up correctly and was not somehow moved slightly in memory, not that there is really any mechanism in L4Re or the hardware that would cause such a bizarre displacement. I looked again at my debugging code and saw my mistake; in concise terms, it took this form:

    for (i = 0; i < fb_size / 4; i++)
    {
        fb[i] = value & mask ? onpix : offpix; // write a pixel
        if ((i % 10) == 0)                     // move to the next bit?
        ...
    }

    For some reason, I had taken some perfectly acceptable code and changed one aspect of it. Here is what it had looked like on the many occasions I had used it in the past:

    i = 0;
    while (i < fb_size / 4)
    {
        fb[i] = value & mask ? onpix : offpix; // write a pixel
        i++;
        if ((i % 10) == 0)                     // move to the next bit?
        ...
    }

    That’s right: I had accidentally reordered the increment and “next bit” tests, causing the first bit in the value to occupy only one pixel, prematurely skipping to the next bit; at the end of the value, the mask would wrap around and show the remaining nine pixels of the first bit. Again, I was debugging the debugging and wasting my own time!

    But despite such distractions, over time, it became interesting to copy the complete source file that does most of the work configuring the hardware from my driver into the example directory and to use its functions directly, these functions normally being accessed by more general driver code. In effect, I was replicating the driver within an environment that was being incrementally enhanced, up until the point where I might assume that the driver itself could work.

    With no obvious problems having occurred, I then created another example without all the memory lookup operations, copied-in functions, and other “instrumentation”: one that merely called the driver API, relying on the general mechanisms to find and activate the hardware…

      struct arm_lcd_ops *ops = arm_lcd_probe("nanonote");

    …obtaining a framebuffer address and size…

      fb_vaddr = ops->get_fb();
      fb_size = ops->get_video_mem_size();

    …and then writing data to the screen just as I had done before. Indeed, this worked just like the previous example, indicating that I had managed to implement the driver’s side of the mechanisms correctly. I had a working LCD driver!

    Adopting Abstractions

    If the final objective had been to just get Fiasco.OC running and to have a program accessing the framebuffer, then this would probably be the end of this adventure. But, in fact, my aim is to demonstrate that the Ben NanoNote can take advantage of the various advertised capabilities of L4Re and Fiasco.OC. This means supporting facilities like the framebuffer driver, GUI multiplexer, and potentially other things. And such facilities are precisely those demonstrated by the “spectrum” example which I had promised myself (and my readership) that I would get working.

    At this point, I shouldn’t need to write any more of my own code: the framebuffer driver, GUI multiplexer, and “spectrum” example are all existing pieces of L4Re code. But what I did need to figure out was whether my recipe for wiring these things up was still correct and functional, and whether my porting exercise had preserved the functionality of these things or mysteriously broken them!

    Monday, 26 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 7)

    Paul Boddie's Free Software-related blog » English | 22:52, Monday, 26 March 2018

    Having tracked down lots of places in the Fiasco.OC kernel that needed changing to run on the Ben NanoNote, including some places I had already visited, changed, and then changed again to fix my earlier mistakes, I was on the “home straight”, needing only to activate the sigma0 thread and the boot thread before the kernel would enter its normal operational state. But the sigma0 thread was proving problematic: control was apparently passed to it, but the kernel would never get control back.

    Could this be something peculiar to sigma0, I wondered? I decided to swap the order of the activation, putting the boot thread first and seeing if the kernel “kept going”. Indeed, it did seem to, showing an indication on screen that I had inserted into the code to test whether the kernel regained control after activating the boot thread. So this indeed meant that something about sigma0 was causing the problem. I decided to trace execution through various method calls to see what might be going wrong.

    The Big Switch

    The process of activating a thread is rather interesting, involving the following methods:

    • Context::activate (in kernel/fiasco/src/kern/context.cpp)
    • Context::switch_to_locked
    • Context::schedule_switch_to_locked
    • Context::switch_exec_locked
    • Context::switch_cpu (in kernel/fiasco/src/kern/mips/context-mips.cpp)

    This final, architecture-specific method saves a few registers on the stack belonging to the current thread, doing so because we are now going to switch away from that thread. One of these registers ($31 or $ra) holds the return address which, by convention, is the address the processor jumps to after returning from a subroutine, function, method or something of that sort. Here, the return address, before it is stored, is set to a label just after a jump (or branch) instruction that is coming up. The flow of the code is such that we are to imagine that this jump will occur and then the processor will return to the label immediately following the jump:

    1. Set return address register to refer to the instruction after the impending jump
    2. Store registers on the stack
    3. Take the jump…
    4. Continue after the jump

    However, there is a twist. Just before the jump is taken, the stack pointer is switched to one belonging to another thread. On top of this, as the jump is taken, the return address is also replaced by loading a value from this other thread’s stack. The processor then jumps to the Context::switchin_context method. When the processor encounters the end of the generated code for this method, it encounters an instruction that makes it jump to the address in the return address register. Here is a more accurate summary:

    1. Set return address register to refer to the instruction after the impending jump
    2. Store registers on the stack
    3. Switch the stack pointer, referencing another thread’s stack
    4. Switch the return address to the other thread’s value
    5. Take the jump…

    Let us consider what might happen if this other thread was, in fact, the one we started with: the original kernel thread. Then the return address register would now hold the address of the label after the jump. Control would now pass back into the Context::switch_cpu method, and back out of that stack of invocations shown above, going from bottom to top.

    But this is not what happens at the moment: the return address is something that was conjured up for a new thread and execution will instead proceed in the place indicated by that address. A switch occurs, leaving the old thread dormant while a new thread starts its life somewhere else. The problem I now faced was figuring out where the processor was “returning” to at the end of Context::switchin_context and what was happening next.

    Following the Threads

    I already had some idea of where the processor would end up, but inserting some debugging code in Context::switchin_context and reading the return address from the $ra register allowed me to see what had been used without chasing down how the value had got there in the first place. Then, there is a useful tool that can help people like me find out the significance of a program address. Indeed, I had already used it a few times by this stage: the sibling of objdump known as addr2line. Here is an example of its use:

    mipsel-linux-gnu-addr2line -e mybuild/fiasco.debug 814165f0

    This indicated that the processor was “returning” to the Thread::user_invoke method (in kernel/fiasco/src/kern/mips/thread-mips.cpp). In fact, looking at the Thread::Thread constructor function, it becomes apparent that this information is specified using the Context::prepare_switch_to method, setting this particular destination up for the above activation “switch” operation. And here we encounter some more architecture-specific tricks.

    One thing that happens of importance in user_invoke is the disabling of interrupts. But if sigma0 is to be activated, they have to be enabled again so that sigma0 is then interrupted when a timer interrupt occurs. And I couldn’t find how this was going to be achieved in the code: nothing was actually setting the interrupt enable (IE) flag in the status register.

    The exact mechanism escaped me for a while, and it was only after some intensive debugging interventions that I realised that the status register is also set up way back in the Thread::Thread constructor function. There, using the result of the Cp0_status::status_eret_to_user_ei method (found in kernel/fiasco/src/kern/mips/cp0_status.cpp), the stored status register is set for future deployment. The status_eret_to_user_ei method initially looks like it might do things directly with the status register, but it just provides a useful value for the point at which control is handed over to a “user space” program.

    And, indeed, in the routine called ret_from_user_invoke (found in kernel/fiasco/src/kern/mips/exception.S), implemented by a pile of macros, there is a macro called restore_cp0_status that finally sets the status register to this useful value. A few instructions later, the “return from exception” instruction called eret appears and, with that, control passes to user space and hopefully some valid program code.

    Finding the Fault

    I now wondered whether the eret instruction was “returning” to a valid address. This caused me to take a closer look at the data structure,  Entry_frame (found in kernel/fiasco/src/kern/mips/entry_frame-mips.cpp), used to hold the details of thread execution states. Debugging in user_invoke, by invoking the ip method on the current context (itself obtained from the stored stack information) yielded an address of 0x2000e0. I double-checked this by doing some debugging in the different macros implementing the routine returning control to user space.

    Looking around, the Makefile for sigma0 (found as l4/pkg/l4re-core/sigma0/server/src/Makefile) provided this important clue as to its potential use of this address:

    DEFAULT_RELOC_mips  := 0x00200000

    Using our old friend objdump on the sigma0 binary (found as mybuild/bin/mips_32/l4f/sigma0), it was confirmed that 0x2000e0 is the address of the _start routine for sigma0. So we could at least suppose that the eret instruction was passing control to the start of sigma0.

    I had a suspicion that some instruction was causing an exception but not getting handled. But I had checked the generated code already and found no new unsupported instructions. This now meant the need to debug an unhandled exception condition. This can be done with care, as always, in the assembly language file containing the various “bare metal” handlers (exception.S, mentioned above), and such an intervention was enough to discover that the cause of the exception was an invalid memory access: an address exception.

    Now, the handling of such exceptions can be traced from the handlers into the kernel. There is what is known as a “vector table” which lists the different exception causes and the corresponding actions to be taken when they occur. One of the entries in the table looks like this:

            ENTRY_ADDR(slowtrap)      # AdEL

    This indicates that for an address exception upon load or instruction fetch, the slowtrap routine will be used. And this slowtrap routine itself employs a jump to a function in the kernel called thread_handle_trap (found in kernel/fiasco/src/kern/mips/thread-mips.cpp). Here, unsurprisingly, I found that attempts to handle the exception would fail and that the kernel would enter the Thread::halt method (in kernel/fiasco/src/kern/thread.cpp). This was a natural place for my next debugging intervention!

    I now emitted bit patterns for several saved registers associated with the thread/context. One looked particularly interesting: the stored exception program counter which contained the value 0x2092ac. I had a look at the code for sigma0 using objdump and saw the following (with some extra annotations added for explanatory purposes):

      209290:       3c02fff3        lui     v0,0xfff3
      209294:       24422000        addiu   v0,v0,8192    // 0xfff32000
      209298:       afc2011c        sw      v0,284(s8)
      20929c:       7c02e83b        0x7c02e83b            // rdhwr v0, $29 (ULR)
      2092a0:       afc20118        sw      v0,280(s8)
      2092a4:       8fc20118        lw      v0,280(s8)
      2092a8:       8fc30158        lw      v1,344(s8)
      2092ac:       8c508ff4        lw      s0,-28684(v0) // 0xfff2aff4

    Of particular interest was the instruction at 0x20929c, which I annotated above as corresponding to our old favourite, rdhwr, along with some other key values. Now, the final instruction above is where the error occurs, and it is clear that the cause is the access to an address that is completely invalid (as annotated). The origin of this address information occurs in the second instruction above. You may have realised by now that the rdhwr instruction was failing to set the v0 (or $v0) register with the value retrieved from the indicated hardware register.

    How could this be possible?! Support for this rdhwr variant was already present in Fiasco.OC, so could it be something I had done to break it? Perhaps the first rule of debugging is not to assume your own innocence for any fault, particularly if you have touched the code in the recent past. So I invoked my first strategy once again and started to look in the “reserved instruction” handler for likely causes of problems. Sure enough, I found this:

            ASM_INS         $at, zero, 0, THREAD_BLOCK_SHIFT, k1 # TCB addr in $at

    I had introduced a macro for the ins instruction that needed a temporary register to do its work, it being specified by the last argument. But k1 (or $k1) still holds the instruction that is being inspected, and it gets used later in the routine. By accidentally overwriting it, the wrong target register gets selected, and then the hardware register value is transferred to the wrong register, leaving the correct register unaffected. This is exactly what we saw above!

    What I meant to write was this:

            ASM_INS         $at, zero, 0, THREAD_BLOCK_SHIFT, k0 # TCB addr in $at

    We can afford to overwrite k0 (or $k0) since it gets overwritten shortly after, anyway. And sure enough, with this modification, sigma0 started working, with control being returned to the kernel after its activation.

    Returning to User Space

    Verifying that the kernel boot process completed was slightly tricky in that further debugging interventions seemed to be unreliable. Although I didn’t investigate this thoroughly, I suspect that with sigma0 initialised, memory may have been cleared, and this clearing activity erases the descriptor structure used by the LCD peripheral. So it then becomes necessary to reinitialise the peripheral by choosing somewhere for the descriptor, writing the appropriate members, and enabling the peripheral again. Since we might now be overwriting other things critical for the system’s proper functioning, we cannot then expect execution to continue after we have written something informative to the framebuffer, so an infinite loop deliberately hangs the kernel and lets us see our debugging output on the screen.

    I felt confident that the kernel was now booting and going about its normal business of switching between threads, handling interrupts and exceptions, and so on. For testing purposes, I had chosen the “hello” example as a user space program to accompany the kernel in the deployed payload, but this example is useless on the Ben without connecting up the serial console connection, which I hadn’t done. So now, I needed to start preparing examples that would actually show something on the screen, working towards running the “spectrum” example provided in the L4Re distribution.

    Sunday, 25 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 6)

    Paul Boddie's Free Software-related blog » English | 22:20, Sunday, 25 March 2018

    With all the previous effort adjusting Fiasco.OC and the L4Re bootstrap code, I had managed to get the Ben NanoNote to run some code, but I had encountered a problem entering the kernel. When an instruction was encountered that attempted to clear the status register, it would seem that the boot process would not get any further. The status register controls things like which mode the processor is operating in, and certain modes offer safety guarantees about how much else can go wrong, which is useful when they are typically entered when something has already gone wrong.

    When starting up, a MIPS-based processor typically has the “error level” (ERL) flag set in the status register, meaning that normal operations are suspended until the processor can be configured. The processor will be in kernel mode and it will bypass the memory mapping mechanisms when reading from and writing to memory addresses. As I found out in my earlier experiments with the Ben, running in kernel mode with ERL set can mask problems that may then emerge when unsetting it, and clearing the status register does precisely that.

    With the kernel’s _start routine having unset ERL, accesses to lower memory addresses will now need to go through a memory mapping even though kernel mode still applies, and if a memory mapping hasn’t been set up then exceptions will start to occur. This tripped me up for quite some time in my previous experiments until I figured out that a routine accessing some memory in an apparently safe way was in fact using lower memory addresses. This wasn’t a problem with ERL set – the processor wouldn’t care and just translate them directly to physical memory – but with ERL unset, the processor now wanted to know how those addresses should really be translated. And since I wasn’t handling the resulting exception, the Ben would just hang.

    Debugging the Debugging

    I had a long list of possible causes, some more exotic than others: improperly flushed caches, exception handlers in the wrong places, a bad memory mapping configuration. I must admit that it is difficult now, even looking at my notes, to fully review my decision-making when confronting this problem. I can apply my patches from this time and reproduce a situation where the Ben doesn’t seem to report any progress from within the kernel, but with hindsight and all the progress I have made since, it hardly seems like much of an obstacle at all.

    Indeed, I have already given the game away in what I have already written. Taking over the framebuffer involves accessing some memory set up by the bootloader. In the bootstrap code, all of this memory should actually be mapped, but since ERL is set I now doubt that this mapping was even necessary for the duration of the bootstrap code’s execution. And I do wonder whether this mapping was preserved once the kernel was started. But what appeared to happen was that when my debugging code tried to load data from the framebuffer descriptor, it would cause an exception that would appear to cause a hang.

    Since I wanted to make progress, I took the easy way out. Rather than try and figure out what kind of memory mapping would be needed to support my debugging activities, I simply wrapped the code accessing the framebuffer descriptor and the framebuffer itself with instructions that would set ERL and then unset it afterwards. This would hopefully ensure that even if things weren’t working, then at least my things weren’t making it all worse.

    Lost in Translation

    It now started to become possible to track the progress of the processor through the kernel. From the _start routine, the processor jumps to the kernel_main function (in kernel/fiasco/src/kern/mips/main.cpp) and starts setting things up. As I was quite sure that the kernel wasn’t functioning correctly, it made sense to drop my debugging code into various places and see if execution got that far. This is tedious work – almost a form of inefficient “single-stepping” – but it provides similar feedback about how the code is behaving.

    Although I had tried to do a reasonable job translating certain operations to work on the JZ4720 used by the Ben, I was aware that I might have made one or two mistakes, also missing areas where work needed doing. One such area appeared in the Cpu class implementation (in kernel/fiasco/src/kern/mips/cpu-mips.cpp): a rich seam of rather frightening-looking processor-related initialisation activities. The Cpu::first_boot method contained this ominous-looking code:

    require(c.r<0>().ar() > 0,  "MIPS r1 CPUs are notsupported\n");

    I hadn’t noticed this earlier, and its effect is to terminate the kernel if it detects an architecture revision just like the one provided by the JZ4720. There were a few other tests of the capabilities of the processor that needed to be either disabled or reworked, and I spent some time studying the documentation concerning configuration registers and what they can tell programs about the kind of processor they are running on. Amusingly, our old friend the rdhwr instruction is enabled for user programs in this code, but since the JZ4720 has no notion of that instruction, we actually disable the instruction that would switch rdhwr on in this way.

    Another area that proved to be rather tricky was that of switching interrupts on and having the system timer do its work. Early on, when laying the groundwork for the Ben in the kernel, I had made a rough translation of the CI20 code for the Ben, and we saw some of these hardware details a few articles ago. Now it was time to start the timer, enable interrupts, and have interrupts delivered as the timer counter reaches its limit. The part of the kernel concerned is Kernel_thread::bootstrap (in kernel/fiasco/src/kern/kernel_thread.cpp), where things are switched on and then we wait in a delay loop for the interrupts to cause a variable to almost magically change by itself (in kernel/fiasco/src/drivers/delayloop.cpp):

      Cpu_time t = k->clock;
      Timer::update_timer(t + 1000); // 1ms
      while (t == (t1 = k->clock))
        Proc::pause();

    But the processor just got stuck in this loop forever! Clearly, I hadn’t done everything right. Some investigation confirmed that various timer registers were being set up correctly, interrupts were enabled, but that they were being signalled using the “interrupt pending 2″ (IP2) flag of the processor’s “cause” register which reports exception and interrupt conditions. Meanwhile, I had misunderstood the meaning of the number in the last statement of the following code (from kernel/fiasco/src/kern/mips/bsp/qi_lb60/mips_bsp_irqs-qi_lb60.cpp):

      _ic[0] = new Boot_object<Irq_chip_ingenic>(0xb0001000);
      m->add_chip(_ic[0], 0);
    
      auto *c = new Boot_object<Cascade_irq>(nullptr, ingenic_cascade);
      Mips_cpu_irqs::chip->alloc(c, 1);

    Here is how the CI20 had been set up (in kernel/fiasco/src/kern/mips/bsp/ci20/mips_bsp_irqs-ci20.cpp):

      _ic[0] = new Boot_object<Irq_chip_ingenic>(0xb0001000);
      m->add_chip(_ic[0], 0);
      _ic[1] = new Boot_object<Irq_chip_ingenic>(0xb0001020);
      m->add_chip(_ic[1], 32);
    
      auto *c = new Boot_object<Cascade_irq>(nullptr, ingenic_cascade);
      Mips_cpu_irqs::chip->alloc(c, 2);

    With virtually no knowledge of the details, and superficially transcribing the code, editing here and there, I had thought that the argument to the alloc method referred to the number of “chips” (actually the number of registers dedicated to interrupt signals). But in fact, it indicates an adjustment to what the kernel code calls a “pin”. In the Mips_cpu_irq_chip class (in kernel/fiasco/src/kern/mips/mips_cpu_irqs.cpp), we actually see that this number is used to indicate the IP flag that will need to be tested. So, the correct argument to the alloc method is 2, not 1, just as it is for the CI20:

      Mips_cpu_irqs::chip->alloc(c, 2);

    This fix led to another problem and the discovery of another area that I had missed: the “exception base” gets redefined in the kernel (in src/kern/mips/cpu-mips.cpp), and so I had to make sure it was consistent with the other places I had defined it by changing its value in the kernel (in src/kern/mips/mem_layout-mips32.cpp). I mentioned this adjustment previously, but it was at this stage that I realised that the exception base gets set in the kernel after all. (I had previously set it in the bootstrap code to override the typical default of 0×80000000.)

    Leaving the Kernel

    Although we are not quite finished with the kernel, the next significant obstacle involved starting programs that are not part of the kernel. Being a microkernel, Fiasco.OC needs various other things to offer the kind of environment that a “monolithic” operating system kernel might provide. One of these is the sigma0 program which has responsibilities related to “paging” or allocating memory. Attempting to start such programs exercises how the kernel behaves when it hands over control to these other programs. We should expect that timer interrupts should periodically deliver control back to the kernel for it to do work itself, this usually involving giving other programs a chance to run.

    I was seeing the kernel in the “home straight” with regard to completing its boot activities. The Kernel_thread::init_workload method (in kernel/fiasco/src/kern/kernel_thread-std.cpp) was pretty much the last thing to be invoked in the Kernel_thread::run method (in kernel/fiasco/src/kern/kernel_thread.cpp) before normal service begins. But it was upon attempting to “activate” a thread to run sigma0 that a problem arose: the kernel never got control back! This would be my last major debugging exercise before embarking on a final excursion into “user space”.

    Saturday, 24 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 5)

    Paul Boddie's Free Software-related blog » English | 23:21, Saturday, 24 March 2018

    We left off last time with the unenviable task of debugging a non-working system. In such a situation the outlook can seem bleak, but I mentioned a couple of strategies that can sometimes rescue the situation. The first of these is to rule out areas of likely problems, which in my case tends to involve reviewing what I have done and seeing if I have made some stupid mistakes. Naturally, it helps to have a certain amount of experience to inform this process; otherwise, practically everything might be a place where such mistakes may be lurking.

    One thing that bothered me was the use of the memory map by Fiasco.OC on the Ben NanoNote. When deploying my previous experimental work to the Ben, I had become aware of limitations around where things might be stored, at least while any bootloader might be active. Care must be taken to load new code away from memory already being used, and it seems that the base of memory must also be avoided, at least at first. I wasn’t convinced that this avoidance was going to happen with the default configuration of the different components.

    The Memory Map

    Of particular concern were the exception vectors – where the processor jumps to if an exception or interrupt occurs – whose defaults in Fiasco.OC situate them at the base of kernel memory: 0×80000000. If the bootloader were to try and copy the code that handles exceptions to this region, I rather suspected that it would immediately cause problems.

    I was also unsure whether the bootloader was able to load the payload from the MMC/MicroSD card into memory without overwriting itself or corrupting the payload as it copied things around in memory. According to the boot script that seems to apply to the Ben, it loads the payload into memory at 0×80600000:

    #define CONFIG_BOOTCOMMANDFROMSD        "mmc init; ext2load mmc 0 0x80600000 /boot/uImage; bootm"

    Meanwhile, the default memory settings for L4Re has code loaded rather low in the kernel address space at 0x802d0000. Without really knowing what happens, I couldn’t be sure that something might get copied to that location, that the copied data might then run past 0×80600000, and this might overwrite some other thing – the kernel, perhaps – that hadn’t been copied yet. Maybe this was just paranoia, but it was at least something that could be dealt with. So I came up with some alternative arrangements:

    0x81401000 exception handlers
    0x81400000 kernel load address
    0x80d00000 bootstrap start address
    0x80600000 payload load address when copied by bootm

    I wanted to rule out memory conflicts but try and not conjure up more exotic solutions than strictly necessary. So I made some adjustments to the location of the kernel, keeping the exception vectors in the same place relative to the kernel, but moving the vectors far away from the base of memory. It turns out that there are quite a few places that need changing if you do this:

    • A configuration setting, CONFIG_KERNEL_LOAD_ADDR-32, in the kernel build scripts (in kernel/fiasco/src/Modules.mips)
    • The exception base, EXC_BASE, in the kernel’s linker script (in kernel/fiasco/src/kernel.mips.ld)
    • The exception base, Exception_base, in a description of the kernel memory layout (in kernel/fiasco/src/kern/mips/mem_layout-mips32.cpp)
    • The exception base, if it is mentioned in the bootstrap initialisation (in l4/pkg/bootstrap/server/src/ARCH-mips/crt0.S)

    The location of the rest of the payload seems to be configured by just changing DEFAULT_RELOC_mips32 in the bootstrap package’s build scripts (in l4/pkg/bootstrap/server/src/Make.rules).

    With this done, I had hoped that I might have “moved the needle” a little and provoked a visible change when attempting to boot the system, but this was always going to be rather optimistic. Having pursued the first strategy, I now decided to pursue the second.

    Getting in at the Start

    The second strategy is to use every opportunity to get the device to show what it is doing. But how can we achieve this if we cannot boot the kernel and start some code that sets up the framebuffer? Here, there were two things on my side: the role of the bootstrap code, it being rather similar to code I have written before, and the state of the framebuffer when this code is run.

    I had already discovered that provided that the code is loaded into a place that can be started by the bootloader, then the _start routine (in l4/pkg/bootstrap/server/src/ARCH-mips/crt0.S) will be called in kernel mode. And I had already looked at this code for the purposes of identifying instructions that needed rewriting as well as for setting the “exception base”. There were a few other precautions that were worth taking here before we might try and get the code to show its activity.

    For instance, the code present that attempts to enable a floating point unit in the processor does not apply to the Ben, so this was disabled. I was also unconvinced that the memory mapping instructions would work on the Ben: the JZ4720 does not seem to support memory pages of 256MB, with the Ben only having 32MB anyway, so I changed this to use 16MB pages instead. This must be set up correctly because any wandering into unmapped memory – visiting bad addresses – cannot be rectified before the kernel is active, and the whole point of the bootstrap code is to get the kernel active!

    Now, it wasn’t clear just how far the processor was getting through this code before failing somewhere, but this is where the state of the framebuffer comes in. On the Ben, the bootloader initialises the framebuffer in order to show the state of the device, indicate whether it found a payload to load and boot from, complain about error conditions, and so on. It occurred to me that instead of trying to initialise a framebuffer by programming the LCD peripheral in the JZ4720, set up various structures in memory, decide where these structures should even be situated, I could just read the details of the existing framebuffer from the LCD peripheral’s registers, then find out where the framebuffer resides, and then just write whatever data I liked to the framebuffer in order to communicate with the outside world.

    So, I would just need to write a few lines of assembly language, slip it into the bootstrap code, and then see if the framebuffer was changed and the details of interest written to the Ben’s display. Here is a fragment of code in a form that would become rather familiar after a time:

            li $8, 0xb3050040       /* LCD_DA0 */
            lw $9, 0($8)            /* &descriptor */
            lw $10, 4($9)           /* fsadr = descriptor[1] */
            lw $11, 12($9)          /* ldcmd = descriptor[3] */
            li $8, 0x00ffffff
            and $11, $8, $11        /* size = ldcmd & LCD_CMD0_LEN */
            li $9, 0xa5a5a5a5
    1:
            sw $9, 0($10)           /* *fsadr = ... */
            addiu $11, $11, -1      /* size -= 1 */
            addiu $10, $10, 4       /* fsadr += 4 */
            bnez $11, 1b            /* until size == 0 */
            nop

    To summarise, it loads the address of a “descriptor” from a configuration register provided by the LCD peripheral, this register having been set by the bootloader. It then examines some members of the structure provided by the descriptor, notably the framebuffer address (fsadr) and size (a subset of ldcmd). Just to show some sign of progress, the code loops and fills the screen with a specific value, in this case a shade of grey.

    By moving this code around in the bootstrap initialisation routine, I could see whether the processor even managed to get as far as this little debugging fragment. Fortunately for me, it did get run, the screen did turn grey, and I could then start to make deductions about why it only got so far but no further. One enhancement to the above that I had to make after a while was to temporarily change the processor status to “error level” (ERL) when accessing things like the LCD configuration. Not doing so risks causing errors in itself, and there is nothing more frustrating than chasing down errors only to discover that the debugging code caused these errors and introduced them as distractions from the ones that really matter.

    Enter the Kernel

    The bootstrap code isn’t all assembly language, and at the end of the _start routine, the code attempts to jump to __main. Provided this works, the processor enters code that started out life as C++ source code (in l4/pkg/bootstrap/server/src/ARCH-mips/head.cc) and hopefully proceeds to the startup function (in l4/pkg/bootstrap/server/src/startup.cc) which undertakes a range of activities to prepare for the kernel.

    Here, my debugging routine changed form slightly, minimising the assembly language portion and replacing the simple screen-clearing loop with something in C++ that could write bit patterns to the screen. It became interesting to know what address the bootstrap code thought it should be using for the kernel, and by emitting this address’s bit pattern I could check whether the code had understood the structure of the payload. It seemed that the kernel was being entered, but upon executing instructions in the _start routine (in kernel/fiasco/src/kern/mips/crt0.S), it would hang.

    The Ben NanoNote showing a bit pattern on the screen

    The Ben NanoNote showing a bit pattern on the screen with adjacent bits using slightly different colours to help resolve individual bit values; here, the framebuffer address is shown (0x01fb5000), but other kinds of values can be shown, potentially many at a time

    This now led to a long and frustrating process of detective work. With a means of at least getting the code to report its status, I had a chance of figuring out what might be wrong, but I also needed to draw on experience and ideas about likely causes. I started to draw up a long list of candidates, suggesting and eliminating things that could have been problems that weren’t. Any relief that a given thing was not the cause of the problem was tempered by the realisation that something else, possibly something obscure or beyond the limit of my own experiences, might be to blame. It was only some consolation that the instruction provoking the failure involved my nemesis from my earlier experiments: the “error level” (ERL) flag in the processor’s status register.

    Friday, 23 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 4)

    Paul Boddie's Free Software-related blog » English | 23:34, Friday, 23 March 2018

    As described previously, having hopefully done enough to modify the kernel – Fiasco.OC – for the Ben NanoNote, it then became necessary to investigate the bootstrap package that is responsible for setting up the hardware and starting the kernel.  This package resides in the L4Re distribution, which is technically a separate thing, even though both L4Re and Fiasco.OC reside in the same published repository structure.

    Before continuing into the details, it is worth noting which things need to be retrieved from the L4Re section of the repository in order to avoid frustration later on with package dependencies. I had previously discovered that the following package installation operation would be required (from inside the l4 directory):

    svn update pkg/acpica pkg/bootstrap pkg/cxx_thread pkg/drivers pkg/drivers-frst pkg/examples \
               pkg/fb-drv pkg/hello pkg/input pkg/io pkg/l4re-core pkg/libedid pkg/libevent \
               pkg/libgomp pkg/libirq pkg/libvcpu pkg/loader pkg/log pkg/mag pkg/mag-gfx pkg/x86emu

    With the listed packages available, it should be possible to build the examples that will eventually interest us. Some of these appear superfluous – x86emu, for instance – but some of the more obviously-essential packages have dependencies on these other packages, and so we cannot rely on our intuition alone!

    Also needed when building a payload is some path definitions in the l4/conf/Makeconf.boot file. Here is what I used:

    MODULE_SEARCH_PATH += $(L4DIR_ABS)/../kernel/fiasco/mybuild
    MODULE_SEARCH_PATH += $(L4DIR_ABS)/conf/examples
    MODULE_SEARCH_PATH += $(L4DIR_ABS)/pkg/io/io/config
    BOOTSTRAP_SEARCH_PATH  = $(L4DIR_ABS)/conf/examples
    BOOTSTRAP_SEARCH_PATH += $(L4DIR_ABS)/../kernel/fiasco/mybuild
    BOOTSTRAP_SEARCH_PATH += $(L4DIR_ABS)/pkg/io/io/config
    BOOTSTRAP_MODULES_LIST = $(L4DIR_ABS)/conf/modules.list

    This assumes that the build directory used when building the kernel is called mybuild. The Makefile will try and copy the kernel into the final image to be deployed and so needs to know where to find it.

    Describing the Ben (Again)

    Just as we saw with the kernel, there is a need to describe the Ben and to audit the code to make sure that it stands a chance of working on the Ben. This is done slightly differently in L4Re but the general form of the activity is similar, defining the following:

    • An architecture version (MIPS32r1) for the JZ4720 (in l4/mk/arch/Kconfig.mips.inc)
    • A platform configuration for the Ben (in l4/mk/platforms)
    • Some platform details in the bootstrap package (in l4/pkg/bootstrap/server/src)
    • Some hardware details related to memory and interrupts (in l4/pkg/io/io/config/plat-qi_lb60)

    For the first of these, I introduced a configuration setting (CPU_MIPS_32R1) to allow us to distinguish between the Ben’s SoC (JZ4720) and other processors, just as I did in the kernel code. With this done, the familiar task of hunting down problematic assembly language instructions can begin, and these can be divided into the following categories:

    • Those that can be rewritten using other instructions that are available to us
    • Those that must be “trapped” and handled by the kernel

    Candidates for the former category include all unprivileged instructions that the JZ4720 doesn’t support, such as ext and ins. Where privileged instructions or ones that “bridge” privileges in some way are used, we can still rewrite them if they appear in the bootstrap code, since this code is also running in privileged mode. Here is an example of such privileged instruction rewriting (from l4/pkg/bootstrap/server/src/ARCH-mips/crt0.S):

    #if defined(CONFIG_CPU_MIPS_32R1)
           cache   0x01, 0($a0)     # Index_Writeback_Inv_D
           nop
           cache   0x08, 0($a0)     # Index_Store_Tag_I
    #else
           synci   0($a0)
    #endif

    Candidates for the latter category include all awkward privileged or privilege-escalating instructions outside the bootstrap package. Fortunately, though, we don’t need to worry about them very much at all. Since the kernel will be obliged to trap them, we can just keep them where they are and concede that there is nothing else we can do with them.

    However, there is one pitfall: these preserved-but-unsupported instructions will upset the compiler! Consider the use of the now overly-familiar rdhwr instruction. If it is mentioned in an assembly language statement, the compiler will notice that amongst its clean MIPS32r1-compliant output, something is inserting an unrecognised instruction, yielding that error we saw earlier:

    Error: opcode not supported on this processor: mips32 (mips32)

    But we do know what we’re doing! So how can we persuade the compiler? The solution is to override what the compiler (or assembler) thinks it should be producing by introducing a suitable directive as in the following example (from l4/pkg/l4re-core/l4sys/include/ARCH-mips/cache.h):

      asm volatile (
        ".set push\n"
        ".set mips32r2\n"
        "rdhwr %0, $1\n"
        ".set pop"
        : "=r"(step));

    Here, with the .set directives, we switch this little region of code to MIPS32r2 compliance and emit our forbidden instruction into the output. Since the kernel will take care of it in the end, the compiler shouldn’t be made to feel that it has to defend us against it.

    In L4Re, there are also issues experienced with the CI20 that will also affect the Ben, such as an awkward and seemingly compiler-related issue affecting the way programs are started. In this regard, I just kept my existing patches for these things applied.

    My other platform-related adjustments for the Ben have mostly borrowed from support for the CI20 where it existed. For instance, the bootstrap package’s definition for the Ben (in l4/pkg/bootstrap/server/src/platform/qi_lb60.cc) just takes the CI20 equivalent, eliminates superfluous features, modifies details that are different between the SoCs, and changes identifiers. The general definition for the Ben (in l4/mk/platforms/qi_lb60.conf) merely acknowledges differences in some basic platform details.

    The CI20 was not supported with a hardware definition describing memory regions and interrupts used by the io package. Taking other devices as inspiration, I consulted the device documentation and wrote a definition when experimenting with the CI20. For the Ben, the form of this definition (in l4/pkg/io/io/config/plat-qi_lb60/hw_devices.io) remains similar but is obviously adjusted for the SoC differences.

    Device Drivers and Output

    One topic that I have not really mentioned at all is that pertaining to device drivers. I would not have even started this work if I didn’t feel there was a chance of seeing some signs of success from the Ben. Although the Ben, like the CI20, has the capability of exposing a serial console to the outside world, meaning that it can emit messages via a cable to another computer and receive input from that computer, unlike the CI20, its serial console pins are not particularly convenient to use: they really require wires to be soldered to some tiny pads that are found in the battery compartment of the device.

    Now, my soldering skills are not very good, and I also want to be able to put the battery back into the device in future. I did try and experiment by holding wires against the pads, this working once or twice by showing output when booting the Ben into its more typical Linux-based environment. But such experiments proved to be unsustainable and rather uncomfortable, needing some kind of “guitar grip” while juggling cables and holding down buttons. So I quickly knew that I would need to get output from the Ben in other ways.

    Having deployed low-level payloads to the Ben before, I knew something about the framebuffer, so I had some confidence about initialising it and getting something on the screen that might tell me what has or hasn’t happened. And I adapted my code from this previous effort, itself being derived from driver code written by the people responsible for the Ben, wrapping it up for L4Re. I tried to keep this code minimally different from its previous incarnation, meaning that I could eliminate certain kinds of mistakes in case the code didn’t manage to do its job. With this in place, I felt that I could now consider trying out my efforts and seeing what, if anything, might happen.

    Attempting to Bootstrap

    Being in the now-familiar position of believing that enough has been done to make the software run, I now considered an attempt at actually bootstrapping the kernel. It may sound naive, but I almost expected to be able to compile everything – the kernel, L4Re, my drivers – and for them all to work together in harmony and produce at least something on the display. But instead, after “Starting kernel …”, nothing happened.

    The Ben NanoNote trying to boot a payload from the memory card

    The Ben NanoNote trying to boot a payload from the memory card

    It should be said that in these kinds of exercises, just one source of failure need present itself and the outcome is, of course, failure. And I can confirm that there were many sources of failure at this point. The challenges, then, are to identify all of these and then to eliminate them all. But how can you even know what all of these sources of failure actually are? It seemed disheartening, but then there are two kinds of strategy that can be employed: to investigate areas likely to be causing problems, and to take every opportunity to persuade the device to tell us what is happening. And with this, the debugging would begin.

    My board nomination statement 2018

    Inductive Bias | 07:21, Friday, 23 March 2018

    Two days ago the Apache Software Foundation members meeting started. One of the outcomes of each members meeting is an elected board of directors. The way that works is explained here: Annual Apache members meeting. As explained in the linked post, members accepting their nomination to become a

    director are supposed to provide a nomination statement. This year they were also asked to answer a set of questions so members could better decide who to vote for.

    As one of my favourite pet peeves is to make the inner workings of the foundation more transparent to outsiders (and have said so in the nomination statement) - I would like to start by publishing my own nomination statement here for others to read who don't have access to our internal communication channels:

    Board statement:

    Two years ago I was put on a roller coaster by being nominated as Apache board member which subsequently meant I got to serve on the board in 2016. Little did I know what kind of questions were waiting for me.

    Much like back then I won't treat this position statement as a voting campaign. I don't claim to have answers to all the questions we face as we grow larger - however I believe being a board member even at our size should be something that is fun. Something that is lightweight enough so people don't outright decline their nominations just for lack of time.

    One thing I learnt the hard way is scalability needs two major ingredients: Breaking dependencies and distribution of workload. Call me old-fashioned (even though chemistry can hide my gray hair, my preference for mutt as a mail client betrays my age), but I believe we already have some of the core values to achieve just that:
    • "Community over code" to me includes rewarding contributions that aren't code. I believe it is important to get people into the foundation that are committed to both our projects as well as the foundation itself - helping us in all sorts of ways, including but not limited to coding, documenting, marketing, mentoring, legal, education and more.
    • "What didn't happen on the mailing list didn't happen" to me means communicating as publicly as possible (while keeping privacy as needed) to enable others to better understand where we are, how we work, what we value and ultimately how to help us. I would like for us to think twice before sending information to private lists - both at the project and at the operational level.
    • I believe we can do better in getting those into the loop who have a vested interest in seeing that our projects are run in a vendor neutral way: Our downstream users who rely on Apache projects for their daily work.
    I am married to a Linux kernel geek working for the Amazon kernel and operating systems team - I've learnt a long time ago that the Open Source world is bigger than just one project, bigger than just one foundation. Expect me to keep the bigger picture in mind during my work here that is not ASF exclusive.

    Much like Bertrand I'm a European - that means I do see value in time spent offline, in being disconnected. I would like to urge others to take that liberty as well - if not for yourselves, then at least to highlight where we are still lacking in terms of number of people that can take care of a vital role.

    As you may have guessed from the time it took for me to accept this nomination, I didn't take the decision lightly. For starters semi-regularly following the discussion on board@ to me feels like there are people way more capable than myself. Seeing just how active people are feels like my time budget is way too limited.

    So what made me accept? I consider myself lucky seeing people nominated for the Apache board who are capable leaders that bring very diverse skills, capabilities and knowledge with them that taken together will make an awesome board of directors.

    I know that with FOSS Backstage one other "pet project of mine" is in capable hands, so I don't need to be involved in it on a day-to-day basis.

    Last but not least I haven't forgotten that back in autumn 2016 Lars Trieloff* told me that I am a role model: Being an ASF director, while still working in tech, with a today three year old at home. As the saying goes "Wege entstehen dadurch, dass man sie geht" - free-form translation: "paths are created by walking them." So instead of pre-emptively declining my nomination I would like to find a way to make the role of being a Director at the Apache Software Foundation something that is manageable for a volunteer. Maybe along that way we'll find a piece in the puzzle to the question of who watches the watchmen - how do we reduce the number of volunteers that we burn through, operating at a sustainable level, enabling people outside of the board of directors to take over or help with tasks.

    * Whom I know through the Apache Dinner/ Lunch Berlin that I used to organise what feels like ages ago. We should totally re-instate that again now that there are so many ASF affiliated people in or close to Berlin. Any volunteers? The one who organises gets to choose date and location after all ;)

    Answers to questions to the board nominees:

    On Thu, Mar 15, 2018 at 01:57:07PM +0100, Daniel Gruno wrote:
    > Missions, Visions...and Decisions:
    > - The ASF exists with a primary goal of "providing open source
    > software to the public, at no charge". What do you consider to be
    > the foundation's most important secondary (implicit) goal?


    I learnt a lot about what is valuable to us in the following discussion:

    https://s.apache.org/hadw

    (and the following public thread over on dev@community with the same subject. My main take-away from there came from Bertrand: The value we are giving back to projects is by providing "A neutral space where they can operate according to our well established best practices."

    The second learning I had just recently when I had the chance of thinking through some of the values that are encoded in our Bylaws that you do not find in those of other organisations: At the ASF you pay for influence with time (someone I respect a lot extended that by stating that you actually pay with time and love).

    > - Looking ahead, 5 years, 10 years...what do you hope the biggest
    > change (that you can conceivably contribute to) to the foundation
    > will be, if any? What are your greatest concerns?


    One year ago I had no idea that little over two months from now we would have something like FOSS Backstage here in Berlin: One thing the ASF has taught me is that predicting the future is futile - the community as a whole will make changes in this world that are way bigger than the individual contributions taken together.

    > < - Which aspect(s) (if any) of the way the ASF operates today are you > least satisfied with? What would you do to change it?

    Those are in my position statement already.

    > #######################################

    > Budget and Operations:
    > - Which roles do you envision moving towards paid roles. Is this the
    > right move, and if not, what can we do to prevent/delay this?
    >

    Honestly I cannot judge what's right and wrong here. I do know that burning through volunteers to me is not an option. What I would like to hear from you as a member is what you would need to step up and do operational tasks at the ASF.

    Some random thoughts: - Do we have the right people in our membership that can fill these operational roles? Are we doing a good enough job in bringing people in with all sorts of backgrounds, who have done all sorts of types of contributions? - Are we doing a good enough job at making transparent where the foundation needs operational help? Are those roles small enough to be filled by one individual?

    This question could be read like today work at the ASF is not paid for. This is far from true - both at the project as well as at the operational level. What I think we need is collective understanding of what the implications of various funding models are: Even if the ASF doesn't accept payment for development doesn't directly imply that projects are more independent as a result. I would assume the same to be true at the operational level.

    > #######################################
    >
    > Membership and Governance:
    > - Should the membership play a more prominent role in
    > decision-making at the ASF? If so, where do you propose this be?


    I may be naive but I still believe in the "those who do the work are those who take decisions". There only close to a dozen people who participated in the "ask the members questionaire" I sent around - something that was troubling for me to see was how pretty much everyone wanted

    > - What would be your take on the cohesion of the ASF, the PMCs, the
    > membership and the communities. Are we one big happy family, or
    > just a bunch of silos? Where do you see it heading, and where do
    > we need to take action, if anywhere?


    If "one big happy family" conjures the picture of people with smiling faces only, than that is a very cheesy image of a family that in my experience doesn't reflect reality of what families typically look like.

    This year at FOSDEM in Brussels we had a dinner table of maybe 15 people (while I did book the table, I don't remember the exact number - over-provisioning and a bit of improvisation helped a lot in making things scale) from various projects, who joined at various times. I do remember a lot of laughter at that table. If anything I think we need the help people to bump into each other face to face independently of their respective project community more often.

    > - If you were in charge of overall community development (sorry,
    > Sharan!), what would you focus on as your primary and secondary
    > goal? How would you implement what you think is needed to achieve
    > this?


    I'm not in charge in that - nor would I want to be, nor should I be. The value I see in the ASF is that we rely very heavily on self organisation, so this foundation is what each individual in it makes out of it - and to me those individuals aren't limited to foundation members, PMC members or even committers. In each Apache Way talk I've seen (and everytime I explain the Apache Way to people) the explanation starts with our projects' downstream users.

    > Show and Tell:

    I'm not much of a show and tell person. At ApacheCon Oakland I once was seeking help with getting a press article about ApacheCon reviewed. It was easy finding a volunteer to proof-read the article. The reason for that ease given by the volunteer themselves? What they got out of their contributions to the ASF was much bigger than anything they put into it. That observation holds true for me as well - and I do hope that this is true for everyone here who is even mildly active.

    Thursday, 22 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 3)

    Paul Boddie's Free Software-related blog » English | 23:24, Thursday, 22 March 2018

    So far, in this exercise of porting L4Re and Fiasco.OC to the Ben NanoNote, we have toured certain parts of the kernel, made adjustments for the compiler to generate suitable code, and added some descriptions of the device itself. But, as we saw, the Ben needs some additional changes to be made to the software in places where certain instructions are used that it doesn’t support. Attempting to compile the kernel will most likely end with an error if we ignore such matters, because although the C and C++ code will produce acceptable instructions, upon encountering an assembly language statement containing an unacceptable instruction, the compiler will probably report something like this:

    Error: opcode not supported on this processor: mips32 (mips32)

    So, we find ourselves in a situation where the compiler is doing the right thing for the code it is generating, but it also notices when the programmer has chosen to do what is now the wrong thing. We must therefore track down these instructions and offer a supported alternative. Previously, we introduced a special configuration setting that might be used to indicate to the compiler when to choose these alternative sequences of instructions: CPU_MIPS32_R1. This gets expanded to CONFIG_CPU_MIPS32_R1 by the build system and it is this identifier that gets used in the program code.

    Those Unsupported Instructions

    I have put off giving out the details so far, but now is as good a time as any to provide some about the instructions that the JZ4720 (the SoC in the Ben NanoNote) doesn’t seem to support. Some of them are just conveniences, offering a single instruction where many would otherwise be needed. Others offer functionality that is not always trivially replicated.

    Instructions Description Privileges
    di, ei Disable, enable interrupts Privileged
    ext Extract bits from register Unprivileged
    ins Insert bits into register Unprivileged
    rdhwr Read hardware register Unprivileged, accesses privileged information
    synci Synchronise instruction cache Unprivileged, performs privileged operations

    We have already mentioned rdhwr, and this is precisely the kind of instruction that can pose problems, these mostly being concerned with it offering access to some (supposedly) privileged information from an unprivileged processor mode. However, since the kernel runs in a privileged mode, typically referred to as “kernel mode”, we won’t see rdhwr when doing our modifications to the kernel. And since the need to provide rdhwr also applied to the JZ4780 (the SoC in the MIPS Creator CI20), it turned out that I didn’t need to do much in addition to what others had already done in supporting it.

    Another instruction that requires a bridging of privilege levels is synci. If we discover synci being used in the kernel, it is possible to rewrite it in terms of the equivalent cache instructions. However, outside the kernel in unprivileged mode, those cache instructions cannot be used and we would not wish to support them either, because “user mode” programs are not meant to be playing around with such aspects of the hardware. The solution for such situations is to “trap” synci when it gets used in unprivileged code and to handle it using the same mechanism as that employed to handle rdhwr: to treat it as a “reserved instruction”.

    Thus, some extra code is added in the kernel to support this “trap” mechanism, but where we can just replace the instructions, we do so as in this example (from kernel/fiasco/src/kern/mips/alternatives.cpp):

    #ifdef CONFIG_CPU_MIPS32_R1
        asm volatile ("cache 0x01, %0\n"
                      "nop\n"
                      "cache 0x08, %0"
                      : : "R"(orig_insn[i]));
    #else
        asm volatile ("synci %0" : : "R"(orig_insn[i]));
    #endif

    We could choose not to bother doing this even in the kernel, instead just trapping all usage of synci. But this would have a performance impact, and L4 is ostensibly very much about performance, and so the opportunity is taken to maximise it by going round and fixing up the code in all these places instead. (Note that I’ve used the nop instruction above, but maybe I should use ehb. It’s probably something to take another look at, perhaps more generally with regard to which instruction I use in these situations.)

    The other unsupported instructions don’t create as many problems. The di (disable interrupts) and ei (enable interrupts) instructions are really shorthand for modifications to the processor’s status register, albeit performing those modifications “atomically”. In principle, in cases where I have written out the equivalent sequence of instructions but not done anything to “guard” these instructions from untimely interruptions or exceptions, something bad could happen that wouldn’t have happened with the di or ei instructions themselves.

    Maybe I will revisit this, too, and see what the risks might actually be, but for the purposes of getting the kernel working – which is where these instructions appear – the minimal solution seemed reasonably adequate. Here is an extract from a statement employing the ei instruction (from kernel/fiasco/src/drivers/mips/processor-mips.cpp):

    #ifdef CONFIG_CPU_MIPS32_R1
        ASM_MFC0 " $t0, $12\n"
        "ehb\n"
        "or $t0, $t0, %[ie]\n"
        ASM_MTC0 " $t0, $12\n"
    #else
        "ei\n"
    #endif

    Meanwhile, the ext (extract) and ins (insert) instructions have similar properties in that they too access parts of registers, replacing sequences of instructions that do the work piece by piece. One challenge that they pose is that they appear in potentially many different places, some with minimal register use, and the equivalent instruction sequence may end up needing an extra register to get the same work done. Fortunately, though, those equivalent instructions are all perfectly usable at whichever privilege level happens to be involved. Here is an extract from a statement employing the ins instruction (from kernel/fiasco/src/kern/mips/thread-mips.cpp):

    #ifdef CONFIG_CPU_MIPS32_R1
           "  andi  $t0, %[status], 0xff  \n"
           "  li    $t1, 0xffffff00       \n"
           "  and   $t2, $t2, $t1         \n"
           "  or    $t2, $t2, $t0         \n"
    #else
           "  ins   $t2, %[status], 0, 8  \n"
    #endif

    Note how temporary registers are employed to isolate the bits from the status register and to erase bits in the $t2 register before these two things are combined and stored in $t2.

    Bridging the Privilege Gap

    The rdhwr instruction has been mentioned quite a few times already. In the kernel, it is handled in the kernel/fiasco/src/kern/mips/exception.S file, specifically in the routine called “reserved_insn”. When the processor encounters an instruction it doesn’t understand, the kernel should have been configured to send it here. I will admit that I knew little to nothing about what to do to handle such situations, but the people who did the MIPS port of the kernel had laid the foundations by supporting one rdhwr variant, and I adapted their work to handle another.

    In essence, what happens is that the processor “shows up” in the reserved_insn routine with the location of the bad instruction in its “exception program counter” register. By loading the value stored at that location, we obtain the instruction – or its value, at least – and can then inspect this value to see if we recognise it and can do anything with it. Here is the general representation of rdhwr with an example of its use:

    SPECIAL3 _____ t s _____ RDHWR
    011111 00000 01000 00001 00000 111011

    The first and last portions of the above representation identify the instruction in general, with the bits for the second and next-to-last portions being set to zero presumably because they are either not needed to encode an instruction in this category, or they encode two parameters that are not needed by this particular instruction. To be honest, I haven’t checked which explanation applies, but I suspect it is the latter.

    This leaves the remaining portions to indicate specific registers: the target (t) and source (s). With t=8, the result is written to register $8, which is normally known as $t0 (or just t0) in MIPS assembly language. Meanwhile, with s=1, the source register has been given as $1, which is the SYNCI_Step hardware register. So, the above is equivalent to the following:

    rdhwr $t0, $1

    To reproduce this same realisation in code, we must isolate the parts of the value that identify the instruction. For rdhwr accessing the SYNCI_Step hardware register, this means using a mask that preserves the SPECIAL3, RDHWR, s and blank regions, ignoring the target register value t because it will change according to specific circumstances. Applying this mask to the instruction value and comparing it to an expected value is done rather like this:

    li $k0, 0x7c00083b # $k0 = SPECIAL3, blank, s=1, blank, RDHWR
    li $at, 0xffe0ffff # $at = define a mask to mask out t
    and $at, $at, $k1  # $at = the mask applied to the instruction value

    Now, if $at is equal to $k0, the instruction value is identified as encoding rdhwr accessing SYNCI_Step, with the target register being masked out so as not to confuse things. Later on, the target register is itself selected and some trickery is employed to get the appropriate data into that register before returning from this routine.

    For the above case and for the synci instruction, the work that needs doing once such an instruction has been identified is equivalent to what would have happened had it been possible to just insert into the code the alternative sequence of instructions that achieves the same thing. So, for synci, the equivalent cache instructions are executed before control is returned to the instruction after synci in the program where it appeared. Thus, upon encountering an unsupported instruction, control is handed over from an unprivileged program to the kernel, the instruction is identified and handled using the necessary privileged instructions, and then control is handed back to the unprivileged program again.

    In fact, most of my efforts in exception.S were not really directed towards these two awkward instructions. Instead I had to deal with the use of quite a number of ext and ins instructions. Although it seems tempting to just trap those as well and to provide handlers for them, that would add considerable overhead, and so I added some macros to provide the same functionality when building the kernel for the Ben.

    Prepare for Launch

    Looking at my patches for the kernel now, I can see that there isn’t much else to cover. One or two details are rather important in the context of the Ben and how it manages to boot, however, and the process of figuring out those details was, like much else in this exercise, time-consuming, slightly frustrating, and left surprisingly little trace once the solution was found. At this stage, not everything was perfectly transcribed or expressed, leaving a degree of debugging activity that would also need to be performed in the future.

    So, with a kernel that might be runnable, I considered what it would take to actually launch that kernel. This led me into the L4 Runtime Environment (L4Re) code and specifically to the bootstrap package. It turns out that the kernel distribution delegates such concerns to other software, and the bootstrap package sits uneasily alongside other packages, it being perhaps the only one amongst them that can exercise as much privilege as the kernel because its code actually runs at boot time before the kernel is started up.

    Wednesday, 21 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 2)

    Paul Boddie's Free Software-related blog » English | 23:25, Wednesday, 21 March 2018

    Having undertaken some initial investigations into running L4Re and Fiasco.OC on the MIPS Creator CI20, I envisaged attempting to get this software running on the Ben NanoNote, too. For a while, I put this off, feeling confident that when I finally got round to it, it would probably be a matter of just choosing the right compiler options and then merely fixing all the mistakes I had made in my own driver code. Little did I know that even the most trivial activities would prove more complicated than anticipated.

    As you may recall, I had noted that a potentially viable approach to porting the software would merely involve setting the appropriate compiler switches for “soft-float” code, thus avoiding the generation of floating point instructions that the JZ4720 – the SoC on the Ben NanoNote – would not be able to execute. A quick check of the GCC documentation indicated the availability of the -msoft-float switch. And since I have a working cross-compiler for MIPS as provided by Debian, there didn’t seem to be much more to it than that. Until I discovered that the compiler doesn’t seem to support soft-float output at all.

    I had hoped to avoid building my own cross-compiler, and apart from enthusiastic (and occasionally successful) attempts to build the Debian ones before they became more generally available, the last time I really had anything to do with this was when I first developed software for the Ben. As part of the general support for the device an OpenWrt distribution had been made available. Part of that was the recipe for building the cross-compiler and other tools, needed for building a kernel and all the software one would deploy on a device. I am sure that this would still be a good place to look for a solution, but I had heard things about Buildroot and so set off to investigate that instead.

    So although Buildroot, like OpenWrt, is promoted as a way of building an entire system, it too offers help in building just the toolchain if that is all you need. Getting it to build the appropriately-configured cross-compiler is a matter of the familiar “make menuconfig” seen from the Linux kernel source distribution, choosing things in a menu – for us, asking for a soft-float toolchain, also enabling C++ support – and then running “make toolchain”. As a result, I got a range of tools in the output/host/bin directory prefixed with mipsel-buildroot-linux-uclibc.

    Some Assembly Required

    Changing the compiler settings for Fiasco.OC (in kernel/fiasco/src/Makeconf.mips) and L4Re (in l4/mk/arch/Makeconf.mips), and making sure not to enable any floating point support in Fiasco.OC, and recompiling the code to produce soft-float output was straightforward enough. However, despite the portability of this software, it isn’t completely C and C++ code: lurking in various places (typically in mips or ARCH-mips directories) are assembly language source files with the .S prefix, and in some C and C++ files one can also find “asm” statements which embed assembly language instructions within higher-level code.

    With the assumption that by specifying the right compiler switches, no floating point instructions will be produced from C or C++ source code, all that remains is to determine whether any of these other code sections mention such forbidden instructions. It was asserted that Fiasco.OC doesn’t use any floating point instructions at all. Meanwhile, I couldn’t find any floating point instructions in the generated code: “mipsel-linux-gnu-objdump -D some-output-file” (or, indeed, “mipsel-buildroot-linux-uclibc-objdump -D some-output-file”) now started to become a familiar acquaintance if not exactly a friend!

    In fact, the assembly language files and statements would provide other challenges in the form of instructions unsupported by the JZ4720. Again, I had the choice of either trying to support MIPS32r2 instructions, like rdhwr, by providing “reserved instruction” handlers, or to rewrite these instructions in forms suitable for the JZ4720. At least within Fiasco.OC – the “kernel” – where the environment for executing instructions is generally privileged, it is possible to reformulate MIPS32r2 instructions in terms of others. I will return to the details of these instructions later on.

    Where to Find Things

    Having spent all this time looking around in the L4Re and Fiasco.OC code, it is perhaps worth briefly mentioning where certain things can be found. The heart of the action in the kernel is found in these places:

    Directory Significance
    kernel/fiasco/src The top-level directory of the kernel sources, having some MIPS-specific files
    kernel/fiasco/src/drivers/mips Various hardware abstractions related to MIPS
    kernel/fiasco/src/jdb/mips MIPS-specific support code for the kernel debugger (which I don’t use)
    kernel/fiasco/src/kern/mips MIPS-specific support code for the kernel itself
    kernel/fiasco/src/templates Device configuration details

    As noted above, I don’t use the kernel debugger, but I still made some edits that might make it possible to use it later on. For the most part, the bulk of my time and effort was spent in the src/kern/mips hierarchy, occasionally discovering things in src/drivers/mips that also needed some attention.

    Describing the Ben

    So it started to make sense to consider how the Ben might be described in terms of a kernel configuration, and whether we might want to indicate a less sophisticated revision of the architecture so that we could test for it in the code and offer alternative sequences of instructions where possible. There are a few different places where hardware platforms are described within Fiasco.OC, and I ended up defining the following:

    • An architecture version (MIPS32r1) for the JZ4720 (in kernel/fiasco/src/kern/mips/Kconfig)
    • A definition for the Ben itself (in kernel/fiasco/src/templates/globalconfig.out.mips-qi_lb60)
    • A board entry for the Ben (in kernel/fiasco/src/kern/mips/bsp/qi_lb60/Kconfig) as part of a board-specific collection of functionality

    This is not by any means enough, even disregarding any code required to do things specific to the Ben. But with the additional configuration setting for the JZ4720, which I called CPU_MIPS32_R1, it becomes possible to go around inside the kernel code and start to mark up places which need different instruction sequences for the Ben, using CONFIG_CPU_MIPS32_R1 as the symbol corresponding to this setting in the code itself. There are places where this new setting will also change the compiler’s behaviour: in kernel/fiasco/src/Makeconf.mips, the -march=mips32 compiler switch is activated by the setting, preventing the compiler from generating instructions we do not want.

    For the board-specific functionality (found in kernel/fiasco/src/kern/mips/bsp/qi_lb60), I took the CI20′s collection of files as a starting point. Fortunately for me, the Ben’s JZ4720 and the CI20′s JZ4780 are so similar that I could, with reference to Linux kernel code and other sources of documentation, make a first effort at support for the Ben by transcribing and editing these files. Some things I didn’t understand straight away, and I only later discovered what some parameters to certain methods really mean.

    But generally, this work was simply a matter of seeing what peripheral registers were mentioned in the CI20 version, figuring out whether those registers were present in the earlier SoC, and determining whether their locations were the same or whether they had been moved around from one product to the next. Let us take a brief look at the registers associated with the timer/counter unit (TCU) in the JZ4720 and JZ4780 (with apologies for WordPress converting “x” into a multiplication symbol in some places):

    JZ4720 (Ben NanoNote) JZ4780 (MIPS Creator CI20)
    Registers Offsets Size Registers Offsets Size
    TER, TESR, TECR (timer enable, set, clear) 0×10, 0×14, 0×18 8-bit TER, TESR, TECR (timer enable, set, clear) 0×10, 0×14, 0×18 16-bit
    TFR, TFSR, TFCR (timer flag, set, clear) 0×20, 0×24, 0×28 32-bit TFR, TFSR, TFCR (timer flags, set, clear) 0×20, 0×24, 0×28 32-bit
    TMR, TMSR, TMCR (timer mask, set, clear) 0×30, 0×34, 0×38 32-bit TMR, TMSR, TMCR (timer mask, set, clear) 0×30, 0×34, 0×38 32-bit
    TDFR0, TDHR0, TCNT0, TCSR0 (timer data full match, half match, counter, control) 0×40, 0×44, 0×48, 0x4c 16-bit TDFR0, TDHR0, TCNT0, TCSR0 (timer data full match, half match, counter, control) 0×40, 0×44, 0×48, 0x4c 16-bit
    TSR, TSSR, TSCR (timer stop, set, clear) 0x1c, 0x2c, 0x3c 8-bit TSR, TSSR, TSCR (timer stop, set, clear) 0x1c, 0x2c, 0x3c 32-bit

    We can see how the later product (JZ4780) has evolved from the earlier one (JZ4720), with some registers supporting more bits, exposing control over an increased number of timers. A lot of the details are the same, which was fortunate for me! Even the oddly-located timer stop registers, separated by intervals of 16 bytes (0×10) instead of 4 bytes, have been preserved between the products.

    One interesting difference is the absence of the “operating system timer” in the JZ4720. This is a 64-bit counter provided by the JZ4780, but for the Ben it seems that we have to make do with the standard 16-bit timers provided by both products. Otherwise, for this part of the hardware, it is a matter of making sure the fundamental operations look reasonable – whether the registers are initialised sensibly – and then seeing how this functionality is used elsewhere. A file called tcu_jz4740.cpp in the board-specific directory for the Ben preserves this information. (Note that the JZ4720 is largely the same as the JZ4740 which can be considered as a broader product category that includes the JZ4720 as a variant with slightly reduced functionality.)

    In the same directory, there is a file covering timer functionality from the perspective of the kernel: timer-jz4740.cpp. Here, the above registers are manipulated to realise certain operations – enabling and disabling timers, reading them, indicating which interrupt they may cause – and the essence of this work again involves checking documentation sources, register layouts, and making sure that the intent of the code is preserved. It may be mundane work, but any little detail that is not correct may prevent the kernel from working.

    Covering the Ground

    At this point, the essential hardware has mostly been described, building on all the work done by others to port the kernel to the MIPS architecture and to the CI20, merely adding a description of the differences presented by the Ben. When I made these changes, I was slowly immersing myself in the code, writing things that I felt I mostly understood from having previously seen code accessing certain hardware features of the Ben. But I knew that there will still some way to go before being able to expect anything to actually work.

    From this point, I would now need to confront the unimplemented instructions, deal with the memory layout, and figure out how the kernel actually gets launched in the first place. This would also mean that I could no longer keep just adding and changing code and feeling like progress was being made: I would actually have to try and get the Ben to run something. And as those of us who write software know very well, there can be nothing more punishing than being confronted with the behaviour of a program that is incorrect, with the computer caring not about intentions or aspirations but only about executing the logic whether it is correct or not.

    Tuesday, 20 March 2018

    Porting L4Re and Fiasco.OC to the Ben NanoNote (Part 1)

    Paul Boddie's Free Software-related blog » English | 23:09, Tuesday, 20 March 2018

    For quite some time, I have been interested in alternative operating system technologies, particularly kernels beyond the likes of Linux. Things like the Hurd and technologies associated with it, such as Mach, seem like worthy initiatives, and contrary to largely ignorant and conveniently propagated myths, they are available and usable today for anyone bothered to take a look. Indeed, Mach has had quite an active life despite being denigrated for being an older-generation microkernel with questionable performance credentials.

    But one technological branch that has intrigued me for a while has been the L4 family of microkernels. Starting out with the motivation to improve microkernel performance, particularly with regard to interprocess communication, different “flavours” of L4 have seen widespread use and, like Mach, have been ported to different hardware architectures. One of these L4 implementations, Fiasco.OC, appeared particularly interesting in this latter regard, in addition to various other features it offers over earlier L4 implementations.

    Meanwhile, I have had some success with software and hardware experiments with the Ben NanoNote. As you may know or remember, the Ben NanoNote is a “palmtop” computer based on an existing design (apparently for a pocket dictionary product) that was intended to offer a portable computing experience supported entirely by Free Software, not needing any proprietary drivers or firmware whatsoever. Had the Free Software Foundation been certifying devices at the time of its introduction, I imagine that it would have received the “Respects Your Freedom” certification. So, it seems to me that it is a worthy candidate for a Free Software porting exercise.

    The Starting Point

    Now, it so happened that Fiasco.OC received some attention with regards to being able to run on the MIPS architecture. The Ben NanoNote employs a system-on-a-chip (SoC) whose own architecture closely (and deliberately) resembles the MIPS architecture, but all information about the JZ4720 SoC specifies “XBurst” as the architecture name. In fact, one can regard XBurst as a clone of a particular version of the MIPS architecture with some additional instructions.

    Indeed, the vendor, Ingenic, subsequently licensed the MIPS architecture, produced some SoCs that are officially MIPS-labelled, culminating in the production of the MIPS Creator CI20 product: a development board commissioned by the then-owners of the MIPS portfolio, Imagination Technologies, utilising the Ingenic JZ4780 SoC to presumably showcase the suitability of the MIPS architecture for various applications. It was apparently for this product that an effort was made to port Fiasco.OC to MIPS, and it was this effort that managed to attract my attention.

    The MIPS Creator CI20 single-board computer

    The MIPS Creator CI20 single-board computer

    It was just as well others had done this hard work. Although I have been gradually immersing myself in the details of how MIPS-based CPUs function, having written some code that can boot the Ben, run a few things concurrently, map memory for different processes, read the keyboard and show things on the screen, I doubt that my knowledge is anywhere near comprehensive enough to tackle porting an existing operating system kernel. But knowing that not only had others done this work, but they had also targeted a rather similar system, gave me some confidence that I might be able to perform the relatively minor porting exercise to target the Ben.

    But first I felt that I had to gain experience with Fiasco.OC on MIPS in a more convenient fashion. Although I had muddled through the development of code on the Ben, reusing existing framebuffer driver code and hacking away until I managed to get some output on the display, I felt that if I were to continue my experiments, a more efficient way of debugging my code would be required. With this in mind, I purchased a MIPS Creator CI20 and, after doing things with the pre-installed Debian image plus installing a newer version of Debian, I set out to try Fiasco.OC on the hardware.

    The Missing Pieces

    According to the Fiasco.OC features page, the “Ci20″ is supported. Unfortunately, this assertion of support is not entirely true, as we will come to see. Previously, I mentioned that the JZ4720 in the Ben NanoNote largely implements the instructions of a certain version of the MIPS architecture. Although the JZ4780 in the CI20 introduces some new features over the JZ4720, such as a floating point arithmetic unit, it still lacks various instructions that are present in commonly-used MIPS versions that might be taken as the “baseline” for software support: MIPS32 Release 2 (MIPS32r2), for instance.

    Upon trying to get Fiasco.OC to start up, I soon encountered one of these instructions, or at least a particular variant of it: rdhwr (read hardware register) accessing SYNCI_Step (the instruction cache line size). This sounds quite fearsome, but I had been somewhat exposed to cache management operations when conjuring up my own code to run on the Ben. In fact, all this instruction variant does is to ask how big the step size has to be in a loop that invalidates the instruction cache, instead of stuffing such a value into the program when compiling it and thus making an executable that will then be specific to a particular processor.

    Fortunately, those hardworking people who had already ported the code to MIPS had previously encountered another rdhwr variant and had written code to “trap” it in the “reserved instruction” handler. That provided some essential familiarisation with the kernel code, saving me the effort of having to identify the right place to modify, as well as providing a template for how such handlers should operate. I feel fairly competent writing MIPS assembly language, although I would manage to make an easy mistake in this code that would impede progress much later on.

    There were one or two other things that also needed fixing up, mentioned briefly in my review of the year article, generally involving position-independent code that was not called correctly and may have been related to me using a generic version of GCC instead of some vendor-modified version. But as I described in that article, I finally managed to boot Fiasco.OC and run a program on top of it, writing the output via the serial connection to my personal computer.

    The End of the Very Beginning

    I realised that compiling such code for the Ben would either require the complete avoidance of floating point instructions, due to the lack of that floating point unit in the JZ4720, or that I would need to provide implementations of those instructions in software. Fortunately, GCC provides a mode to compile “soft-float” versions of C and C++ programs, and so this looked like the next step. And so, apart from polishing support for features of the Ben like the framebuffer, input/output pins, the clock circuitry, it didn’t really seem that there would be so much to do.

    As it so often turns out with technology, optimism can lead to unrealistic estimates of how much time and effort remains in a project. I now know that a description of all this effort would be just too much for a single article. So, I will wrap this article up with a promise that the next one will descend into the details of compilers, assembly language, the SoC, and before too long, we will get to see the inconvenience of debugging low-level software with nothing more than a framebuffer.

    Migrating to PowerDNS

    Evaggelos Balaskas - System Engineer | 18:47, Tuesday, 20 March 2018

    A few years ago, I migrated from ICS Bind Authoritative Server to PowerDNS Authoritative Server.

    Here was my configuration file:

    # egrep -v '^$|#' /etc/pdns/pdns.conf 
    
    dname-processing=yes
    launch=bind
    bind-config=/etc/pdns/named.conf
    
    local-address=MY_IPv4_ADDRESS
    local-ipv6=MY_IPv6_ADDRESS
    
    setgid=pdns
    setuid=pdns

    Α quick reminder, a DNS server is running on tcp/udp port53.


    I use dnsdist (a highly DNS-, DoS- and abuse-aware loadbalancer) in-front of my pdns-auth, so my configuration file has a small change:

    local-address=127.0.0.1
    local-port=5353

    instead of local-address, local-ipv6

    You can also use pdns without dnsdist.


    My named.conf looks like this:

    # cat /etc/pdns/named.conf
    
    zone "balaskas.gr" IN {
        type master;
        file "/etc/pdns/var/balaskas.gr";
    };

    So in just a few minutes of work, bind was no more.
    You can read more on the subject here: Migrating to PowerDNS.


    Converting from Bind zone files to SQLite3

    PowerDNS has many features and many Backends. To use some of these features (like the HTTP API json/rest api for automation, I suggest converting to the sqlite3 backend, especially for personal or SOHO use. The PowerDNS documentation is really simple and straight-forward: SQLite3 backend

    Installation

    Install the generic sqlite3 backend.
    On a CentOS machine type:

    # yum -y install pdns-backend-sqlite

    Directory

    Create the directory in which we will build and store the sqlite database file:

    # mkdir -pv /var/lib/pdns

    Schema

    You can find the initial sqlite3 schema here:

    /usr/share/doc/pdns/schema.sqlite3.sql

    you can also review the sqlite3 database schema from github

    If you cant find the schema.sqlite3.sql file, you can always download it from the web:

    # curl -L -o /var/lib/pdns/schema.sqlite3.sql  \
       https://raw.githubusercontent.com/PowerDNS/pdns/master/modules/gsqlite3backend/schema.sqlite3.sql

    Create the database

    Time to create the database file:

    # cat /usr/share/doc/pdns/schema.sqlite3.sql | sqlite3 /var/lib/pdns/pdns.db

    Migrating from files

    Now the difficult part:

    # zone2sql --named-conf=/etc/pdns/named.conf -gsqlite | sqlite3 /var/lib/pdns/pdns.db
    
    100% done
    7 domains were fully parsed, containing 89 records

    Migrating from files - an alternative way

    If you have already switched to the generic sql backend on your powerdns auth setup, then you can use: pdnsutil load-zone command.

    # pdnsutil load-zone balaskas.gr /etc/pdns/var/balaskas.gr 
    
    Mar 20 19:35:34 Reading random entropy from '/dev/urandom'
    Creating 'balaskas.gr'

    Permissions

    If you dont want to read error messages like the below:

    sqlite needs to write extra files when writing to a db file

    give your powerdns user permissions on the directory:

    # chown -R pdns:pdns /var/lib/pdns

    Configuration

    Last thing, make the appropriate changes on the pdns.conf file:

    ## launch=bind
    ## bind-config=/etc/pdns/named.conf
    
    launch=gsqlite3
    gsqlite3-database=/var/lib/pdns/pdns.db
    

    Reload Service

    Restarting powerdns daemon:

    # service pdns restart
    
    Restarting PowerDNS authoritative nameserver: stopping and waiting..done
    Starting PowerDNS authoritative nameserver: started
    

    Verify

    # dig @127.0.0.1 -p 5353  -t soa balaskas.gr +short 
    
    ns14.balaskas.gr. evaggelos.balaskas.gr. 2018020107 14400 7200 1209600 86400

    or

    # dig @ns14.balaskas.gr. -t soa balaskas.gr +short
    
    ns14.balaskas.gr. evaggelos.balaskas.gr. 2018020107 14400 7200 1209600 86400

    perfect!


    Using the API

    Having a database as pdns backend, means that we can use the PowerDNS API.

    Enable the API

    In the pdns core configuration file: /etc/pdns/pdns.conf enable the API and dont forget to type a key.

    api=yes
    api-key=0123456789ABCDEF
    

    The API key is used for authorization, by sending it through the http headers.

    reload the service.

    Testing API

    Using curl :

    # curl -s -H 'X-API-Key: 0123456789ABCDEF' http://127.0.0.1:8081/api/v1/servers

    The output is in json format, so it is prefable to use jq

    # curl -s -H 'X-API-Key: 0123456789ABCDEF' http://127.0.0.1:8081/api/v1/servers | jq .

    [
      {
        "zones_url": "/api/v1/servers/localhost/zones{/zone}",
        "version": "4.1.1",
        "url": "/api/v1/servers/localhost",
        "type": "Server",
        "id": "localhost",
        "daemon_type": "authoritative",
        "config_url": "/api/v1/servers/localhost/config{/config_setting}"
      }
    ]
    

    jq can also filter the output:

    # curl -s -H 'X-API-Key: 0123456789ABCDEF' http://127.0.0.1:8081/api/v1/servers | jq .[].version
    "4.1.1"

    Zones

    Getting the entire zone from the database and view all the Resource Records - sets:

    # curl -s -H 'X-API-Key: 0123456789ABCDEF' http://127.0.0.1:8081/api/v1/servers/localhost/zones/balaskas.gr

    or just getting the serial:

    # curl -s -H 'X-API-Key: 0123456789ABCDEF' http://127.0.0.1:8081/api/v1/servers/localhost/zones/balaskas.gr | \
      jq .serial
    
    2018020107

    or getting the content of SOA type:

    # curl -s -H 'X-API-Key: 0123456789ABCDEF' http://127.0.0.1:8081/api/v1/servers/localhost/zones/balaskas.gr | \
      jq '.rrsets[] | select( .type | contains("SOA")).records[].content '
    
    "ns14.balaskas.gr. evaggelos.balaskas.gr. 2018020107 14400 7200 1209600 86400"
    

    Records

    Creating or updating records is also trivial.
    Create the Resource Record set in json format:

    
    # cat > /tmp/test.text <<EOF
    {
        "rrsets": [
            {
                "name": "test.balaskas.gr.",
                "type": "TXT",
                "ttl": 86400,
                "changetype": "REPLACE",
                "records": [
                    {
                        "content": ""Test, this is a test ! "",
                        "disabled": false
                    }
                ]
            }
        ]
    }
    
    EOF
    

    and use the http Patch method to send it through the API:

    # curl -s -X PATCH -H 'X-API-Key: 0123456789ABCDEF' --data @/tmp/test.text \
        http://127.0.0.1:8081/api/v1/servers/localhost/zones/balaskas.gr | jq . 

    Verify Record

    We can use dig internal:

    # dig -t TXT test.balaskas.gr @127.0.0.1 -p 5353 +short
    "Test, this is a test ! "

    querying public dns servers:

    $ dig test.balaskas.gr txt +short @8.8.8.8
    "Test, this is a test ! "
    
    $ dig test.balaskas.gr txt +short @9.9.9.9
    "Test, this is a test ! "
    

    or via the api:

    # curl -s -H 'X-API-Key: 0123456789ABCDEF' http://127.0.0.1:8081/api/v1/servers/localhost/zones/balaskas.gr | \
       jq '.rrsets[].records[] | select (.content | contains("test")).content'
    
    ""Test, this is a test ! ""

    That’s it.

    Tag(s): powerdns, sqlite, api

    Can a GSoC project beat Cambridge Analytica at their own game?

    DanielPocock.com - fsfe | 12:15, Tuesday, 20 March 2018

    A few weeks ago, I proposed a GSoC project on the topic of Firefox and Thunderbird plugins for Free Software Habits.

    At first glance, this topic may seem innocent and mundane. After all, we all know what habits are, don't we? There are already plugins that help people avoid visiting Facebook too many times in one day, what difference will another one make?

    Yet the success of companies like Facebook and those that prey on their users, like Cambridge Analytica (who are facing the prospect of a search warrant today), is down to habits: in other words, the things that users do over and over again without consciously thinking about it. That is exactly why this plugin is relevant.

    Many students have expressed interest and I'm keen to find out if any other people may want to act as co-mentors (more information or email me).

    One Facebook whistleblower recently spoke about his abhorrence of the dopamine-driven feedback loops that keep users under a spell.

    The game changer

    Can we use the transparency of free software to help users re-wire those feedback loops for the benefit of themselves and society at large? In other words, instead of letting their minds be hacked by Facebook and Cambridge Analytica, can we give users the power to hack themselves?

    In his book The Power of Habit, Charles Duhigg lays bare the psychology and neuroscience behind habits. While reading the book, I frequently came across concepts that appeared immediately relevant to the habits of software engineers and also the field of computer security, even though neither of these topics is discussed in the book.

    where is my cookie?

    Most significantly, Duhigg finishes with an appendix on how to identify and re-wire your habits and he has made it available online. In other words, a quickstart guide to hack yourself: could Duhigg's formula help the proposed plugin succeed where others have failed?

    If you could change one habit, you could change your life

    The book starts with examples of people who changed a single habit and completely reinvented themselves. For example, an overweight alcoholic and smoker who became a super-fit marathon runner. In each case, they show how the person changed a single keystone habit and everything else fell into place. Wouldn't you like to have that power in your own life?

    Wouldn't it be even better to share that opportunity with your friends and family?

    One of the challenges we face in developing and promoting free software is that every day, with every new cloud service, the average person in the street, including our friends, families and co-workers, is ingesting habits carefully engineered for the benefit of somebody else. Do you feel that asking your friends and co-workers not to engage you in these services has become a game of whack-a-mole?

    Providing a simple and concise solution, such as a plugin, can help people to find their keystone habits and then help them change them without stress or criticism. Many people want to do the right thing: if it can be made easier for them, with the right messages, at the right time, delivered in a positive manner, people feel good about taking back control. For example, if somebody has spent 15 minutes creating a Doodle poll and sending the link to 50 people, is there any easy way to communicate your concerns about Doodle? If a plugin could highlight an alternative before they invest their time in Doodle, won't they feel better?

    If you would like to provide feedback or even help this project go ahead, you can subscribe here and post feedback to the thread or just email me.

    cat plays whack-a-mole

    Monday, 19 March 2018

    KDE Applications 18.04 branches created

    TSDgeos' blog | 22:23, Monday, 19 March 2018

    Make sure you commit anything you want to end up in the KDE Applications 18.04 release to them :)

    We're already past the dependency freeze.

    The Freeze and Beta is this Thursday 22 of March.

    More interesting dates
    April 5: KDE Applications 18.04 RC (18.03.90) Tagging and Release
    April 12: KDE Applications 18.04 Tagging
    April 19: KDE Applications 18.04 Release

    https://community.kde.org/Schedules/Applications/18.04_Release_Schedule

    Planet FSFE (en): RSS 2.0 | Atom | FOAF |

      /var/log/fsfe/flx » planet-en  Albrechts Blog  Alessandro at FSFE » English  Alessandro's blog  Alina Mierlus - Building the Freedom » English  Andrea Scarpino's blog  André Ockers on Free Software  Being Fellow #952 of FSFE » English  Bela's Internship Blog  Bernhard's Blog  Bits from the Basement  Blog of Martin Husovec  Blog » English  Blog – Think. Innovation.  Bobulate  Brian Gough's Notes  Carlo Piana :: Law is Freedom ::  Ciarán's free software notes  Colors of Noise - Entries tagged planetfsfe  Communicating freely  Computer Floss  Daniel Martí's blog  Daniel's FSFE blog  DanielPocock.com - fsfe  David Boddie - Updates (Full Articles)  Don't Panic » English Planet  ENOWITTYNAME  English Planet – Dreierlei  English on Björn Schießle - I came for the code but stayed for the freedom  English – Kristi Progri  English – Max's weblog  English — mina86.com  Escape to freedom  Evaggelos Balaskas - System Engineer  FLOSS – Creative Destruction & Me  FSFE Fellowship Vienna » English  FSFE interviews its Fellows  FSFE – Patis Blog  Fellowship News  Fellowship News » Page not found  Florian Snows Blog » en  Frederik Gladhorn (fregl) » FSFE  Free Software & Digital Rights Noosphere  Free Software with a Female touch  Free Software –  Free Software – Frank Karlitschek_  Free Software – GLOG  Free Software – hesa's Weblog  Free as LIBRE  Free speech is better than free beer » English  Free, Easy and Others  From Out There  Giacomo Poderi  Graeme's notes » Page not found  Green Eggs and Ham  Handhelds, Linux and Heroes  HennR's FSFE blog  Henri Bergius  Hook’s Humble Homepage  Hugo - FSFE planet  Inductive Bias  Jelle Hermsen » English  Jens Lechtenbörger » English  Karsten on Free Software  Losca  MHO  Mario Fux  Martin's notes - English  Matej's blog » FSFE  Matthias Kirschner's Web log - fsfe  Myriam's blog  Mäh?  Nice blog  Nico Rikken » fsfe  Nicolas Jean's FSFE blog » English  Norbert Tretkowski  PB's blog » en  Paul Boddie's Free Software-related blog » English  Planet FSFE on Iain R. Learmonth  Posts - Carmen Bianca Bakker's blog  Posts on Hannes Hauswedell's homepage  Pressreview  Ramblings of a sysadmin (Posts about planet-fsfe)  Rekado  Repentinus » English  Riccardo (ruphy) Iaconelli - blog  Saint's Log  Seravo  TSDgeos' blog  Tarin Gamberini  Technology – Intuitionistically Uncertain  The Girl Who Wasn't There » English  The trunk  Thib's Fellowship Blog » fsfe  Thinking out loud » English  Thomas Koch - free software  Thomas Løcke Being Incoherent  Told to blog - Entries tagged fsfe  Tonnerre Lombard  Torsten's FSFE blog » english  Viktor's notes » English  Vitaly Repin. Software engineer's blog  Weblog  Weblog  Weblog  Weblog  Weblog  Weblog  Werner's own blurbs  With/in the FSFE » English  a fellowship ahead  agger's Free Software blog  anna.morris's blog  ayers's blog  bb's blog  blog  drdanzs blog » freesoftware  egnun's blog » FreeSoftware  free software - Bits of Freedom  free software blog  freedom bits  gollo's blog » English  julia.e.klein's blog  marc0s on Free Software  mkesper's blog » English  nikos.roussos - opensource  pichel's blog  polina's blog  rieper|blog » en  softmetz' anglophone Free Software blog  stargrave's blog  the_unconventional's blog » English  things i made  tobias_platen's blog  tolld's blog  vanitasvitae's blog » englisch  wkossen's blog  yahuxo's blog