Student: Nikita Korobov
Mentors: Jean-Baptiste Boric, Sambuc Lionel
git repository: https://github.com/nekorobov/minix/tree/rpi_clean
The MINIX3 has already supported the ARM-based platforms such as the BeagleBoard. The goal of this project is port the MINIX3 to the RaspberryPi. The task requires changing the booting process, because it doesn't allow have more than one platform. The MINIX3 should be more flexible OS, port to the new platform shouldn't require change boot process, kernel files, etc. Only drivers must be written. A device tree is suitable technology for this purpose.
Also, some of the RaspberryPi drivers such as USB, SDCard, SPI, I2C, etc. must be implemented. It's the most long-term issue.
|☑||Remove the dirty hack from kernel||100%||Done|
|☐||Make kernel platform independent||70%||Add device-tree parsing|
|☐||Cleanup booting process||60%|
|☑||Resolve tty issues||100%||Done|
|☐||SDCard driver||80%||Add general and logical system|
|☑||PWM mini jack driver||99%||Done|
The previous implementation of booting doesn't allow to have more than the one platform, because there were the different phys_base constants, the different hardware initialization functions with conflict names, which prevent compiling all sources of the MINIX into one .elf.
Now the kernel sets a page table on the early bootstrap stage in assembly and only the one file is unmapped. The all hardware-dependent functions called from exemplar of a special table. This table is initialized at runtime depending on platform, where the MINIX runs. We know the platform-depending constants and other platform information from a device-tree. I've imported external libfdt under BSD license to parse the dev-tree quickly.
The device tree is parsed in the pre_init stage. Machine type, memory constants, CPU amount and some necessary platform information are set up in this stage. Each driver, which use the platform depending constants (almost all drivers) should get these constants from the device tree. The earm/fdt.c allows get some parameters without knowledge how the device tree works and how parse it.
It will be good to have the general bootloader for all platforms, we thought. And it will be better to have a general structure in main with information about memory size, platform, framebuffer, etc.for each architecture.
Thus, a kernel-loader parse the device tree on the ARM, packs information into a multiboot2 format, which are compatible with any architecture. Other information(which can't be packed into the multiboot2) the kernel-loader packs into special structure, which is available only for the ARM platforms. The loader passes these structs to kmain, where multiboot2 format unpacks and constants are set.
The paging is also enabled in the kernel-loader. It means that the kernel doesn't contain unpaged code anymore. It makes the linker script easier and the kernel more consistent for each architecture.
The SDcard is very important driver, because it allows us to place whole system and binaries on the SDcard, which surely makes the MINIX more useful and comfortable. Lionel Sambuc wrote a new script, which place whole system on the SDCard.
There are not very big difference between the RPI and the OMAP, if we talk about the driver structure.
The mailbox driver is a character device. Other servers can communicate with it by open/read/write/close. Servers have to make structure with request to the Mailbox driver according to rules, which is described https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface. They have to open /dev/mailbox with read/write permissions and firstly write there request, then read it. You can find an example https://github.com/nekorobov/minix/blob/rpi_clean_driver/minix/drivers/video/fb/arch/earm/fb_arch_rpi.c
The new I2C driver is similar with the previous drivers, because the MINIX has the I2C stack, which requires definition of specific functions. The RPI may be as slave or master, but the current version of I2C driver supports only the master mode. It supports the 7 and 10 bits address. Plan - how to add the new I2C driver was added to the README. It's very simple, because the I2C stack was created as portable driver.
The RPI bus can't generate repeated start bit. It's bit which hardware generate instead of stop bit after the write command transmission, this bit is followed by read transaction. It's a big missing of the Broadcom, cause we can't read from the device's register, because many devices, which uses I2C require repeated start bit. There are exist software methods how work around it, but it may be in race condition, thus these methods are unreliable.
The PCM driver is audio driver. The special device can be connected to RPI by the I2S interface. The PCM driver uses the 5th DMA channel to send data to the I2S. It doesn't support recording audio and 24 and 32 bits audio. There are common pins for I2S interface and SPI1, thus you can't use I2S, if you'd like to use it at the same time with SPI1.
This driver is finished up 99%, because I have no the I2S device to connect it, but there are right driver logic and correct output on pins (I checked it by oscilloscope).
The MINIX hasn't had the SPI stack yet, so we decided to develop the SPI driver as the chardriver. Driver is designed in the poll mode. It is the bidirectional driver now, it means that we need only three wires to connect the RPI with device:
Communications with it carried out by open/close, read/write for sending data and ioctls for the setting SPI mode and speed. There are 4 modes of SPI, the difference between them is: pass data with the rising or down edge of sync signal, the sync signal starts with up or down level. Variation of this parameters determine modes. The current SPI driver can work only as a master.
It has three GPIO out as I2C, so we have to use three devices: spi-1, spi-2 and spi-3.
Since the Raspberry Pi is the System On Chip there are mini jack 3.5 mm. We can listen to audio directly through it. Note that it uses the Pulse Width Modulator it means that we can't use analog audio and the PWM at the same time. The mini jack connected with GPIO 40&45 on the RPI2 and GPIO 40&41 on the RPI3. Thanks to thePWM interface there are to channels (AUD_PWM0 and AUD_PWM1) which is left and right audio channels. The mini jack on the RPI doesn't support headphones with 4 rings. (There are only out sound, but no input from mic). It must to be standard headphones, where the first ring is responsible for the left channel, the second for the right channel and the third for the GND. This driver uses DMA. Sound can be mono, stereo and any length of frame.
There are common pins for PWM interface and SPI2, thus you can't use analogue audio, if you'd like to use it at the same time with SPI2.
Arm reference manuals http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.architecture.reference/index.html
RaspberryPi peripherals reference manual https://cdn-shop.adafruit.com/product-files/2885/BCM2835Datasheet.pdf
SDCard description http://users.ece.utexas.edu/~valvano/EE345M/SD_Physical_Layer_Spec.pdf
The Mailbox tags list https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface