I'm working on a small secure OS to put in the secure/trustzone world alongside Raspbian. In a few words, what I do to achieve this is:
* I removed the USB FIQ using the following line with u-boot:
* boot with config.txt:kernel_old=1 to boot in secure mode
Code: Select all
setenv bootargs "dwc_otg.fiq_enable=0 dwc_otg.fiq_fsm_enable=0 mem=768M dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait"
* boot a patched version of u-boot that sets everything up for linux but jump to my OS instead of Linux, at the last moment
* my OS setups a few things, the most important ones are a monitor to handle the switch between the two worlds, and the sp804 timer's interrupt as FIQ, but I don't start the timer yet.
* my OS jumps to Linux and Linux boots ok
At this point, Linux works perfectly ok (since I didn't start the timer, there is no switch to the secure world). I initiate the switch with a kernel module that I insmod dynamically. From this point, each time an IRQ is triggered, it is sent to the monitor which schedule Linux, and each time the FIQ is triggered, it is sent to the monitor which schedule my OS.
And it still works nicely, up to the point Linux enters arch/arm/mm/proc-v7.s:cpu_v7_do_idle and especially the wfi instruction. At this point, everything freezes. I have really no idea why. Wild guess: the FIQ was used for something else and I broke that ?
PS: if it matters, I only have one instance of my OS, on cpu0. The other 3 cpu are fully under the control of Linux.