hackndev / zinc

The bare metal stack for rust
zinc.rs
Apache License 2.0
1k stars 100 forks source link

Zinc on Cortex-A #283

Open geraldstanje opened 9 years ago

geraldstanje commented 9 years ago

Hi,

is arm cortex a9 bare metal supported?

Thanks, Gerald

farcaller commented 9 years ago

Zinc can technically run on anything that is supported by rustc, which includes cortex-a cores. There is no support for any cortex-a9 chips in the works though.

While cortex-a cores can usually run things like linux and require more complex init sequences, I'm not entirely against adding bare metal cortex-a support into zinc in the future.

Arnold1 commented 9 years ago

how much effort is it to add those support? a basic support would already be great...many people use arm cortex a9 with xillinx zynq device... http://www.xilinx.com/products/silicon-devices/soc/zynq-7000.html http://www.myirtech.com/list.asp?id=502 http://www.open-electronics.org/red-pitaya-the-opensource-electronic-laboratory/

farcaller commented 9 years ago

There is a very big amount of various Cortex-A cores, so it's a very hard target for zinc. What features would you like to see in Cortex-A code?

Arnold1 commented 9 years ago

for arm cortex a9: GPIO/s, VFPv3, Timers, shared memory access between the ARM and the FPGA by adding some interrupt logic ... how much effort is it to add those?

ghost commented 9 years ago

This would be nice to see. @farcaller, can you quickly outline at a high level what would be needed by zinc to support the Zynq SoC?

ghost commented 9 years ago

Just a clarification to my above comment, what I mean is: in general, what does zinc need to support a platform? Given that I can figure out the Zynq specifics...

bharrisau commented 9 years ago

Like most things, zinc has layers:

I hope that is a sufficient overview. Also, don't forget the initialisation code, there is usually a system initialisation document detailing the order that things need to be activated (and please link to it in your comments wherever you reference it). Forgetting to initialise watchdogs causes lots of debugging grief.

In the future (when I get some more time for Zinc), I'd like to decouple the above a little bit, so that the definition and instantiation of each layer is separate. i.e. ARM_systick_module_1 is implemented once in layer 1, and we map it into Cortex_M1 in a separate layer. Same for layer 2 peripherals, implement the vendor peripheral in one area, but instantiate it for the particular device somewhere else.

bharrisau commented 9 years ago

And for completeness, there is also a layer of Zinc utilities.

ghost commented 9 years ago

Thanks Ben, good overview. its nice to give each board a crate. Those could grow as large as they want. Now that I understand the layout a bit, I'll have a better time digging around.

Arnold1 commented 9 years ago

awesome zinc seems to build with nightly....

Any news about very basic support for arm corex a9? e.g. GPIO + Timer to toggle a LED...

mcoffin commented 9 years ago

@Arnold1 I don't think anybody is working on it right now, but as always feel free to start it!

farcaller commented 9 years ago

Let's clarify terminology once again.

Cortex-A9 is a computing core along with a very little set of peripherals (systick timer and MMU). It is somewhat different from the cores currently supported in zinc (Cortex-M0, M3 and M4), but not very different for adding support to be unbearable.

Different MCU vendors incorporate ARM cores in their products, e.g. Raspberry Pi 2 has a BCM2836 CPU featuring Cortex-A7 core. Broadcomm provides IP for gpios, serial ports, audio, video, etc. on the same die as the ARM core is.

So, speaking of adding Cortex-M9 support, the only core-specific thing we now have is a set of initialisation vectors, and adding that is trivial. Adding support for specific CPU or a family of CPUs is where complexity is. As far as I know xillinx zynq devices, those are FPGAs with ARM cores inside, so, basically, you provide the peripheral IP yourself (including gpio, serial and other things). I don't see how this fits zinc, as the peripheral configuration is defined by user and we just can't provide any kind of generic drivers.

Speaking of Cortex-A profile support, I can consider looking at some easily-available board (RPi, beaglebone?) and giving directions on what is needed to add support for it in zinc.

ghost commented 9 years ago

Hi Vladimir, Xilinx's Zynq is actually a full dual core A9 SoC with USB, gpio, Ethernet, and many other peripherals on die. Also on die is the fpga which you can have the processor subsystem populate on boot with a custom design (say a specific HW accel function your app needs). You can then call that function from C code. It would fit Zinc as far as the processor system is concerned which is why I found interest in Zinc.

I have started to look at the tool chain layer along with the layout described by Ben. However, the repo does not appear to be in the state he described just yet. Still, I have to get to know rust a bit more and I'm working my way there. This is definitely an interesting project though and seeing Zynq running zinc would be a cool thing to see.

On Monday, June 1, 2015, Vladimir Pouzanov <notifications@github.com javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

Let's clarify terminology once again.

