File System Development, Testing and Debugging

File System Development, Testing and Debugging

This topic outlines some techniques I use to write a file system. I use the same techniques to debug and test file systems.

File System Stack

A file system sits between the user facing calls such as open(), close(), read(), write(), ioctl() and the media the file system is hosted on. RTEMS supports the POSIX standard calls for user applications. The media can be access directly with drivers or the libblock block IO cache can be used to improve performance on slow media.

File Systems

The file systems RTEMS supports are:

  1. DOS FS, FAT16 and FAT32 formats with cluster sizes up to 4048 bytes
  2. RFS or RTEMS File System. A small, fast file system for embedded systems
  3. JFFSv2, Flash file system

Media

A file system needs media to hold the data the file system manages. The development of a file system wants a stable media to avoid any unrelated and unneeded bugs. The RAM disk provides a simple volatile media.

If you are working with DOSFS the qemu simulator supports creating a DOFS disk from a host directory.

BSP and QEMU

This topic will use the i386/pc686 BSP and QEMU.

i386 Tools

The RSB can build the tools for RTEMS 7. First get a recent copy of the RSB from GitLab:

mkdir rtems
cd rtems
git clone https://gitlab.rtems.org/rtems/tools/rtems-source-builder.git

Select a suitable directory to install the tools:

cd rtems-source-builder/rtems
../source-builder/sb-set-builder --prefix=/opt/rtems/7 --log=i386.txt 7/rtems-i386
cd ../..

QEMU

If your host has a working QEMU for i386 you can use it. If not you can build QEMU using the RSB:

cd rtems-source-builder/bare
../source-builder/sb-set-builder --prefix=/opt/rtems/qemu --log=q.txt devel/qemu
cd ../..

The commands in this topic will use the QEMU built by the RSB.

i386/pc686 BSP

To build the BSP we need a configuration file. This is a simple configuration file:

[DEFAULT]
# Disabled debug because this BSP has a chain init bug
# I will change this once fixed
RTEMS_DEBUG = False
RTEMS_POSIX_API = True

[i386/pc686]
BUILD_TESTS = True

Save this to a file called pc686.ini. Get a recent copy of RTEMS kernel code from GitLab:

git clone https://gitlab.rtems.org/rtems/rtos/rtems.git

Use the same prefix to install RTEMS. We will not need to install RTEMS because are developing RTEMS code:

cd rtems
./waf configure --pefix=/opt/rtems/7 --rtems-config=../pc686.ini

If you are using this procedure to work on an 3rd party package such as Micropython install RTEMS and then use the installed RTEMS:

./waf install

The RTEMS header files and libraries will be installed under the --prefix path supplied in the RTEMS configure step.

Running fileio.exe

The testsuite has the fileio test and that provides an application base you can use to run and test your file system. We will run the test with QEMU and have it provide a DOSFS disk of a directory we can hold some files. This assumes we are working on a DOSFS file system.

This shell script shows how to run QEMU for this BSP. It takes 2 arguments. The first is a directory of files and the second is the test executable:

#! /bin/sh
set -x
vdir=$1
shift
/opt/rtems/qemu/bin/qemu-system-i386 \
    --cpu core2duo \
    -no-reboot \
    -append "--console=/dev/com1" -serial stdio \
    -drive file=fat:rw:$vdir,format=raw,media=disk \
    -kernel $*

You will need to run the following command after creating the script to run it:

chmod +x pc-qemu

To run the test after building RTEMS execute:

../pc-qemu files build/i386/pc686/testsuites/samples/fileio.exe

If you want to debug RTEMS add the -s option:

../pc-qemu files build/i386/pc686/testsuites/samples/fileio.exe -s

If you want to debug RTEMS start up code also add the -S option:

../pc-qemu files build/i386/pc686/testsuites/samples/fileio.exe -s -S

The QEMU Debug documentation shows how you start GDB. Provide GDB with the same fileio.exe you started QEMU with.

Using fileio

The fileio test provides you with a range of functions when it starts. Press a key and start a shell and login as root:

