Okay, got some progress on this. Well, maybe not so much progress, but I got
something.
At first, I tried installing Code Composer Studio (CCS) version 6.2, since most forum posts and references I could find mentioned the 6.x version when talking about OMAP4/5. Unfortunately, it didn't install on my system. There's some kind of
bug in glibc that hangs the installer on my system, and I don't feel like downgrading my glibc
or use a chroot. So, instead I installed the latest CCS (11.2.0.00007), which had a checkbox for OMAP3/4/5 processors, and built a hello world program:
C:
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
Nevermind that this processor doesn't have any output to print to, but hey, it's an experiment. This resulted in a ELF file named
hello_world.out
, which I uploaded to my board.
I followed some online instructions on how to load and start the program:
Code:
echo -n "/root" > /sys/module/firmware_class/parameters/path # adjust global search path for firmwares. Bad idea generally, I know, sue me :P
cd /sys/class/remoteproc/remoteproc1/
echo -n "hello_world.out" > firmware
echo start > state
This seems to align well with the official documentation:
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-remoteproc
However, that failed:
Code:
# echo start > state
[ 63.981751] remoteproc remoteproc1: powering up 55020000.ipu
[ 63.989227] remoteproc remoteproc1: Booting fw image hello_world.out, size 8632
[ 63.996704] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1
[ 64.002625] remoteproc remoteproc1: IOMMU enabled
[ 64.007416] remoteproc remoteproc1: rproc prepared
[ 64.012279] remoteproc remoteproc1: rproc bootaddr: 0x55020801
[ 64.018646] remoteproc remoteproc1: Boot failed: -22
sh: write error: Invalid argument
A lot of
printk()
sprinkling later and I figure out that my elf file is missing a custom elf section called
.resource_table. This was of course also mentioned in the documentation:
https://www.kernel.org/doc/Documentation/remoteproc.txt
Now, here is when things start to get complicated. The resource table is meant to include information on what kind of resources should be reserved for the Cortex-M4. My initial attempt to manually hack in an empty resource table got me a bit further, but I didn't realize it at the time and thought something was wrong with my empty table.
I searched online for more answers. I looks like the
IPC software stack from TI includes support for populating this section. The latest version of this software is bundled with
TI Processor SDK, but none of the SDKs listed offer support for any OMAP family of CPUs!
IPC 3.40 was the last version offered as a standalone package, so I went with that one. I think the upstream git repo for this code is located here:
https://git.ti.com/cgit/ipc/ipcdev/
The IPC 3.40 is just a zip file with very little instructions inside
Well, there
are instructions but they are outdated and doesn't tell me how to incorporate IPC with CCS. I eventually gave up and just yanked the
rsc_table_omap5_ipu.h and
rsc_types.h files from the IPC package and massaged the whole thing to build. I ripped out the trace buffer entry from the resource table, because it was referencing some symbol that I didn't bother to investigate. I made sure to update the number of elements in the resource table appropriately.
CCS was kind enough to automatically create a linker file for my project, so I added
.resource_table to the list of sections there, and set the section parameters as close as I could to what the IPC code did. IPC also seem to want to load this section at
address 0x3000 by default, but I never got that to work properly. I think CCS is using a Clang flavor of compiler and linker. This is how my
.resource_table section in the linker script looks like right now:
Code:
SECTIONS
{
.text > OCMC_RAM
.stack > OCMC_RAM
.bss > OCMC_RAM
...
.resource_table > M4RAM, type = NOINIT, align = 4096 # <- Added by me
}
I also had to update my code to actually reference the resource table, or the linker would automatically strip it! I'm sure there are ways to tell the linker to ignore it, but this was faster:
C:
#include <stdio.h>
#include "rsc_table_omap5_ipu.h"
int main(void)
{
printf("Hello world!\n");
printf("Using table format: %d\n", ti_ipc_remoteproc_ResourceTable.base.ver);
return 0;
}
This got me a little further. In fact, it got me to the same point I was earlier when I had hacked in an empty resource table. Namely, I got this error now:
Code:
# echo start > state
[12507.846851] remoteproc remoteproc1: powering up 55020000.ipu
[12507.852790] remoteproc remoteproc1: Booting fw image hello_world.out, size 202624
[12507.860462] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1
[12507.866528] remoteproc remoteproc1: IOMMU enabled
[12507.871326] remoteproc remoteproc1: rproc prepared
[12507.876158] remoteproc remoteproc1: rproc bootaddr: 0x550227D9
[12507.882068] remoteproc remoteproc1: fw parsed
[12507.888457] remoteproc remoteproc1: resources handled
[12507.916649] remoteproc remoteproc1: carveouts allocated
[12507.921924] remoteproc remoteproc1: bad phdr da 0x55020000 mem 0x2a34 # <- THIS ERROR
[12507.928455] remoteproc remoteproc1: Failed to load program segments: -22
[12507.937156] remoteproc remoteproc1: failed to unmap 3000/0
[12507.942706] remoteproc remoteproc1: failed to unmap 3000/0
[12507.959230] remoteproc remoteproc1: Boot failed: -22
sh: write error: Invalid argument
(please note that some of these printouts are added by me for debugging)
The Linux kernel does a sanity check on the ELF headers to verify that the software is trying to execute at the correct address, as seen by the Cortex-M4. The
omap_remoteproc driver says that Cortex-M4 code should execute from address
0x2000 0000
, but I can't really find that information in the OMAP5432 reference manual. The only thing I can find is that this (virtual) address is the beginning of a bit-band region in the Cortex-M4 processors. I found these 2 commits which has some info on the issue, but I wonder if the assumptions are wrong for the OMAP5432:
I would love it if someone can help me decipher the TRM regarding this.
I anyway changed my linker script so that
M4RAM
was set to start at offset
0x20000000
, recompiled, and started it...
Code:
# echo "start" > state
[ 1736.332638] remoteproc remoteproc1: powering up 55020000.ipu
[ 1736.338766] remoteproc remoteproc1: Booting fw image hello_world.out, size 202624
[ 1736.346367] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1
[ 1736.352295] remoteproc remoteproc1: IOMMU enabled
[ 1736.357043] remoteproc remoteproc1: rproc prepared
[ 1736.361931] remoteproc remoteproc1: rproc bootaddr: 0x200027D9
[ 1736.367974] remoteproc remoteproc1: fw parsed
[ 1736.374108] remoteproc remoteproc1: resources handled
[ 1736.402581] remoteproc remoteproc1: carveouts allocated
[ 1736.407952] remoteproc remoteproc1: 0x20000000 (10804) vs 0x20000000 (65536)
[ 1736.415128] remoteproc remoteproc1: 0x20002A38 (5040) vs 0x20000000 (65536)
[ 1736.422280] remoteproc remoteproc1: 0x20003DE8 (416) vs 0x20000000 (65536)
[ 1736.429314] remoteproc remoteproc1: 0x20004000 (928) vs 0x20000000 (65536)
[ 1736.436241] remoteproc remoteproc1: 0x20004000 (928) vs 0x20000000 (65536)
[ 1736.443260] remoteproc remoteproc1: searched for resource table: 43ab22d0
[ 1736.450146] remoteproc remoteproc1: subdevices prepared
[ 1736.455925] remoteproc remoteproc1: remote processor started!
[ 1736.455925] omap-iommu 55082000.mmu: iommu fault: da 0x0 flags 0x0
[ 1736.461727] remoteproc1#vdev0buffer: assigned reserved memory node ipu-memory@95800000
[ 1736.467914] remoteproc remoteproc1: crash detected in 55020000.ipu: type mmufault
[ 1736.467919] omap-iommu 55082000.mmu: 55082000.mmu: errs:0x00000002 da:0x00000000 pgd:0xdd7074d2 *pgd:px95900002
[ 1736.476067] remoteproc1#vdev0buffer: registered virtio0 (type 7)
[ 1736.499749] remoteproc remoteproc1: remote processor subdevicess started!
[ 1736.506585] remoteproc remoteproc1: remote processor 55020000.ipu is now up
[ 1736.513622] remoteproc remoteproc1: rproc started!
[ 1736.518547] remoteproc remoteproc1: handling crash #1 in 55020000.ipu
# [ 1736.525048] remoteproc remoteproc1: recovering 55020000.ipu
[ 1736.530987] remoteproc remoteproc1: stopped remote processor 55020000.ipu
[ 1736.538691] remoteproc remoteproc1: 0x20000000 (10804) vs 0x20000000 (65536)
[ 1736.545875] remoteproc remoteproc1: 0x20002A38 (5040) vs 0x20000000 (65536)
[ 1736.552971] remoteproc remoteproc1: 0x20003DE8 (416) vs 0x20000000 (65536)
[ 1736.559976] remoteproc remoteproc1: 0x20004000 (928) vs 0x20000000 (65536)
[ 1736.566948] remoteproc remoteproc1: 0x20004000 (928) vs 0x20000000 (65536)
[ 1736.573906] remoteproc remoteproc1: searched for resource table: 43ab22d0
[ 1736.580843] remoteproc remoteproc1: subdevices prepared
[ 1736.586354] remoteproc remoteproc1: remote processor started!
[ 1736.592158] remoteproc1#vdev0buffer: assigned reserved memory node ipu-memory@95800000
[ 1736.600532] remoteproc1#vdev0buffer: registered virtio0 (type 7)
[ 1736.606667] remoteproc remoteproc1: remote processor subdevicess started!
[ 1736.613517] remoteproc remoteproc1: remote processor 55020000.ipu is now up
# cat state
running
Success! My code got loaded and the Cortex-M4 started, but it crashed!
So, that's where I'm at right now. I haven't deciphered what the errors means. Thought I'd write down today's progress unless I forget it tomorrow. Maybe I'll ask for some help on the linux-omap tomorrow
Now, it's time to sleep
EDIT:
I also tried to use the TI-RTOS (a.k.a SYS/BIOS) component. I ran the installer, but nothing showed up in CCS so I gave up on that for now. In the long run, I believe some kind of RTOS+RpMsg is the way to go if we want some kind of structured message passing between the two processors.
I also tried various combination of my code where I removed the
printf()
s and/or linked+loaded the M4 code at
0x55020000
. Still crashed with an iommu fault.