Cortex-A9 is a computing core along with a very little set of peripherals (systick timer and MMU). It is somewhat different from the cores currently supported in zinc (Cortex-M0, M3 and M4), but not very different for adding support to be unbearable.

Different MCU vendors incorporate ARM cores in their products, e.g. Raspberry Pi 2 has a BCM2836 CPU featuring Cortex-A7 core. Broadcomm provides IP for gpios, serial ports, audio, video, etc. on the same die as the ARM core is.

So, speaking of adding Cortex-M9 support, the only core-specific thing we now have is a set of initialisation vectors, and adding that is trivial. Adding support for specific CPU or a family of CPUs is where complexity is. As far as I know xillinx zynq devices, those are FPGAs with ARM cores inside, so, basically, you provide the peripheral IP yourself (including gpio, serial and other things). I don't see how this fits zinc, as the peripheral configuration is defined by user and we just can't provide any kind of generic drivers.

Speaking of Cortex-A profile support, I can consider looking at some easily-available board (RPi, beaglebone?) and giving directions on what is needed to add support for it in zinc.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/283#issuecomment-107418748.

farcaller commented 9 years ago

Xilinx's Zynq is actually a full dual core A9 SoC with USB, gpio, Ethernet, and many other peripherals on die.

Ah, makes more sense then. Given that, the support plan would be the same as with other platforms, add support for any boot requirements for CPU, then add peripheral drivers. The issue with latter is that Platform Tree has a big chance to get a redesign, and we don't have good traits defined for peripherals, really.

Arnold1 commented 9 years ago

@farcaller thanks for the reply. could you prepare a basic toolchain e.g. platform tree as a start implementing the support for arm cortex a9? maybe @bechamp whats to join in some work too...

Arnold1 commented 9 years ago

any feedback on this @farcaller @bechamp ?

ghost commented 9 years ago

Hi, trying to get hands on a board through work before committing. Also new to rust so I'm still trying to get my head around the platform trees. This won't be a one weekend project for me alone but definitely interested. Do you have a board?

On Friday, June 5, 2015, Arnold1 notifications@github.com wrote:

any feedback on this @farcaller https://github.com/farcaller @bechamp https://github.com/bechamp ?

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/283#issuecomment-109326126.

Arnold1 commented 9 years ago

yes i have a board. i already used rust and mapped the fpga memory to linux using mmap... it would be great if @farcaller can help us with the initial start as well as platform tree... do you want to constribute?

ghost commented 9 years ago

Which board?

Also have you gotten vanilla rust to cross compile for it already? because if not then we don't need the boards right away if we are still figuring out the tool chain.

On Friday, June 5, 2015, Arnold1 notifications@github.com wrote:

yes i have a board.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/283#issuecomment-109329266.

Arnold1 commented 9 years ago

i have this board called redpitaya. but also might get a myirtech Z-turn Board... do you get a myirtech Z-turn Board as well?

i already used rust and mapped the fpga memory to linux using mmap... but not yet bare metal...

what is vanella rust?

ghost commented 9 years ago

RedPitaya boards are a great application. I saw them when they were announced. Outside my hobby budget though and we don't have those laying around at work. You are further along then me then. Would you have any notes to share on getting rust to build for the device? Bare metal right (not cross Linux)?

On Friday, June 5, 2015, Arnold1 notifications@github.com wrote:

i have this board called redpitaya.

i already used rust and mapped the fpga memory to linux using mmap...

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/283#issuecomment-109330327.

Arnold1 commented 9 years ago

i have not yet tried to build rust for bare metal... @farcaller can you jump in?

posborne commented 9 years ago

Having worked on a number of Cortex-A devices (working on U-Boot, Embedded Linux, and also and RTOS project), I'm not sure it makes a lot of sense for Zinc to try to target them in the short term. Although targeting the core itself is and getting some code running in SRAM loaded on through JTAG is probably not terrible, these more powerful cores after often found within the context of more complicated SoCs which require more work to integrate with. Let's say we were to target something like the BeagleBone Black or Freescale i.mx6:

Maybe I have only worked with the more complex designs using these cores? I just wonder if it makes sense for Zinc to stay focused on M0, M0+, M3, M4 MCUs rather than targeting more powerful cores that really require an OS for reasonable use.

Arnold1 commented 9 years ago

for reference: http://www.xilinx.com/support/documentation/application_notes/xapp1079-amp-bare-metal-cortex-a9.pdf https://github.com/PUTvision/Xilinx_code_templates

farcaller commented 9 years ago

I really agree with @posborne on this one, if your hardware supports u-boot, then there's really very little sense to bring zinc in.

As for guidelines on where to start, I really have little idea how to initialise Cortex-A systems and can hardly advice on that. Maybe starting with barebones helloworld in rust that inits hw enough to blink a led is a reasonable starting point? We can then see how init code can be fit into zinc.

Arnold1 commented 9 years ago

why? some people run linux on core0 and bare metal on core1...

hello world + blink a led sounds great... can you provide some infos on how to initialize the cortex a9?

ghost commented 9 years ago

Hi Paul, Everything you say is absolutely correct. Fully supporting the A core is not a small feat. Supporting the on-die ecosystem is approaching monumental. Then each board support package would be quite a bit of work.

SoCs are getting very complex with nonhomogeneous mutlicore arrangements that support hypervisors and other such advances. Are those even attainable by Rust and zinc? Maybe, probably, with enough time. But it's a good discussion to define the scope and possibilies of a project like zinc.rs. But, without taking focus away from the current goals. So thanks for the interjection.

I approached this discussion from the notion that 1) Rust is (intended) interchangeable with C not just replacement and 2) I envision the rust code would simply be the application level code operating in the existing bare metal ecosystem. Maybe that is not the intent of zinc.rs as it is taking ownership of the system but it was a thought. ( and well 3) zinc.rs running on Zynq would be cool even if it's a bit superficial ;) )

(T.b.h. Where I am right now as far as exposure to Rust, had I the time I would probably try to make a crate for a teensy board running zinc to start with before seriously considering a full scale SoC)

On Friday, June 5, 2015, Paul Osborne notifications@github.com wrote:

Having worked on a number of Cortex-A devices (working on U-Boot, Embedded Linux, and also and RTOS project), I'm not sure it makes a lot of sense for Zinc to try to target them in the short term. Although targeting the core itself is and getting some code running in SRAM loaded on through JTAG is probably not terrible, these more powerful cores after often found within the context of more complicated SoCs which require more work to integrate with. Let's say we were to target something like the BeagleBone Black or Freescale i.mx6:

  • Both of these boards are used with DDR SDRAM. This requires a fair amount of additional code to initialize this RAM.
  • In order to boot to code, executables must be programmed into NAND flash (or eMMC/SD Card) in a specific fashion that can be understood by the boot ROM in the SoC. Doable, but work that must be done differently for many different boards.
  • There are many, many IP blocks in modern SoCs. The reference manual for MCUs is maybe 1000 pages. It isn't unusual for the reference manual on SoCs to be upwards of 6000-8000 pages. You don't need to use all of those IP blocks, but you are better off just using Linux if you want to make use of most of that hardware.

Maybe I have only worked with the more complex designs using these cores? I just wonder if it makes sense for Zinc to stay focused on M0, M0+, M3, M4 MCUs rather than targeting more powerful cores that really require an OS for reasonable use.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/283#issuecomment-109388167.

Arnold1 commented 9 years ago

@bechamp lets build a hello world in rust targeting the arm cortex a9 as a proof of concept?

farcaller commented 9 years ago

@bechamp you can take any existing C-based OS for Cortex-A9 and run rust code on it with reasonably little effort already. I envision zinc.rs as rust-only [RT]OS with no C code, the reasoning is to see what rust is missing to be used like that.

ghost commented 9 years ago

That is what I felt this project was and support that. Which is why I'm not too sure about pursuing the SoC yet (myself) now as a lot of foundation is still to achieved.

But, Arnold, I think I'll try and look through that app note in the coming days and cross reference the redpitaya docs to get an idea of what a hello world on that board would be. I think it will be nontrivial too:

But after getting there, porting of zinc is somewhat within range.

On Friday, June 5, 2015, Vladimir Pouzanov notifications@github.com wrote:

@bechamp https://github.com/bechamp you can take any existing C-based OS for Cortex-A9 and run rust code on it with reasonably little effort already. I envision zinc.rs as rust-only [RT]OS with no C code, the reasoning is to see what rust is missing to be used like that.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/issues/283#issuecomment-109416044.

Arnold1 commented 9 years ago

@bechamp i agree... i will also read the application note and try to figure out how to configure the zynq for enable both cores fore bare metal and getting the startup code... i guess we also need to configure the zynq with vivado first?

other reference: http://www.state-machine.com/arm/Building_bare-metal_ARM_with_GNU.pdf http://henryomd.blogspot.co.at/2015/02/zynq-amp-linux-on-cpu0-and-bare-metal.html http://www.vision.put.poznan.pl/?p=182 http://www.xilinx.com/support/documentation/application_notes/xapp1078-amp-linux-bare-metal.pdf https://github.com/zynqgeek/zed_helloworld/tree/master/zed_first/zed_first.sdk/SDK/SDK_Export/hello_world_0/src

geraldstanje commented 9 years ago

hi,

i would like to contribute and started to port some C code to Rust: https://github.com/geraldstanje/rust-arm-cortex-a9

