using the same rootfs for different ARM SOCs - linux-kernel

I'm trying to use userspace built for i.mx53 on a identical board with i.mx6. The i.mx6 board differs only in the CPU used. I built a new kernel and appropriate DTB, I can load it with uboot and it starts fine. However, when I try to use the rootfs I had for i.mx53 board I get a following jffs error:
jffs2: inconsistent device description
which has something to do with flash OOB not containing valid information.
I write the rootfs into a flash partition with the nand write.trimffs command. Do I need to initialize the OOB somehow? I don't remember doing it on the old board. Where can this error come from?

Turns out i.MX6 NAND controller (gpmi driver) uses entire OOB space for ECC and JFFS2 cannot fit it's markers there. It is possible to communicate to the kernel weaker requirements for ECC based on NAND chip specification and use fsl,use-minimum-ecc device tree option to save up some OOB. However, u-boot does not seem to have support for such ECC reconfiguration and it becomes impossible to use NAND in both bootloader and Linux. Probably the best way forward in this situation is to ditch JFFS2 and use UBIFS instead.
Note: I've seen JFFS2 patches which make it not use OOB, but haven't tried them.

Related

Flashing ESP32's memory without installing the whole IDF?

Problem
I'm looking for a way to flash an ESP32 module's memory without installing the whole IDF software suite.
Why
Because I want to integrate ESP32 onto a custom board along with a low-performance ARM-powered CPU which runs a tiny Linux distro (based on Debian), and I want to flash ESP32 from this tiny Linux distro.
I know I could use the bootloader, but who will upload the initial bootloader? I don't want to do extra steps, so my idea is to embed the ESP32 module onto my custom board, and let the Linux to flash it from factory-state (when it's flash is empty, ie. no preloaded bootloader). Or is the serial bootloader always preinstalled on all ESP32 modules (like on ESP-WROOM-32)?
Why I don't want to use IDF? Because I don't want to build or debug anything, I just want to flash myprogram.bin onto ESP32. Also, as the board is low-performance, it would take ages to download everything for running IDF.
Current state
The ESP32 module is now visible via UART (RX,TX,GND), and if I held low the GPIO0, it runs the bootloader (my current module is embedded onto a NodeMCU - but there is no USB connected, this is raw UART!):
rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download
Could I expect the same behavior (controlling GPIO0 for running the bootloader) for all ESP32 modules, or this works just because guys at NodeMCU preprogrammed already some bootloader onto it?
I'm looking for a way to flash this ESP32 preferrably without any python script.
The ESP32 has a first-stage bootloader in ROM capable of writing to Flash - that's what's printing your output. You can talk to it if you know the protocol - this is implemented by the Python scripts in ESP IDF. If you don't want to use the official implementation because it's too heavy, you'll have to write your own implementation of this protocol which scratches your specific itch. Fortunately it's more or less documented and you can likely reverse engineer any missing knowledge from official Python scripts.
Actually Espressif also provides a nice and small binary for flashing ESPs:
https://github.com/espressif/esp-serial-flasher
Serial flasher component provides portable library for flashing Espressif SoCs (ESP32, ESP32-S2, ESP8266) from other host microcontroller. Espressif SoCs are normally programmed via serial interface (UART). Port layer for given host microcontroller has to be implemented, if not available.
One more (but very important) addition:
You have to modify this repo to make it work correctly, and also you might have to upload not just your binary, but also bootloader and partition_table.

Detect spi device from another driver

I have a Freescale imx.6q (arm) based board.
Hardware is configured with devicetree.
It had a change major incompatible change to timings and voltage for an onboard fpga, but these changes are invisible to the kernel.
The EE's tell us we shouldn't load the old fpga firmware for fear of damaging it. I would like to support both hardware from the same code (It is already causing confusion)
The solution I have thought of is this:
There are several new spi temperature sensors on the board. If I can read from one of those devices, I can infer that I need the new firmware.
How can I (in one driver) grab an spi device and then release it?
I suspect that I might be able to do something like this with device tree,
But I don't want to make the device unavailable.
Any ideas or examples of something like this being done?
After reading question i think your concern is how to add software support for more than one hardware.
If that is the case i think we can write two drivers supporting both hardware's with different configuration such as irq, voltage, register set etc.
So i will enable both drivers in Makefile and config file.
So at the time of boot when probe of drivers gets called we can check the hardware id by using spi_read command from driver.
If hardware id matches then driver probe gets successful and driver can be used to interact with hardware.
If spi_read fails then driver probe itself will fail.
I think this will do the trick.
EDIT (answer the question)
To detect use an SPI device from another driver use a reference to the device in the devicetree structure.
Short answer: add a reference to the spi device in your devices dts entry.
Slightly longer answer:
When adding spi to another device driver, you are effectively adding a subdevice, which may want its own driver. I have an FPGA which loads its firmware over (something close enough to be considered) SPI. I started with the idea of just treating the spi device as part of the larger driver, but the more work went into it, the more obvious it was that it is its own device, with a purpose and function that is distinct from the rest of the driver. I separated that code into its own driver.
Now instead of a reference to an SPI device, my driver just has a reference to an FPGA Manager device.
See line 98, 370 of https://github.com/d4ddi0/linux/blob/v4.12evi/arch/arm/boot/dts/imx6q-evi.dts
and
make sure the spi driver is loaded before your driver completes loading
My original answer to my question (for historical purposes):
What I ended up doing was using different devicetree files. The difference is know at initial install time (based on the serial number). The bootloader knows which dts filename to load.
There are multiple FPGA firmware versions and the right one is chosen based on the description in the dts.
This way, I can still update the driver and/or dts without breakage.
This works well in practice even though it does not detect anything at runtime.
One problem still exists, if I take an SD card from a new revision, and put it into an old one, the incorrect firmware will be loaded. To really solve this last problem, we've talked about adding an EEPROM to uniquely identify the hardware revision on future boards.

