The previous article laid the ground for (cross-)building VLC on RISC-V in general and Linux in particular, without needing any actual hardware. The logical next step would be testing in an emulator or simulator.
That being said, VLC only really a C run-time environment. Unlike a boot-loader, a kernel or the run-time linker, VLC can nominally run with (Linux) OS-specific but without any architecture-dependent code. Indeed the bulk of platform-specific code in VLC and dependent libraries such as FFmpeg consists of SIMD optimisations, which are not essential (until you need their performance benefits).
There are of course some architecture dependencies still, but at the C language level, RISC-V is mostly like ARM: they are both RISC instruction sets with little-endian LP64 (or LPI32) types, and no unaligned memory accesses. Thus I naively thought that I could skip the emulation and wait for hardware. With the benefits of hindsight, I was of course (surprise surprise) wrong.
My RISC-V activities are suboptimally conducted outside business hours and mostly on my free time. If you are looking for a senior system software engineer with RISC-V experience, see my my LinkedIn profile.
char
See the problem is, VLC has a test suite (with sadly very poor coverage), which is being checked as part of Continuous Integration. But it is only actually checked on Linux x86-64. And there is one not so subtle difference between RISC-V (also ARM) and x86 when it comes to C programming:
char
is a signed type (by default)
for consistency with all other integer types.
In the end, this is about as much of a pitfall as a feature.
Consistency is good and all, but programmers rarely need
to manipulate bytes as signed quantities.
In fact, most standard C functions manipulating bytes expect
unsigned values up-converted to int
,
so between 0 and 255 rather than -128 and 127
(e.g. memchr
, getc
).
char
is unsigned.
As I understand it, the C specifications permit this behaviour,
albeit only for the char
type.
The rationale is that some instruction sets back in the days
did not support sign-extended 8-bit memory loads.
ARMv4 and later versions do feature loads with sign extension
loads, but presumably not the older no longer documented
versions 1 through 3.
char
be unsigned,
though I would be surprised if such backward-incompatible
change was ever taken into future versions of the C language.
So anyway, it turns out that the test suite was broken on RISC-V, and also on ARM, and nobody had noticed. I would only find that out once I ran the test suite on real hardware though.
Fortunately all is well that ends well still. I got real working hardware:
$ cat /proc/cpuinfo processor : 0 hart : 0 isa : rv64imafdc mmu : sv39 uarch : sifive,u74-mc processor : 1 hart : 1 isa : rv64imafdc mmu : sv39 uarch : sifive,u74-mc
...and the problem was fixed within a day, only few weeks later than it otherwise could have been. The VLC test suite now runs succesfully on Linux RISC-V, and more importantly and interestingly, so does VLC itself!