I think Duo is a great board, and I’m planning to use CV1800B SoC in one of my upcoming projects. But the thing that makes me scratch my head is that only first RISC-V core (1GHz one) can be used to run Linux, while the other one (700 MHz one) may only run simpler RTOS. I was curious why is that and tried to look for a reason for that limitation, but found nothing. This post of a Milk-V representative simply states that second core just won’t run Linux, even if it’s not used to run RTOS. But otherwise there are no information whatsoever that clarify the reason for which second core would not be usable on Linux. CV1800B datasheet also doesn’t contain any information on that matter.
So, what is technical reason that second RISC-V core can’t be used under Linux? Both cores are described as C906, so they should have identical structure under the hood. The only visible difference is in their speed, but I don’t think that’s enough of a reason for one core to be completely unusable under Linux just because it’s slower. In fact, desktop CPUs tend to have variable speeds for each of their core depending on the workload and the system somehow manages it. So then again - what limits the second core so that Linux could not use it?
While they are both C906, that is just the name of the cores design by Xuantie that implements the RISC-V 64-bit architecture. It does not mean they are the same at all, as the implementation can be with different features turned on and off depending on the use case. Most processor designs from any ISA are like this, but not all MCU/SOC designers combine them as such - it requires a specific use case, like Milk-V have done with their Duo series. With this implementation, they are operating in two different domains, thus at the most basic level: if one crashes, the other doesn’t.
On to your query re the technical reason.
The primary C906 core is 1GHz and off the top of my head its specification is RV64IMAFDCV. Note that the ‘V’ there as it’s the RVV 0.71 ‘T-Head’ extensions from what I know, not the real RVV implementation - albeit apparently just as good. Those ‘IMADFC’ extensions though, which can also be summarised as ‘GC’ as best I know, are essentially the minimum requirements for running Linux in most cases. Technically you can probably run Linux on RV64IMAF but that’d be a custom build/patching most likely.
The second core in these SOCs is both C906 and 700MHz as you stated, but a different configuration of that design. It firstly lacks an L2 cache like the main core has, which is going to add notable hinderance to the core trying to make use of the DDR subsystem aka RAM. Secondly though, this is RV64IMFD from what I recall. This means it’s lacking Atomic instructions, and 16-bit compressed instructions. Both of these are essentially mandatory to run Linux.
So the way this is instead designed, is that the lesser core can run RTOS applications, such as FreeRTOS, Arduino, or your own custom code to provide ancillary, low power or watchdog services. It can then communicate with the primary OS core via the implemented mailbox.
That was from me using it, not from reading. Might have even been RV64IMAC.
I did a quick Google search though and found the Duo Arduino code (that runs on the smaller core) is compiled with -march=rv64imfd, so I think I was right the first time.
The freertos code from the duo-buildroot-sdk is compiled with -march=rv64imafdc.
From my experience, I can confirm that the atomic instructions don’t work. But the compressed instructions seem to work, if I understand objdump -d output correctly (I see a lot of instructions that only use 16 bits)
Is it? Didn’t know that! Might be a mistake, especially if atomic instructions definitely don’t work and the Arduino code is rv64imfd. Good find though.
And yeah I am not 100% sure if Linux would work without atomics, but I am guessing not!
From my experience, I can confirm that the atomic instructions don’t work.
After more experiment, only atomic operation on hardware register make the software crash. But I don’t know if atomics on normal memory just appears to works but are not synchronized or really work.
Further to this, I’ve found from looking into C906B vs C906L, that the little core has no MMU. So whether or not it has C or A extensions, no data or instruction cache, and no MMU, so not sure if memory sharing would work and I don’t think there’s any way a Linux kernel would run on it.
The Linux kernel needs an MMU for its basic functions. RTOS doesn’t need an MMU.
You can run a Linux without an MMU for use on microcontrollers. So theoretically one might be able to run a second Linux kernel on the second core, it could be a fun experiment if it could run mailbox.
Yeah RV64IMAFDC is the primary core though, from what I could find and cited earlier, the C906L might be IMFD, although one user apparently saw 16-bit instructions working signififying the C extension.
Requires a higher level of explanations.
Multicore is not all what it seems. The DRAM is shared. That is bottleneck1. Bottleneck2 is DRAM paging speed. Typically DRAM is organized into say blocks of 256 bytes so that only one block at a time is fully powered up and reading or writing at nanosecond speeds. If you need to change page, its 100+ ns to change page - so the read write speed falls to about 10 MHz and less. The same with multicore Intel CPUs, more cores does not mean more speed. So there is cache for each CPU which is much faster and a buffer against paging and running out of data to process. If the data can fit inside the cache, then your software runs at terrific speed, but if its large and jumping around pages, throughput rates drop very fast. So the second CPU needs its cache enabled and best to run some small bare metal or RTOS code that fits inside cache and handles GPIO is probably best. Running full blown Linux on both cores likely a disaster as they trip each other up in memory causing page change and CPU performance degrade down to 10MHz. A duo can beat an i7 if the i7 is page tripping with improperly written code.