Coder Social home page Coder Social logo

dbuenzli / rpi-boot-ocaml Goto Github PK

View Code? Open in Web Editor NEW
53.0 53.0 0.0 300 KB

Raspberry Pi boot support for the OCaml system (unreleased)

Home Page: http://erratique.ch/software/rpi-boot-ocaml

Makefile 0.29% C 27.80% C++ 0.27% Assembly 0.20% OCaml 71.44%

rpi-boot-ocaml's Introduction

rpi-boot-ocaml - Raspberry Pi boot support for the OCaml system

Release %%VERSION%%

rpi-boot-ocaml is a minimal static library and linker script for booting a Raspberry Pi directly into the OCaml system. The rest is yours.

For now only the Raspberry Pi 2 Model B is supported.

rpi-boot-ocaml is distributed under the BSD3 license.

Prerequisites

We first need an OCaml cross compiler for ARMv7. Add the following repository to opam:

opam repo add rpi-boot-ocaml http://erratique.ch/repos/rpi-boot-ocaml.git
opam update

Install an OCaml compiler with a version that matches the cross-compiler (currently 4.02.3). On a 64-bit build system you need a 32-bit OCaml compiler.

opam switch 4.02.3       # If you are on a 32-bit platform
opam switch 4.02.3+32bit # If you are on a 64-bit platform
eval `opam config env`

You need ARM's gcc cross-compiler in your path. On Linux and MacOSX with homebrew it can be installed with:

opam depext ocaml-armv7-none-eabihf

The OCaml cross compiler can now be installed via:

opam install ocaml-armv7-none-eabihf

The cross compiler is installed in $(opam config var prefix)/armv7-none-eabihf. It can be invoked by using the -toolchain argument of ocamlfind:

ocamlfind -toolchain armv7_none_eabihf ocamlopt -config

Note that the compiler is configured not to link against libc and libm so that you can substitute them with whatever you wish.

Now run an OCaml system kernel

Clone this repository:

git clone http://erratique.ch/repos/rpi-boot-ocaml.git
cd rpi-boot-ocaml

A simple base example kernel is in the src directory. Adjust the variables in Makefile.config. And:

make

This will generate the kernel image _build/rpi-boot-ocaml.img that can be loaded by the Raspberry Pi.

To run it, the easiest is to have an SD card loaded with one of the officially supported operating system images, follow these instructions. Simply copy _build/rpi-boot-ocaml.img at the root of the SD card and add the following line to the config.txt file present at that location:

kernel=rpi-boot-ocaml.img

Unmount the SD card, plug it in the Raspberry Pi. To witness the OCaml system boot you can connect a display and/or a serial cable to the Pi. Power the system. The display should show something like this:

rpi-boot-ocaml greetings

The serial connection should output something along the lines of:

Welcome to rpi-boot-ocaml ๐Ÿซ
Boot time: 1324ms
Framebuffer: 800x480 bpp:32 addr:0x3DA83000

Note that the outrageous boot time is not due to the use of OCaml whose runtime and linked modules initialisation only adds ~4ms to an equivalent boot sequence into a plain C kernel.

Boot and halt procedure

We describe what happens once we get a chance to execute our code. If you want to know about the slow GPU dance that comes before see for example this (sligthly outdated) stackoverflow answer.

The kernel starts with boot.S which:

  1. Enables the L1 cache and branch prediction.
  2. Enables the Neon MPE.
  3. Zeroes the C bss section.
  4. Setups the C call stack and jumps into the _startup C function of startup.c which simply calls caml_startup and never returns.

If the program ends up in the C exit or abort function the halt function of startup.c gets called with the status code (255 for abort). If the status code is non-zero the ACT led of the Pi will flash at high-frequency; this will happen for example in case of an uncaught OCaml exception or an out of memory condition. If halt is called with a status of 0 we just call the wfe ARM instruction in a loop; this will happen on exit 0 or if caml_startup returns normally.

Kernel development and image build procedure

To build a kernel simply create an OCaml program and link it into an object cfile using ocamlopt's -output-obj option.

This object file must then be linked using the rpi-boot-ocaml.ld linker script with the following libraries:

  • lib-ocaml-boot.a, has the boot code from src-boot
  • libbigarray.a, OCaml's bigarray support.
  • libasmrun.a, OCaml's runtime library.
  • libgcc.a, gcc library needed for some of the generated code.
  • libc.a, a libc of your choice.
  • libm.a, a libm of your choice.

This results in an an ELF executable that must be stripped to a raw binary ARM executable using objcopy.

If you hack directly on this repo you should be able to simply add .c and .ml files to src, mention the .ml files in Makefile.config and things should compile into the _build/rpi-boot-ocaml.img kernel image. Generated documentation for the helper Rpi module can be found here.

In case of problems you can have a look at the generated assembly code _build/rpi-boot-ocaml.dasm and the map file _build/rpi-boot-ocaml.map.

Status and future plans

Note that all this is only a starting point and there are quite a few issues to solve and a few problems you may run into. See the TODO.md file and the issue tracker.

Once we get proper cross-compilation support in opam the plan is to eventually package and split away libc-ocaml and make this a package only for the src-boot static library and the linker script (and maybe the helper base Rpi module). The rest in src should be developed and distributed independently as libraries.

rpi-boot-ocaml's People

Contributors

dbuenzli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rpi-boot-ocaml's Issues

Device tree support

If you want the device tree address rather than atags in register r2 then you need to add the magic trailer RPTL to the kernel image. See here for more information.

Review OCaml's use of `setjump`

Currently libc-ocaml does nothing. I think it's only used for signals but this should be double checked (at least exceptions seemed to work in the kernels).

Stack size

What's the correct way of setting this up ? See link script and boot.S. Can we honour/specify the OCAMLRUNPARAM variable name for OCaml ?

Interrupt vector support.

One way of handling this would simply to set some global variables. With effects we can then easily have functions that you call and suspend until the interrupt occurs by making an effect. The main run loop simply checks the interrupt global variables to see if there's something new and invokes the continuations waiting on them. If there's nothing to do the main loop can sleep with WFI until the next os timer deadline.

Get rid of newlib header pollution

The cross-compiler package compiles using gcc-arm-embedded's header which are newlib's one and pollute the objects in libasmrun.a with symbols we don't want (see newlib-fix.c in libc-ocaml).

Ideally we should compile the runtime system with -nostdinc against libc-ocaml's headers (which are not complete yet to compile the compiler). This also means that libc-ocaml should become an independent package needed by the cross-compilation package.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.