Embedded Linux Newbie Questions

So I am on the quest of learning embedded Linux and have a few questions that I cannot seem to find an answer for.
1) Does the kernel depend on the dtb/dts files when compiling? I thought that the kernel only needs to know the chip architecture (i.e. arm) and the dtb file is loaded by the boot loader (uBoot) so therefore the kernel only needs to load its drivers which are configured by the dtb file.
2) Mixing and matching: I'm under the impression that I can mix and match any combination of boot loader, dtb, kernel, rootfs, and modules given the following
kernel: must know which chip it is compiled for
dtb: must know the board details and chip, i.e. how much ram, configure a GPIO for SPI
boot loader: must know the chip and uEnv.txt must have params for the kernel and dtb location
rootfs: completely independent
modules: must be compiled with the specific version of kernel
3) Drivers: If I want to load a SPI driver do I need anything specific or will the kernel know how to operate this because the dtb file setup the required registers?
4) Modules: Are these just dependent on the kernel or do they need to know something about the chip and board (when I say chip what I mean is do they have to know more than a simple arm or x86 architecture)?
Thank you in advance, I know these are some basic questions but any help is appreciated.
1) Does the kernel depend on the dtb/dts files when compiling? I thought that the kernel only needs to know the chip architecture (i.e. arm) and the dtb file is loaded by the boot loader (uBoot [sic]) so therefore the kernel only needs to load its drivers which are configured by the dtb file.
The Linux kernel is compiled without any dependency on the Device Tree.
The compilation of the kernel does depend on the chip architecture, but which code modules that are compiled depends on the board configuration(s) and feature selection.
BTW it's U-Boot for Universal Boot, not microBoot.
2) Mixing and matching: I'm under the impression that I can mix and match any combination of boot loader, dtb, kernel, rootfs, and modules given the following
kernel: must know which chip it is compiled for
dtb: must know the board details and chip, i.e. how much ram, configure a GPIO for SPI
boot loader: must know the chip and uEnv.txt must have params for the kernel and dtb location
rootfs: completely independent
modules: must be compiled with the specific version of kernel
Essentially correct, but typically one doesn't go overboard in trying to "mix-n-match". There are often optimal or preferred (or at least appropriate) choices.
By "rootfs" I'm assuming you mean type of filesystem for the rootfs, rather some image of a rootfs. (See Addendum below.)
3) Drivers: If I want to load a SPI driver do I need anything specific or
There are two types of "SPI driver", the master and protocol.
The SPI master driver is for the SPI controller chip that serves as the one interface master. This is usually a platform driver and not have a device node in /dev.
For each SPI slave device there must be a protocol driver. This driver will typically have a device node in /dev.
will the kernel know how to operate this because the dtb file setup the required registers?
The Device Tree must specify which driver is for which device and any/all resources allocated/assigned to each device.
The dtb file does not "setup" anything. It's only configuration data; there is no executable code. A device driver, typically during its probe or initialization phase, is responsible for acquiring/allocating its resources.
4) Modules: Are these just dependent on the kernel or do they need to know something about the chip and board?
Your use of "modules" is ambiguous. Source code files are sometimes referred to as "modules". Presumably you really mean loadable kernel modules.
Although most people associate kernel modules (only) with device drivers, other kernel services such as filesystems and network protocol handlers can also be built as modules.
The primary rationale for a kernel module versus static linkage (i.e. built in the kernel) is for runtime configurability (which in turn improves memory efficiency). Optional features, services and drivers can be left out of the kernel that is booted, but can still be loaded later when needed.
Loadable modules are "dependent" on the kernel simply because of linking requirements for proper execution. The degree of "chip and board knowledge" obviously depends on the functionality of the module, just like any other piece of kernel code.
Addendum
when I say rootfs I am referring to a prebuilt rootfs
A kernel image and (prebuilt) rootfs image are not "completely independent".
The executable binaries and the shared libraries in the rootfs image must be compatible with the kernel features. More significantly, since kernel loadable modules are installed in the rootfs and not with the kernel image, and these modules can be strictly tied to a specific build of a kernel version, it makes sense to pair a kernel image with a rootfs image.