+ vdir=files
+ shift
+ /opt/work/rtems/qemu/bin/qemu-system-i386 --cpu core2duo -no-reboot -append '--console=/dev/com1' -serial stdio -drive 'file=fat:rw:files,format=raw,media=disk' -kernel build/i386/pc686/testsuites/samples/fileio.exe
qemu-system-i386: warning: TCG doesn't support requested feature: CPUID.80000001H:EDX.syscall [bit 11]
qemu-system-i386: warning: TCG doesn't support requested feature: CPUID.80000001H:EDX.lm [bit 29]
i386: isr=0 irr=1
i386: isr=0 irr=1
IDE0:master:QEMU HARDDISK, 516.0M (16/1024/63), max blk size:8192


*** BEGIN OF TEST FILE I/O ***
*** TEST VERSION: 7.0.0.abd8d79391be512749331c1e68be1ce4fe934354
*** TEST STATE: USER_INPUT
*** TEST BUILD: RTEMS_POSIX_API
*** TEST TOOLS: 13.3.0 20240521 (RTEMS 7, RSB 170160cb918e7c68b4b35d8f0a42db6df81168e7, Newlib 1b3dcfd)
Press any key to start file I/O sample (20s remaining)
Press any key to start file I/O sample (19s remaining)
 =========================
 RTEMS FILE I/O Test Menu
 =========================
   p -> part_table_initialize
   f -> mount all disks in fs_table
   l -> list  file
   r -> read  file
   w -> write file
   s -> start shell
   Enter your selection ==>s
Creating /etc/passwd and group with four useable accounts:
  root/pwd
  test/pwd
  rtems/NO PASSWORD
  chroot/NO PASSWORD
Only the root user has access to all available commands.
 =========================
 starting shell
 =========================

Welcome to rtems-7.0.0 (Intel i386/Pentium/pc686)
Copyright (C) 1989, 2021 RTEMS Project and contributors
Login into RTEMS
/dev/foobar login: root
Password:

RTEMS Shell on /dev/foobar. Use 'help' to list commands.
SHLL [/] #

The password for the root account is pwd.

Using a RAM disk

To make a RAM disk, create a DOSFS file system and mount it enter the following commands:

SHLL [/] # mkrd
Register RAM Disk Driver [blocks=1024 block-size=512]:successful
SHLL [/] # mkdos /dev/rda
msdos format: /dev/rda
msdos format successful
SHLL [/] # mkdir dosfs
SHLL [/] # mount -t dosfs /dev/rda /dosfs
mounted /dev/rda -> /dosfs

Note: You need rtos/rtems!480 for the mount command to work.
To mount the QEMU DOSFS disk:

SHLL [/] # fdisk /dev/hda register
SHLL [/] # mkdir qemu
SHLL [/] # mount -t dosfs /dev/hda1 /qemu
mounted /dev/hda1 -> /qemu
2 Likes

Thanks for the tutorial. It is indeed working!
Just a quick note, I don’t know if it’s on my side but ./waf --prefix=... does not configure, instead I have to use this:

./waf configure --pefix=/opt/rtems/7 --rtems-config=../pc686.ini.

Thank you for the review and feedback. I have fixed the configure command.

You are welcome! I was going over this again, and noticed a couple of other steps that could help:

  1. After building the RSB, we need to do:
export PATH=/opt/rtems/7:"$PATH"
  1. We have to make sure the pc-qemu is executable:
chmod +x pc-qemu
  1. We need to make sure the files directory exists where we run the pc-qemu command:
mkdir -p files
  1. If you are running QEMU locally, replace /opt/rtems/qemu/bin/qemu-system-i386 with qemu-system-i386 in the script.

Setting a Path

I avoid adding the path to my RTEMS tools to my $PATH. I actually avoid adding anything that effects a build to my environment.

The reason is the magic effect it can have on builds. I found over the years subtle bugs and differences appear that end up being related back to the environment. For example a path not updated to point to a different version of the tools. I have a number of machines and others using them so I have a number of varying builds of the tool at any one time. A fixed path only makes things more complicated, ie removing one path to adding another.

If you look across all the builds we do in RTEMS you will see the path to the tools is either based on the --prefix configure option of the --rtems-tool option. The build system uses those paths to find the tools and then caches and uses that path. There is no need to set the path. I do use a full path to tools like gdb.

Environment variables are a difficult area to audit and track when looking to do repeatable quality controlled builds. For example a CC environment variable can change a compiler or add extra flags to a build. This can be helpful but it also provides a low level back door to deep into a build system.

File Directory

Maybe I need to explain that better. You point it to any directory you have. You do not need to make one to follow the procedure.

1 Like