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:
- DOS FS, FAT16 and FAT32 formats with cluster sizes up to 4048 bytes
- RFS or RTEMS File System. A small, fast file system for embedded systems
- 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