the original C source is here: https://github.com/geraldstanje/rust-arm-cortex-a9/tree/master/orig/bare_metal_test.cpu1

Rust project (main.rs will implement a blink app): https://github.com/geraldstanje/rust-arm-cortex-a9/

...im not sure about the llvm-target for arm cortex a9!? target.json:

{
    "arch": "arm",
    "cpu": "cortex-a9",
    "data-layout": "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-v128:64:128-a:0:32-n32-S64",
    "disable-redzone": true,
    "executables": true,
    "llvm-target": "arm-unknown-eabi",
    "linker": "arm-xilinx-eabi-gcc",
    "morestack": false,
    "os": "none",
    "linker-is-gnu": true,
    "has-rpath": true,
    "relocation-model": "static",
    "target-endian": "little",
    "target-pointer-width": "32"
}

my c compiler (for linking the object files):

arm-xilinx-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-xilinx-eabi-gcc
COLLECT_LTO_WRAPPER=/opt/Xilinx/SDK/2015.1/gnu/arm/lin/bin/../libexec/gcc/arm-xilinx-eabi/4.9.1/lto-wrapper
Target: arm-xilinx-eabi
Configured with: /scratch/cltang/xilinx/eabi/src/gcc-4.9-2014.11/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-xilinx-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch=armv7-a --with-cpu=cortex-a9 --with-float=softfp --with-fpu=neon-fp16 --disable-multilib --with-gnu-as --with-gnu-ld --with-specs='%{save-temps: -fverbose-asm} -D__CS_SOURCERYGXX_MAJ__=2014 -D__CS_SOURCERYGXX_MIN__=11 -D__CS_SOURCERYGXX_REV__=31' --enable-languages=c,c++ --disable-shared --enable-lto --with-newlib --with-pkgversion='Sourcery CodeBench Lite 2014.11-31' --with-bugurl=https://s...content-available-to-author-only...r.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-headers=yes --with-sysroot=/opt/codesourcery/arm-xilinx-eabi --with-build-sysroot=/scratch/cltang/xilinx/eabi/install/opt/codesourcery/arm-xilinx-eabi --with-gmp=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpfr=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpc=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-isl=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --with-cloog=/scratch/cltang/xilinx/eabi/obj/pkg-2014.11-31-arm-xilinx-eabi/xilinx-2014.11-31-arm-xilinx-eabi.extras/host-libs-i686-pc-linux-gnu/usr --disable-libgomp --disable-libitm --disable-libatomic --disable-libssp --enable-poison-system-directories --with-build-time-tools=/scratch/cltang/xilinx/eabi/install/opt/codesourcery/arm-xilinx-eabi/bin --with-build-time-tools=/scratch/cltang/xilinx/eabi/install/opt/codesourcery/arm-xilinx-eabi/bin SED=sed
Thread model: single
gcc version 4.9.1 (Sourcery CodeBench Lite 2014.11-31)

will libcompiler-rt.a only need boot.S? ...boot.S is part of the board support package (BSP): http://www.xilinx.com/support/documentation/sw_manuals/xilinx12_2/SDK_Doc/concepts/sdk_c_bsp_internal.htm

How can i port offsetof(struct rproc_resource, code_cout) from C to Rust?

@farcaller @posborne @bharrisau can you comment on this?

geraldstanje commented 9 years ago

can someone comment on this?

farcaller commented 9 years ago

The safest bet is to dump ti_ipc_remoteproc_ResourceTable in a hex editor and just make a [u8] vec in rust to make you going.

geraldstanje commented 9 years ago

@farcaller is arm-unknown-eabi the right llvm target for arm cortex a9? and what about the startup code, i currently only added boot.S?!

farcaller commented 9 years ago

arm-unknown-eabi sounds like a reasonable target. as for boot.S, I haven't worked with Cortex-A in a long while so I can't really advice on the proper initialisation sequence.

geraldstanje commented 9 years ago

@farcaller i have my working c project here: https://github.com/geraldstanje/rust-arm-cortex-a9/tree/master/orig/bare_metal_test.cpu1

but i cant see how the startup sequence is called. any idea?

farcaller commented 9 years ago

This is the entry: https://github.com/geraldstanje/rust-arm-cortex-a9/blob/master/orig/bare_metal_test.cpu1/lscript.ld#L33

That calls to the vector table:

.section .vectors
_vector_table:
    B   _boot
    B   Undefined
    B   SVCHandler
    B   PrefetchAbortHandler
    B   DataAbortHandler
    NOP /* Placeholder for address exception vector*/
    B   IRQHandler
    B   FIQHandler

that goes to the boot, that branches to C code.

geraldstanje commented 9 years ago

@farcaller so all i need is asm_vectors.S and boot.S, thats it?

farcaller commented 9 years ago

I think it's a reasonable approximation.