Simple bootloader for running Linux kernel on a simulator

We have built a simple instruction set simulator for the sparc v8 processor. The model consists of a v8 processor, a main memory and a character input and a character output device. Currently I am able to run simple user-level programs on this simulator which are built using a cross compiler and placed in the modeled main memory directly.
I am trying to get a linux kernel to run on this simulator by building a simplest bootloader. (I'm considering uClinux which is made for mmu-less systems). The uncompressed kernel and the filesystem are both assumed to be present in the main memory itself, and all that my bootloader has to do is pass the relevant information to the kernel and make a jump to the start of the kernel code. I have no experience in OS development or porting linux.
I have the following questions :
What is this bare minimum information that a bootloader has to supply to the kernel ?
How to pass this information?
How to point the kernel to use my custom input/output devices?
There is some documentation available for porting linux to ARM boards, and from this documentation, it seems that the bootloader passes information about the size of RAM etc
via a data structure called ATAGS. How is it done in the case of a Sparc processor? I could not find much documentation for Sparc on the internet. There exists a linux bootloader for the Leon3 implementation of Sparc v8, but I could not find the specific information I was looking for in its code.
I will be grateful for any links that explain the bare minimum information to be passed to a kernel and how to pass it.
Thanks,
-neha

how to burn a uboot to board NAND flash

I am having a question regarding Uboot. I am looking forward to make a ARM based Board.
Now i want to to burn Uboot to NAND flash attached to my controller. How can i perform this operation ?
http://www.stlinux.com/u-boot/target-install
What i got from this link is that -- STx7111 Mboard - have some serial port which is capable to communicate with GDB.
And from GDB we use to burn following file u-boot. Is this file burned in RAM or NAND flash by gdb ?
Then execution moves to this u-boot program "u-boot". Now this program "u-boot" will burn the actual u-boot.bin onto the NAND flash.
Do every controller have some serial port which is capable to communicate with GDB ?
Do every controller follow this approach to burn uboot bootloader into its NAND flash ?
Please suggest.
What i got from this link is that -- STx7111 Mboard - have some serial port which is capable to communicate with GDB. And from GDB we use to burn following file u-boot. Is this file burned in RAM or NAND flash by gdb ?
No, you did not read that article accurately.
GDB is merely used as the interface to the JTAG.
This first step is to load an executable (a copy of U-Boot) into RAM.
Do every controller have some serial port which is capable to communicate with GDB ?
Do every controller follow this approach to burn uboot bootloader into its NAND flash ?
You should avoid making (or trying to make) sweeping generalizations (in this and your other postings).
The features and capabilities of microcontrollers, microprocessors and SoCs ("controllers" is something else) is so broad that very few generalization can be made. Rarely is there only "one way" to perform these procedures.
In order the write a copy of U-Boot (or any file image) to NAND flash, there are two steps:
transfer the image file from the host PC (or some storage device) into local memory;
erase the NAND flash blocks, and then write the image file to NAND flash with ECC if required and cognizant of bad blocks.
These are not trivial steps, so a capable utility is needed. There are at least three approaches:
The microcontroller can be configured (via input pins) to a "receive and write an image file" mode on power-up. A hardcoded program in ROM will load the image and write it to the integrated flash.
The SoC ROM has a bootloader that has capabilities to communicate with a host PC over RS232 or USB, and can perform as the client side of a proprietary utility program. On the host PC you would run the server side of this utility program. This scheme would allow transferring files and reading & writing the target's memories. Atmel's SAM-BA utility fits into this category.
Use an open-source utility, such as U-Boot, that is configurable and extensible to support the external NAND flash and any other memory types on your board, and also has file transfer capabilities. The console for U-Boot is typically a UART/USART serial port, but can be configured to use a USB-to-RS232 adapter.
In the case of using a program like U-Boot to install programs in NAND, a chicken versus egg situation arises: how to get this program loaded in the first place? The two common approaches are:
a. Install the utility (i.e. U-Boot) on a SDcard with any required bootloader, and then boot the SoC from the SDcard. This assumes that the SoC has this booting capability, but this scheme requires the least operator skill.
b. Load the utility (i.e. U-Boot) using JTAG, such as Segger J-Link, which will allow you to transfer the image file to RAM (assuming that RAM has been properly initialized if necessary) and then start its execution. The J-Link can be interfaced using its own JLINK program or GDB.
Once U-Boot is resident and executing, you have all of its capabilities available. U-Boot cannot write itself to NAND flash, so you have to load another copy of U-Boot in order to write it to NAND (or any other type of) flash.
If you load something using GDB, then it must be loaded in RAM..
Using gdb you will run that binary (u-boot), and the binary will give you the u-boot prompt, which you use to burn another image (it can be u-boot.img (configured for running from FLASH), linux kernel image, or any other image) into the flash (it can be NOR or NAND)..

Resources