Configuration - Raspberry Pi Documentation
Configuration - Raspberry Pi Documentation
We use optional cookies, as detailed in our cookie policy, to remember your settings and understand how you use our website.
raspi-config
Screen blanking
Configuration Getting started
Users
raspi-config To open the configuration tool from the desktop GUI, go to Preferences > Raspberry Pi External storage
Update Use the up and down arrow keys to scroll through the settings list. Configure UARTs
Finish Return to the settings list using the Left arrow or Tab. Change the default pin
configuration
non-interactive Type a letter to jump ahead alphabetically. For example, type E to jump ahead to
raspi-config 'Europe' in the time zone list.
Displays
Audio
Networking
Screen blanking
Users
External storage
Localise your
Raspberry Pi
Secure your
Raspberry Pi
Set up a headless
Raspberry Pi
Host a wireless
network from your
System options
Raspberry Pi
Configure parts of the boot, login, and networking process, along with other system
Use a proxy server level changes.
Hostname
Boot/Auto login
Boot to console or desktop with the option of an automatic login to your current user
account.
Network at boot
Splash screen
Power LED
If your Raspberry Pi model allows, change the behaviour of the power LED.
Browser
Display options
Underscan
NOTE
If the initial text shown on the screen disappears off the edge, enable overscan to adjust
the border. On some displays, particularly monitors, disabling overscan will make the
picture fill the whole screen and remove the black border.
Screen blanking
VNC resolution
Composite
4Kp60 HDMI
Interface options
Enable and disable various physical and virtual interfaces.
SSH
SSH allows you to remotely access the command line of the Raspberry Pi from another
computer. SSH is disabled by default. For more information about SSH, see the SSH
documentation.
RPi Connect
Enable or disable Raspberry Pi Connect, which provides the ability to access your
Raspberry Pi remotely with no manual network configuration.
VNC
Enable or disable SPI interfaces and automatic loading of the SPI kernel module.
I2C
Enable or disable I2C interfaces and automatic loading of the I2C kernel module.
Serial port
1-Wire
Enable or disable the Dallas 1-wire interface, often used for DS18B20 temperature
sensors.
Remote GPIO
Performance options
Overclock
If your Raspberry Pi model allows, overclock the CPU. Overclocking potential varies
between individual Raspberry Pi devices, even within the same model. Overclocking too
high may result in instability.
WARNING
GPU memory
Fan
Localisation options
Configure location and country-related options.
Locale
Time zone
Set your local time zone in the format Region/City, for example 'Europe/London'. Type
a letter to jump to that letter in the list.
Keyboard
Open a menu where you can select your keyboard layout. Changes usually take effect
immediately, but may require a reboot. Type a letter to jump to that letter in the list.
WLAN country
Advanced options
WARNING
Expand your OS partition to fill the whole storage device, giving you more space to use
for files. Reboot your Raspberry Pi to complete this action. Normally, Raspberry Pi OS
runs this action on first boot. This option can be useful if you clone your OS to a
separate storage device with more capacity than the original.
WARNING
There is no confirmation step. Selecting the option begins the partition expansion
immediately.
Boot order
On Raspberry Pi 4 and later, specify whether to boot from USB or network when no SD
card or SSD has been detected. For more information, see bootloader configuration.
Bootloader version
On the Raspberry Pi 4 and later, switch to the latest boot ROM software. Alternatively,
you can revert to the factory default if the latest version causes problems.
Wayland
Switch between the X11 and Wayland backends, and choose a window manager. Since
Raspberry Pi OS Bookworm, all Raspberry Pi models run Wayland using labwc by
default.
NOTE
Audio config
Switch between the PulseAudio and PipeWire audio backends. Prior to Raspberry Pi OS
Bookworm, Raspberry Pi OS used PulseAudio.
Update
Update this tool to the latest version.
About raspi-config
Display a description of raspi-config.
Finish
Exit raspi-config. If necessary, raspi-config will ask you to reboot when you exit.
When implementing changes for the first time, reboot to ensure your changes take
effect.
non-interactive raspi-config
The raspi-config tool also supports non-interactive options and flags that change
options entirely on the command line with no visual component. Available options may
differ between Raspberry Pi models.
NOTE
The meaning of 0 and 1 varies between options. Always check the documentation
before passing a value to an option.
System options
Wireless LAN
Pass a wireless network name (SSID) and passphrase, if required. The following flags
are optional:
The <hidden> option indicates the visibility of the SSID. If the network broadcasts an
open SSID, pass 0 or omit the option. If your SSID is hidden, pass 1. Defaults to 0.
The <plain> option indicates whether the given passphrase is wrapped in an extra set
of quotation marks. Most users can ignore this option: as an implementation detail,
raspi-config may need to add quotation marks before passing the passphrase to
other parts of the system, and a <plain> value of 0 indicates that the quotation marks
are already present. A value of 1 indicates that the quotation marks are not present, and
the implementation should add them as necessary. Defaults to 1. To pass this option,
you must specify a value for <hidden>.
non-hidden network named myssid with the passphrase mypassphrase, where you
have already added extra quotes to the passphrase:
Audio
1: vc4-hdmi-0
2: vc4-hdmi-1
For a full list of possible <N> values, see the numbers used in the interactive raspi-
config version of this option.
Password
NOTE
This function uses a full-screen interactive interface, even when run from a CLI
option.
Hostname
Boot/Auto login
whether your Raspberry Pi automatically logs into your current user account when
powered on
Network at boot
Splash screen
Power LED
If your Raspberry Pi model allows, change the behaviour of the power LED.
Browser
Change the default web browser. Choosing a web browser that isn’t currently installed
won’t work.
Display options
Underscan
NOTE
If the initial text shown on the screen disappears off the edge, enable overscan to adjust
the border. On some displays, particularly monitors, disabling overscan will make the
picture fill the whole screen and remove the black border.
Device:
1: HDMI-1
2: HDMI-2
Enabled:
0: enable overscan
1: disable overscan
Screen blanking
VNC resolution
Composite
On Raspberry Pi 4:
On other models:
Interface options
SSH
SSH allows you to remotely access the command line of the Raspberry Pi from another
computer. For more information about SSH, see the SSH documentation.
0: enable SSH
1: disable SSH
Raspberry Pi Connect
Enable or disable Raspberry Pi Connect, which provides the ability to access your
Raspberry Pi remotely with no manual network configuration.
VNC
Enable or disable a Virtual Network Computing (VNC) server. For more information
about VNC, see the VNC documentation.
0: enable VNC
1: disable VNC
SPI
Enable or disable SPI interfaces and automatic loading of the SPI kernel module.
0: enable SPI
1: disable SPI
I2C
Enable or disable I2C interfaces and automatic loading of the I2C kernel module.
0: enable I2C
1: disable I2C
Serial Port
Serial console
1-wire
Enable or disable the Dallas 1-wire interface. This is usually used for DS18B20
temperature sensors.
0: enable 1-wire
1: disable 1-wire
Remote GPIO
Performance options
Overclock
If your Raspberry Pi model allows, overclock the CPU. Overclocking potential varies
between individual Raspberry Pi devices, even within the same model. Overclocking too
high may result in instability.
WARNING
GPU memory
Fan
Customise the behaviour of the GPIO-connected Raspberry Pi 4 Case Fan. This setting
is inapplicable to other fan models.
0: enable fan
1: disable fan
Localisation options
Locale
For a full list of possible <locale> values, see the abbreviations used in the interactive
raspi-config version of this option.
Time zone
Set your local time zone in the format Region/City, for example 'Europe/London'.
For a full list of possible <timezone> values, see the abbreviations used in the
interactive raspi-config version of this option.
Keyboard
Set your keyboard layout. Changes usually take effect immediately, but may require a
reboot.
For a full list of possible <keymap> values, see the the abbreviations used in the
interactive raspi-config version of this option.
WLAN country
Advanced options
WARNING
Expand filesystem
Expand your OS partition to fill the whole storage device, giving you more space to use
for files. Reboot the Raspberry Pi to complete this action. Normally, Raspberry Pi OS
runs this action on first boot. This option can be useful if you clone your OS to a
separate storage device with more capacity than the original.
WARNING
There is no confirmation step. Selecting the option begins the partition expansion
immediately.
Boot order
On the Raspberry Pi 4 and later, specify whether to boot from USB or network in
absence of an SD card. See the bootloader configuration section for more information.
Depending on your device, you can choose from the following options:
B1: SD card boot - boot from SD card if available, otherwise boot from NVMe,
otherwise boot from USB
B2: NVMe/USB boot - boot from NVMe if available, otherwise boot from USB if
available, otherwise boot from SD card
B3: Network boot - boot from SD card if inserted, otherwise boot from network
Bootloader version
On the Raspberry Pi 4 and later, switch to the latest boot ROM software. Alternatively,
you can revert to the factory default if the latest version causes problems.
Wayland
Switch between the X11 and Wayland backends, and choose a window manager. Since
Raspberry Pi OS Bookworm, all Raspberry Pi models run Wayland using the labwc
window manager by default.
NOTE
To use Wayland on Raspberry Pi models prior to Raspberry Pi 4 running a version of
Raspberry Pi OS earlier than Bookworm, add wayland=on to
/boot/firmware/cmdline.txt.
Audio config
Use this option to switch between the PulseAudio and PipeWire audio backends. Prior
to Raspberry Pi OS Bookworm, Raspberry Pi OS used PulseAudio.
Update
Update this tool to the latest version.
Displays
Edit this on GitHub
To configure your Raspberry Pi to use a non-default display mode, set the resolution or
rotation manually.
The Raspberry Pi Zero, Zero W and Zero 2 W have a mini HDMI port, so you need a mini-
HDMI-to-full-size-HDMI lead or adapter.
Flagship models since Raspberry Pi 4B and Keyboard models have two micro HDMI
ports, so you need a micro-HDMI-to-full-size-HDMI lead or adapter for each display you
wish to attach. Connect the cables before turning on the Raspberry Pi.
Flagship models since Raspberry Pi 4B, Compute Modules since CM4 (except for
CM4S), and Keyboard models can drive up to two displays.
5-series devices support up to two displays at 4K resolution at a 60hz refresh rate with
no additional configuration.
Alternatively, use the following command to open the Screen Configuration utility:
$ raindrop
TIP
If your installation of Raspberry Pi OS doesn’t already include raindrop, you can install it
with the following command:
$ sudo apt install raindrop
To manually configure resolution and rotation, you’ll need to know the names of your
display devices. To determine the device names, run the following command to display
information about attached devices:
To set a custom resolution, use our Screen Configuration tool, raindrop. If your
Raspberry Pi OS installation doesn’t already include raindrop (for instance, if you’re still
using the previous Screen Configuration tool, arandr), you can download raindrop
from apt or the Recommended Software GUI.
To set a custom resolution, use our Screen Configuration tool, raindrop. If your
Raspberry Pi OS installation doesn’t already include raindrop (for instance, if you’re still
using the previous Screen Configuration tool, arandr), you can download raindrop
from apt or the Recommended Software GUI.
If you run the Wayland desktop compositor, you can set a custom display rotation with
wlr-randr. The following commands rotate the display by 0°, 90°, 180°, and 270°:
NOTE
You can also use one of the following --transform options to mirror the display at the
same time as rotating it: flipped, flipped-90, flipped-180, flipped-270.
NOTE
When using console mode with multiple displays, all connected displays share the
same rotation settings.
Audio
Edit this on GitHub
Raspberry Pi OS has multiple audio output modes: HDMI 1, the headphone jack (if your
device has one), and USB audio.
Right-click the volume icon on the system tray to open the audio output selector.
This interface lets you choose an audio output device. Click an audio output
device to switch audio output to that device.
You may see a device profile named Pro Audio when viewing an audio device in
the audio output selector. This profile exposes the maximum number of channels
across every audio device, allowing you greater control over the routing of signals.
Unless you require fine-tuned control over audio output, use a different device
profile.
For more information about the Pro Audio profile, visit PipeWire’s FAQ.
Networking
Edit this on GitHub
NOTE
Access Network Manager via the network icon at the right-hand end of the menu bar. If
you are using a Raspberry Pi with built-in wireless connectivity, or if a wireless dongle is
plugged in, click this icon to bring up a list of available wireless networks. If you see the
message 'No APs found - scanning…', wait a few seconds, and Network Manager should
find your network.
NOTE
Devices with dual-band wireless automatically disable networking until you assign a
wireless LAN country. Flagship models since Raspberry Pi 3B+, Compute Modules
since CM4, and Keyboard models support dual-band wireless. To set a wireless LAN
country, open the Raspberry Pi Configuration application from the Preferences
menu, select Localisation and select your country from the menu.
The icons on the right show whether a network is secured or not, and give an indication
of signal strength. Click the network that you want to connect to. If the network is
secured, a dialogue box will prompt you to enter the network key:
Enter the key and click OK, then wait a couple of seconds. The network icon will flash
briefly to show that a connection is being made. When connected, the icon will stop
flashing and show the signal strength.
To use a hidden network, navigate to Advanced options > Connect to a hidden Wi-Fi
network in the network menu:
Then, enter the SSID for the hidden network. Ask your network administrator which type
of security your network uses; while most home networks currently use WPA and WPA2
personal security, public networks sometimes use WPA and WPA2 enterprise security.
Select the security type for your network, and enter your credentials:
Click the Connect button to initiate the network connection.
This guide will help you configure a wireless connection on your Raspberry Pi from a
terminal without using graphical tools. No additional software is required.
NOTE
This guide should work for WEP, WPA, WPA2, or WPA3 networks, but may not work
for enterprise networks.
On a fresh install, you must specify the country where you use your device. This allows
your device to choose the correct frequency bands for 5GHz networking. Once you have
specified a wireless LAN country, you can use your Raspberry Pi’s built-in wireless
networking module.
To do this, set your wireless LAN country with the command line raspi-config tool.
Run the following command:
$ sudo raspi-config
Select the Localisation options menu item using the arrow keys. Choose the WLAN
country option. Pick your country from the dropdown using the arrow keys. Press
Enter to select your country.
You should now have access to wireless networking. Run the following command to
check if your Wi-Fi radio is enabled:
If this command returns the text "enabled", you’re ready to configure a connection. If
this command returns "disabled", try enabling Wi-Fi with the following command:
Find networks
Look in the "SSID" column for the name of the network you would like to connect to. Use
the SSID and a password to connect to the network.
Connect to a network
Your Raspberry Pi should automatically connect to the network once you enter your
password.
If you see error output that claims that "Secrets were required, but not provided", you
entered an incorrect password. Run the above command again, carefully entering your
password.
Check for an asterisk (*) in the "IN-USE" column; it should appear in the same row as
the SSID of the network you intended to connect to.
NOTE
If the network you are connecting to does not use a password, run the following
command:
WARNING
Unsecured wireless networks can put your personal information at risk. Whenever
possible, use a secured wireless network or VPN.
If you are using a hidden network, specify the "hidden" option with a value of "yes" when
you run nmcli:
If your device detects more than one known networks at the same time, it could
connect any of the detected known networks. Use the priority option to force your
Raspberry Pi to prefer certain networks. Your device will connect to the network that is
in range with the highest priority. Run the following command to view the priority of
known networks:
$ nmcli --fields autoconnect-priority,name connection
AUTOCONNECT-PRIORITY NAME
0 myNetwork
0 lo
0 Pi Towers
0 Example
-999 Wired connection 1
Use the nmcli connection modify command to set the priority of a network. The
following example command sets the priority of a network named "Pi Towers" to 10:
Your device will always try to connect to the in-range network with the highest non-
negative priority value. You can also assign a network a negative priority; your device
will only attempt to connect to a negative priority network if no other known network is
in range. For example, consider three networks:
AUTOCONNECT-PRIORITY NAME
-1 snake
0 rabbit
1 cat
1000 dog
If all of these networks were in range, your device would first attempt to connect to
the "dog" network.
If connection to the "dog" network fails, your device would attempt to connect to the
"cat" network.
If connection to the "cat" network fails, your device would attempt to connect to the
"rabbit" network.
If connection to the "rabbit" network fails, and your device detects no other known
networks, your device will attempt to connect to the "snake" network.
Configure DHCP
By default, Raspberry Pi OS attempts to automatically configure all network interfaces
by DHCP, falling back to automatic private addresses in the range 169.254.0.0/16 if
DHCP fails.
Screen blanking
Edit this on GitHub
You can configure your Raspberry Pi to blank the screen after a period of inactivity. By
default, Raspberry Pi OS blanks the screen after ten minutes of inactivity when screen
blanking is enabled.
Desktop
You can control screen blanking using the Screen Blanking option in the Raspberry Pi
Configuration menu.
Raspberry Pi Configuration
Click the Raspberry Pi button in the menu bar. Navigate to Preferences > Raspberry Pi
Configuration.
Select the Display tab. Toggle the Screen Blanking radio button into the on position.
Press OK to confirm your selection.
CLI
You can enable and disable screen blanking with the raspi-config CLI tool. Run the
following command to open the tool:
$ sudo raspi-config
Use the arrow keys to navigate and the Enter key to select. Select Display Options >
Screen Blanking. Choose yes with the arrow keys to enable screen blanking, or no to
disable screen blanking.
Console
The dpms_timeout screen blanking configuration used by Raspberry Pi Configuration
only affects desktop sessions. In console mode, when your Raspberry Pi is connected
to a monitor and keyboard with only a terminal for input, use the consoleblank setting
in the kernel command line.
Changes to cmdline.txt only take effect after a reboot. Use the following command to
reboot your Raspberry Pi:
$ sudo reboot
You can display the current console blank time in seconds with the following command:
$ cat /sys/module/kernel/parameters/consoleblank
Users
Edit this on GitHub
$ sudo raspi-config
$ passwd
Add a user
To add a new user, enter the following command, replacing the <username>
placeholder with the username for the new user:
You can find the home directory for the new user at /home/<username>/.
To grant the new user necessary permissions, like sudo, run the following command to
add the user to the associated user groups, replacing the <username> placeholder with
the username for the new user:
To check that the permissions were successfully granted, run the following command,
replacing the <username> placeholder with the username for the new user:
$ sudo su - <username>
If the above command runs successfully, permissions were successfully configured for
the user.
Delete a user
To delete a user, run the following command, replacing the <username> placeholder
with the username you would like to delete:
This command deletes the user as well as their home directory. If you’d like to preserve
the user’s home directory, run the command without the -remove-home option.
$ sudo raspi-config
Select option 1, Boot/Auto login. Reboot to put your changes into effect.
External storage
Edit this on GitHub
You can connect your external hard disk, SSD, or USB stick to any of the USB ports on
the Raspberry Pi, and mount the file system to access the data stored on it.
By default, your Raspberry Pi automatically mounts some of the popular file systems
such as FAT, NTFS, and HFS+ at the /media/pi/<HARD-DRIVE-LABEL> location.
NOTE
To set up your storage device so that it always mounts to a specific location of your
choice, you must mount it manually.
Plug the storage device into a USB port on the Raspberry Pi, and list all the disk
partitions on the Raspberry Pi using the following command:
The Raspberry Pi uses mount points / and /boot/firmware/. Your storage device will
show up in this list, along with any other connected storage.
Use the SIZE, LABEL, and MODEL columns to identify the name of the disk partition that
points to your storage device. For example, sda1. The FSTYPE column contains the
filesystem type. If your storage device uses an exFAT file system, install the exFAT
driver:
If your storage device uses an NTFS file system, you will have read-only access to it. If
you want to write to the device, you can install the ntfs-3g driver:
Run the following command to get the location of the disk partition:
$ sudo blkid
Create a target folder to be the mount point of the storage device. The mount point
name used in this case is mydisk. You can specify a name of your choice:
Verify that the storage device is mounted successfully by listing the contents:
$ ls /mnt/mydisk
$ sudo blkid
Find the disk partition from the list and note the UUID. (For example, 5C24-1453.) Open
the fstab file using a command line editor such as nano:
Replace fstype with the type of your file system, which you found when you went
through the steps above, for example: ntfs.
If the filesystem type is FAT or NTFS, add ,umask=000 immediately after nofail - this
will allow all users full read/write access to every file on the storage device.
Now that you have set an entry in fstab, you can start up your Raspberry Pi with or
without the storage device attached. Before you unplug the device you must either shut
down the Raspberry Pi, or manually unmount it.
NOTE
If you do not have the storage device attached when the Raspberry Pi starts, it will
take an extra 90 seconds to start up. You can shorten this by adding ,x-
systemd.device-timeout=30 immediately after nofail. This will change the
timeout to 30 seconds, meaning the system will only wait 30 seconds before giving
up trying to mount the disk.
For more information on each Linux command, refer to the specific manual page using
the man command. For example, man fstab.
If you receive an error that the 'target is busy', this means that the storage device was
not unmounted. If no error was displayed, you can now safely unplug the device.
The 'target is busy' message means there are files on the storage device that are in use
by a program. To close the files, use the following procedure.
Close any program which has open files on the storage device. If you have a terminal
open, make sure that you are not in the folder where the storage device is mounted, or
in a sub-folder of it.
If you are still unable to unmount the storage device, you can use the lsof tool to check
which program has files open on the device. You need to first install lsof using apt:
To use lsof:
$ lsof /mnt/mydisk
The Linux kernel accepts a collection of command line parameters during boot. On the
Raspberry Pi, this command line is defined in a file in the boot partition, called
cmdline.txt. You can edit this text file with any text editor.
IMPORTANT
Put all parameters in cmdline.txt on the same line. Do not use newlines.
To view the command line passed to the kernel at boot time, run the following
command:
$ cat /proc/cmdline
Because Raspberry Pi firmware makes changes to the command line before launching
the kernel, the output of this command will not exactly match the contents of
cmdline.txt.
Standard entries
console
defines the serial console. There are usually two entries:
console=serial0,115200
console=tty1
root
defines the location of the root filesystem. e.g. root=/dev/mmcblk0p2 means
multimedia card block 0 partition 2.
rootfstype
defines what type of filesystem the rootfs uses, e.g. rootfstype=ext4.
quiet
sets the default kernel log level to KERN_WARNING, which suppresses all but very
serious log messages during boot.
The legacy firmware and FKMS display modes used in earlier versions of Raspberry Pi
OS are no longer supported. Instead, recent OS versions use KMS (Kernel Mode
Setting).
video=HDMI-A-1:1920x1080M@60
video=HDMI-A-1:1920x1080M@60,rotate=90,reflect_x
You must specify the resolution explicitly when specifying rotation and reflection
parameters.
Possible options for the display type - the first part of the video= entry - include:
Composite-1 Composite
Other entries
This section contains some of the other entries you can use in the kernel command
line. This list is not exhaustive.
splash
tells the boot to use a splash screen via the Plymouth module.
plymouth.ignore-serial-consoles
normally if the Plymouth module is enabled it will prevent boot messages from
appearing on any serial console which may be present. This flag tells Plymouth to
ignore all serial consoles, making boot messages visible again, as they would be
if Plymouth was not running.
dwc_otg.lpm_enable=0
turns off Link Power Management (LPM) in the dwc_otg driver, which drives the
USB controller built into the processor used on Raspberry Pi computers. On
Raspberry Pi 4, this controller is disabled by default, and is only connected to the
USB type C power input connector. The USB-A ports on Raspberry Pi 4 are driven
by a separate USB controller which is not affected by this setting.
dwc_otg.speed
sets the speed of the USB controller built into the processor on Raspberry Pi
computers. dwc_otg.speed=1 will set it to full speed (USB 1.0), which is slower
than high speed (USB 2.0). This option should not be set except during
troubleshooting of problems with USB devices.
smsc95xx.turbo_mode
enables/disables the wired networking driver turbo mode.
smsc95xx.turbo_mode=N turns turbo mode off.
usbhid.mousepoll
specifies the mouse polling interval. If you have problems with a slow or erratic
wireless mouse, setting this to 0 with usbhid.mousepoll=0 might help.
drm.edid_firmware=HDMI-A-1:edid/your_edid.bin
Override your monitor’s built-in EDID with the contents of
/usr/lib/firmware/edid/your_edid.bin.
You can configure the UI language, keyboard layout, and time zone of Raspberry Pi OS
with the raspi-config tool.
Here, we describe some common ways to improve the security of your Raspberry Pi.
To force sudo to require a password, edit the nopasswd sudoers file for your user
account, replacing the <username> placeholder in the file name with your username:
Change the <username> entry to the following, replacing <username> with your
username:
Save the file. Your new preference should take effect immediately.
Update Raspberry Pi OS
Only the latest OS distribution contains all the latest security fixes. Always keep your
device updated to the latest version of Raspberry Pi OS.
You can also allow or deny specific users by altering the sshd configuration.
Add, edit, or append to the end of the file the following line, which contains the
usernames you wish to allow to log in:
You can also use DenyUsers to specifically stop some usernames from logging in:
After the change, restart the sshd service with the following command to put your
changes into effect:
Use a firewall
There are many firewall solutions available for Linux. Most use the underlying iptables
project to provide packet filtering. This project sits over the Linux netfiltering system. By
default, iptables is installed on Raspberry Pi OS, but is not set up. Setting it up can be
a complicated task, and one project that offers a simpler interface than iptables is
Uncomplicated Firewall (UFW). This is the default firewall tool in Ubuntu, and can be
installed on your Raspberry Pi:
ufw is a command-line tool, although there are some GUIs available for it. Note that ufw
needs to be run with superuser privileges, so all commands are preceded with sudo. It
is also possible to use the option --dry-run any ufw commands, which indicates the
results of the command without actually making any changes.
To enable the firewall, which will also ensure it starts up on boot, use:
Allow a particular port to have access (we have used port 22 in our example):
Denying access on a port is also very simple (again, we have used port 22 as an
example):
You can also specify which service you are allowing or denying on a port. In this
example, we are denying TCP on port 22:
You can specify the service even if you do not know which port it uses. This example
allows the ssh service access through the firewall:
The status command lists all current settings for the firewall:
Limit login attempts on ssh port using TCP. This denies connection if an IP address has
attempted to connect six or more times in the last 30 seconds:
Inside this configuration file are a set of default options, together with options for
checking specific services for abnormalities. To examine the rules used for ssh, open
jail.local in an editor:
Create the [ssh] section if it does not already exist and add the following lines to the
section:
[ssh]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 6
This enables Fail2ban checks for suspicious ssh activity, including system log checks,
and allows six retries before blocking activity.
The [default] section in this same file defines the default banning action, iptables-
multiport, which runs the /etc/fail2ban/action.d/iptables-multiport.conf file
when the detection threshold is reached:
Multiport bans all access on all ports. The action.d folder contains a number of
alternative action configuration files you can use to customise your server’s response to
suspicious activity.
For instance, to permanently ban an IP address after three failed attempts, change the
maxretry value in the [ssh] section to 3 and set the bantime to a negative number:
[ssh]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 3
bantime = -1
To connect your Raspberry Pi to a network, you can either plug your device into a wired
connection via Ethernet or configure wireless networking.
To access your Raspberry Pi over that network, use SSH. Once you’ve connected over
SSH, you can use raspi-config to enable VNC if you’d prefer a graphical desktop
environment.
If you’re setting up your Raspberry Pi from scratch, set up wireless networking and SSH
during the imaging process. If you’ve already got a Raspberry Pi set up, you can
configure SSH using raspi-config.
WARNING
Depending on the model of Raspberry Pi and type of SD card you use, your
Raspberry Pi may require up to five minutes to boot and connect to your wireless
network the first time it boots.
NOTE
Remote access
With no keyboard or monitor, you need a way to remotely control your headless
Raspberry Pi. On first boot, the only option is SSH. To enable SSH on a fresh installation
of Raspberry Pi OS, choose one of the following methods:
create a file named ssh at the root of the first partition of the SD card (labeled
bootfs), then configure a user manually with userconf.txt following the
instructions in the section below
For more information, see set up an SSH server. Once you’ve connected over SSH, you
can use raspi-config to enable VNC if you’d prefer a graphical desktop environment.
At the root of the first partition of your SD card (the filesystem labeled bootfs), create a
file named userconf.txt.
NOTE
<username> must only contain lower-case letters, digits and hyphens, and must
start with a letter. It may not be longer than 31 characters.
To generate the encrypted password, use OpenSSL on another computer. Open a
terminal and enter the following:
$ openssl passwd -6
When prompted, enter your password and verify it. This command will then output an
encrypted version of the supplied password.
Your Raspberry Pi can host its own wireless network using a wireless module. If you
connect your Raspberry Pi to the internet via the Ethernet port (or a second wireless
module), other devices connected to the wireless network can access the internet
through your Raspberry Pi.
Consider a wired network that uses the 10.x.x.x IP block. You can connect your
Raspberry Pi to that network and serve wireless clients on a separate network that uses
another IP block, such as 192.168.x.x.
In the diagram below, note that the laptop exists in an IP block separate from the router
and wired clients:
With this network configuration, wireless clients can all communicate with each other
through the Raspberry Pi router. However, clients on the wireless network cannot
directly interact with clients on the wired network other than the Raspberry Pi; wireless
clients exist in a private network separate from the network that serves wired clients.
NOTE
The Raspberry Pi 5, 4, 3, Zero W, and Zero 2 W can host a wireless network using
the built-in wireless module. Raspberry Pi models that lack a built-in module support
this functionality using a separate wireless dongle.
Enable hotspot
To create a hosted wireless network on the command line, run the following command,
replacing the <example-network-name> and <example-password> placeholders with
your own values:
Use another wireless client, such as a laptop or smartphone, to connect to the network.
Look for a network with a SSID matching <example-network-name>. Enter your
network password, and you should connect successfully to the network. If your
Raspberry Pi has internet access via an Ethernet connection or a second wireless
adapter, you should be able to access the internet.
Disable hotspot
To disable the hotspot network and resume use of your Pi as a wireless client, run the
following command:
TIP
In the diagram below, the laptop exists in the same IP block as the router and wired
clients:
The following steps describe how to set up a network bridge on your Raspberry Pi to
enable communication between wireless clients and the parent network.
$ sudo nmcli connection add type bridge con-name 'Bridge' ifname brid
ge0
Next, add your device’s Ethernet connection to the parent network to the bridge:
Finally, add your wireless hotspot connection to the bridge. You can either add an
existing hotspot interface or create a new one:
If you have already created a wireless hotspot connection using the instructions
above, add the existing interface to the bridge with the following command:
If you have not yet created a wireless hotspot connection, create a new interface and
add it to the bridge with a single command, replacing the <hotspot-ssid> and
<hotspot-password> placeholders with a network name and password of your
choice, respectively:
Now that you’ve configured your bridge, it’s time to activate it. Run the following
command to activate the bridge:
You can use the nmcli device command to verify that the bridge, Ethernet interface,
and wireless hotspot interface are all active.
TIP
Use a tool such as arp-scan to check if devices on the parent network are
accessible once connected to the hotspot.
A proxy server acts as an intermediary between a client device and the Internet. To
configure your Raspberry Pi as a proxy server client, follow the instructions in this
section.
Open a terminal window, and open the file /etc/environment using nano:
Add the following to the /etc/environment file to create the http_proxy variable:
export http_proxy="http://<proxy_ip_address>:<proxy_port>"
NOTE
If your proxy requires a username and password, add them using the following format:
export http_proxy="http://<username>:<password>@proxyipaddress:
proxyport"
Replace the <username> and <password> placeholders with the username and
password you use to authenticate with your proxy.
export https_proxy="http://username:password@proxyipaddress:proxypor
t"
export http_proxy="http://username:password@proxyipaddress:proxyport"
export https_proxy="http://username:password@proxyipaddress:proxypor
t"
export no_proxy="localhost, 127.0.0.1"
Add the following line to the file so sudo will use the environment variables you just
created:
Raspberry Pi OS stores boot files on the first partition of the SD card, formatted with the
FAT file system.
On startup, each Raspberry Pi loads various files from the boot partition in order to start
up the various processors before the Linux kernel boots.
NOTE
bootcode.bin
The bootloader, loaded by the SoC on boot. It performs some very basic setup, and then
loads one of the start*.elf files.
The Raspberry Pi 4 and 5 do not use bootcode.bin. It has been replaced by boot code
in the onboard EEPROM.
start*.elf
Binary firmware blobs loaded onto the VideoCore GPU in the SoC, which then take over
the boot process.
start.elf
the basic firmware.
start_x.elf
includes additional codecs.
start_db.elf
used for debugging.
start_cd.elf
a cut-down version of the firmware that removes support for hardware blocks
such as codecs and 3D as well as debug logging support; it also imposes initial
frame buffer limitations. The cut-down firmware is automatically used when
gpu_mem=16 is specified in config.txt.
For more information on how to use these files, see the config.txt documentation.
The Raspberry Pi 5 does not use elf files. The firmware is self-contained within the
bootloader EEPROM.
fixup*.dat
Linker files found in matched pairs with the start*.elf files listed in the previous
section.
cmdline.txt
The kernel command line passed into the kernel at boot.
config.txt
Contains many configuration parameters for setting up the Raspberry Pi. For more
information, see the config.txt documentation.
IMPORTANT
issue.txt
Text-based housekeeping information containing the date and git commit ID of the
distribution.
initramfs*
Contents of the initial ramdisk. This loads a temporary root file system into memory
before the real root file system can be mounted.
ssh or ssh.txt
When this file is present, enables SSH at boot. SSH is otherwise disabled by default. The
contents do not matter. Even an empty file enables SSH.
NOTE
lscpu reports a CPU architecture of armv7l for systems running a 32-bit kernel, and
aarch64 for systems running a 64-bit kernel. The l in the armv7l case refers to
little-endian CPU architecture, not LPAE as is indicated by the l in the kernel7l.img
filename.
overlays folder
Contains Device Tree overlays. These are used to configure various hardware devices,
such as third-party sound boards. Entries in config.txt select these overlays. For
more information, see Device Trees, overlays and parameters.
If a Raspberry Pi fails to boot for some reason, or has to shut down, in many cases an
LED will flash a specific number of times to indicate what happened. The LED will blink
for a number of long flashes (0 or more), then produce short flashes, to indicate the
exact status. In most cases, the pattern will repeat after a two-second gap.
0 8 SDRAM failure
0 9 Insufficient SDRAM
0 10 In HALT state
2 4 File signature/hash
mismatch - Pi 4 and Pi 5
3 4 Secure-boot configuration is
not valid
Configure UARTs
Edit this on GitHub
There are two types of UART available on the Raspberry Pi - PL011 and mini UART. The
PL011 is a capable, broadly 16550-compatible UART, while the mini UART has a
reduced feature set.
All UARTs on the Raspberry Pi are 3.3V only - damage will occur if they are connected to
5V systems. An adapter can be used to connect to 5V systems. Alternatively, low-cost
USB to 3.3V serial adapters are available from various third parties.
Name Type
UART0 PL011
Name Type
UART0 PL011
UART2 PL011
Name Type
UART3 PL011
UART4 PL011
UART5 PL011
Raspberry Pi 5
Raspberry Pi 5 has an additional four PL011s, which are disabled by default:
Name Type
UART0 PL011
UART1 PL011
UART2 PL011
UART3 PL011
UART4 PL011
On all models of Compute Module, the UARTs are disabled by default and can be
explicitly enabled using a Device Tree overlay. You may also specify which GPIO pins to
use, for example:
dtoverlay=uart1,txd1_pin=32,rxd1_pin=33
Primary UART
On the Raspberry Pi, one UART is selected to be present on GPIO 14 (transmit) and 15
(receive) - this is the primary UART. By default, this will also be the UART on which a
Linux console may be present. Note that GPIO 14 is pin 8 on the GPIO header, while
GPIO 15 is pin 10.
Secondary UART
The secondary UART is not normally present on the GPIO connector. By default, the
secondary UART is connected to the Bluetooth side of the combined wireless
LAN/Bluetooth controller, on models which contain this controller.
/dev/serial0 and /dev/serial1 are symbolic links which point to either /dev/ttyS0
or /dev/ttyAMA0.
Due to changes in Bookworm, /dev/serial1 does not exist by default. You can re-
enable serial1 by setting the following values in config.txt:
dtparam=krnbt=off
TIP
This option may not work on all models in the future. Only use this option if there is
no other alternative for your use case.
In order to use the mini UART, you need to configure the Raspberry Pi to use a fixed VPU
core clock frequency. This is because the mini UART clock is linked to the VPU core
clock, so that when the core clock frequency changes, the UART baud rate will also
change. The enable_uart and core_freq settings can be added to config.txt to
change the behaviour of the mini UART. The following table summarises the possible
combinations:
The default state of the enable_uart flag depends on which UART is the primary UART:
mini UART 0
Exit raspi-config and reboot the Raspberry Pi for changes to take effect
For Raspberry Pi 5, earlycon output only appears on the 3-pin debug connector with
the following configuration:
earlycon=pl011,0x107d001000,115200n8
earlycon=uart8250,mmio32,0xfe215040
earlycon=pl011,mmio32,0xfe201000
For Raspberry Pi 2, 3, 3+, Zero 2 W, Compute Module 3, and Compute Module 3+:
earlycon=uart8250,mmio32,0x3f215040
earlycon=pl011,mmio32,0x3f201000
earlycon=uart8250,mmio32,0x20215040
earlycon=pl011,mmio32,0x20201000
NOTE
Selecting the wrong early console can prevent the Raspberry Pi from booting.
disable-bt disables the Bluetooth device and makes the first PL011 (UART0) the
primary UART. You must also disable the system service that initialises the modem, so
it does not connect to the UART, using sudo systemctl disable hciuart.
miniuart-bt switches the Bluetooth function to use the mini UART, and makes the first
PL011 (UART0) the primary UART. Note that this may reduce the maximum usable
baud rate (see mini UART limitations below). You must also set the VPU core clock to a
fixed frequency using either force_turbo=1 or core_freq=250.
The overlays uart2, uart3, uart4, and uart5 are used to enable the four additional
UARTs on the Raspberry Pi 4. There are other UART-specific overlays in the folder. Refer
to /boot/firmware/overlays/README for details on Device Tree overlays, or run
dtoverlay -h overlay-name for descriptions and usage information.
You add a line to the config.txt file to apply a Device Tree overlay. Note that the -
overlay.dts part of the filename is removed. For example:
dtoverlay=disable-bt
The mini-UART has smaller FIFOs. Combined with the lack of flow control, this makes it
more prone to losing characters at higher baudrates. It is also generally less capable
than a PL011, mainly due to its baud rate link to the VPU clock speed.
No break detection
No framing errors detection
No parity bit
Further documentation on the mini UART can be found in the SoC peripherals
document.
Raspberry Pi kernels and firmware use a Device Tree (DT) to describe hardware. These
Device Trees may include DT parameters that to control onboard features. DT overlays
allow optional external hardware to be described and configured, and they also support
parameters for more control.
The firmware loader (start.elf and its variants) is responsible for loading the DTB
(Device Tree Blob - a machine-readable DT file). It chooses which one to load based on
the board revision number, and makes modifications to further tailor it. This runtime
customisation avoids the need for many DTBs with only minor differences.
User-provided parameters in config.txt are scanned, along with any overlays and
their parameters, which are then applied. The loader examines the result to learn (for
example) which UART, if any, is to be used for the console. Finally it launches the kernel,
passing a pointer to the merged DTB.
Device Trees
A Device Tree (DT) is a description of the hardware in a system. It should include the
name of the base CPU, its memory configuration, and any peripherals (internal and
external). A DT should not be used to describe the software, although by listing the
hardware modules it does usually cause driver modules to be loaded.
NOTE
Device Trees are usually written in a textual form known as Device Tree Source (DTS),
and are stored in files with a .dts suffix. DTS syntax is C-like, with braces for grouping
and semicolons at the end of each line. Note that DTS requires semicolons after closing
braces: think of C structs rather than functions. The compiled binary format is referred
to as Flattened Device Tree (FDT) or Device Tree Blob (DTB), and is stored in .dtb files.
/dts-v1/;
/include/ "common.dtsi";
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
cousin: child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint3
2 */
child-node1 {
my-cousin = <&cousin>;
};
};
};
/node2 {
another-property-for-node2;
};
The inclusion of another DTS file, conventionally named *.dtsi and analogous to a
.h header file in C
Properties are simple key-value pairs where the value can either be empty or contain an
arbitrary byte stream. While data types are not encoded in the data structure, there are a
few fundamental data representations that can be expressed in a Device Tree source
file.
Arbitrary byte data is delimited with square brackets, and entered in hex:
The /include/ directive results in simple textual inclusion, much like C’s #include
directive, but a feature of the Device Tree compiler leads to different usage patterns.
Given that nodes are named, potentially with absolute paths, it is possible for the same
node to appear twice in a DTS file (and its inclusions). When this happens, the nodes
and properties are combined, interleaving and overwriting properties as required (later
values override earlier ones).
In the example above, the second appearance of /node2 causes a new property to be
added to the original:
/node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
another-property-for-node2;
child-node1 {
my-cousin = <&cousin>;
};
};
It is therefore possible for one .dtsi to overwrite, or provide defaults for, multiple
places in a tree.
It is often necessary for one part of the tree to refer to another, and there are four ways
to do this:
Path strings
Similar to filesystem paths, e.g. /soc/i2s@7e203000 is the full path to the I2S
device in BCM2835 and BCM2836. The standard APIs don’t create paths to
properties like /soc/i2s@7e203000/status: instead, you first find a node, then
choose properties of that node.
Phandles
A unique 32-bit integer assigned to a node in its phandle property. For historical
reasons, you may also see a redundant, matching linux,phandle. Phandles are
numbered sequentially, starting from 1; 0 is not a valid phandle. They are usually
allocated by the DT compiler when it encounters a reference to a node in an
integer context, usually in the form of a label. References to nodes using phandles
are simply encoded as the corresponding integer (cell) values; there is no markup
to indicate that they should be interpreted as phandles, as that is application-
defined.
Labels
Just as a label in C gives a name to a place in the code, a DT label assigns a
name to a node in the hierarchy. The compiler takes references to labels and
converts them into paths when used in string context (&node) and phandles in
integer context (<&node>); the original labels do not appear in the compiled
output. Note that labels contain no structure; they are just tokens in a flat, global
namespace.
Aliases
Similar to labels, except that they do appear in the FDT output as a form of index.
They are stored as properties of the /aliases node, with each property mapping
an alias name to a path string. Although the aliases node appears in the source,
the path strings usually appear as references to labels (&node), rather then being
written out in full. DT APIs that resolve a path string to a node typically look at the
first character of the path, treating paths that do not start with a slash as aliases
that must first be converted to a path using the /aliases table.
How to construct a Device Tree, and how best to use it to capture the configuration of
some hardware, is a large and complex subject. There are many resources available,
some of which are listed below, but several points deserve highlighting:
compatible properties are the link between the hardware description and the driver
software. When an OS encounters a node with a compatible property, it looks it up
in its database of device drivers to find the best match. In Linux, this usually results
in the driver module being automatically loaded, provided it has been appropriately
labelled and not blacklisted.
The status property indicates whether a device is enabled or disabled. If the status
is ok, okay or absent, then the device is enabled. Otherwise, status should be
disabled, so that the device is disabled. It can be useful to place devices in a .dtsi
file with the status set to disabled. A derived configuration can then include that
.dtsi and set the status for the devices which are needed to okay.
When a system like Raspberry Pi also supports optional plug-in accessories such as
HATs, the problem grows. Ultimately, each possible configuration requires a Device Tree
to describe it, but once you factor in all the different base models and the large number
of available accessories, the number of combinations starts to multiply rapidly.
What is needed is a way to describe these optional components using a partial Device
Tree, and then to be able to build a complete tree by taking a base DT and adding a
number of optional elements. You can do this, and these optional elements are called
"overlays".
Unless you want to learn how to write overlays for Raspberry Pis, you might prefer to
skip on to Use Device Trees.
Fragments
A DT overlay comprises a number of fragments, each of which targets one node and its
subnodes. Although the concept sounds simple enough, the syntax seems rather
strange at first:
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&i2s>;
__overlay__ {
status = "okay";
test_ref = <&test_label>;
test_label: test_subnode {
dummy;
};
};
};
};
The compatible string identifies this as being for BCM2835, which is the base
architecture for the Raspberry Pi SoCs; if the overlay makes use of features of a
Raspberry Pi 4 then brcm,bcm2711 is the correct value to use, otherwise brcm,bcm2835
can be used for all Raspberry Pi overlays. Then comes the first (and in this case only)
fragment. Fragments should be numbered sequentially from zero. Failure to adhere to
this may cause some or all of your fragments to be missed.
Each fragment consists of two parts: a target property, identifying the node to apply
the overlay to; and the __overlay__ itself, the body of which is added to the target
node. The example above can be interpreted as if it were written like this:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
};
&i2s {
status = "okay";
test_ref = <&test_label>;
test_label: test_subnode {
dummy;
};
};
With a sufficiently new version of dtc you can write the example exactly as above and
get identical output, but some homegrown tools don’t understand this format yet. Any
overlay that you might want to see included in the standard Raspberry Pi OS kernel
should be written in the old format for now.
The effect of merging that overlay with a standard Raspberry Pi base Device Tree (e.g.
bcm2708-rpi-b-plus.dtb), provided the overlay is loaded afterwards, would be to
enable the I2S interface by changing its status to okay. But if you try to compile this
overlay using:
This shouldn’t be too unexpected, since there is no reference to the base .dtb or .dts
file to allow the compiler to find the i2s label.
Trying again, this time using the original example and adding the -@ option to allow
unresolved references (and -Hepapr to remove some clutter):
If dtc returns an error about the third line, it doesn’t have the extensions required for
overlay work. Run sudo apt install device-tree-compiler and try again - this
time, compilation should complete successfully. Note that a suitable compiler is also
available in the kernel tree as scripts/dtc/dtc, built when the dtbs make target is
used:
$ make ARCH=arm dtbs
Dump the contents of the DTB file to see what the compiler has generated:
$ fdtdump 1st.dtbo
/dts-v1/;
// magic: 0xd00dfeed
// totalsize: 0x207 (519)
// off_dt_struct: 0x38
// off_dt_strings: 0x1c8
// off_mem_rsvmap: 0x28
// version: 17
// last_comp_version: 16
// boot_cpuid_phys: 0x0
// size_dt_strings: 0x3f
// size_dt_struct: 0x190
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <0xffffffff>;
__overlay__ {
status = "okay";
test_ref = <0x00000001>;
test_subnode {
dummy;
phandle = <0x00000001>;
};
};
};
__symbols__ {
test_label = "/fragment@0/__overlay__/test_subnode";
};
__fixups__ {
i2s = "/fragment@0:target:0";
};
__local_fixups__ {
fragment@0 {
__overlay__ {
test_ref = <0x00000000>;
};
};
};
};
After the verbose description of the file structure there is our fragment. But look
carefully - where we wrote &i2s it now says 0xffffffff, a clue that something strange
has happened (older versions of dtc might say 0xdeadbeef instead). The compiler has
also added a phandle property containing a unique (to this overlay) small integer to
indicate that the node has a label, and replaced all references to the label with the same
small integer.
__symbols__ lists the labels used in the overlay (test_label here), and the path to
the labelled node. This node is the key to how unresolved symbols are dealt with.
__local_fixups__ holds the locations of any references to labels that exist within
the overlay - the test_ref property. This is required because the program
performing the merge will have to ensure that phandle numbers are sequential and
unique.
Back in section 1.3 it says that "the original labels do not appear in the compiled
output", but this isn’t true when using the -@ switch. Instead, every label results in a
property in the __symbols__ node, mapping a label to a path, exactly like the aliases
node. In fact, the mechanism is so similar that when resolving symbols, the Raspberry
Pi loader will search the "aliases" node in the absence of a __symbols__ node. This was
useful at one time because providing sufficient aliases allowed very old versions of dtc
to be used to build the base DTB files, but fortunately that is ancient history now.
To avoid the need for lots of Device Tree overlays, and to reduce the need for users of
peripherals to modify DTS files, the Raspberry Pi loader supports a new feature - Device
Tree parameters. This permits small changes to the DT using named parameters,
similar to the way kernel modules receive parameters from modprobe and the kernel
command line. Parameters can be exposed by the base DTBs and by overlays, including
HAT overlays.
Parameters are defined in the DTS by adding an __overrides__ node to the root. It
contains properties whose names are the chosen parameter names, and whose values
are a sequence comprising a phandle (reference to a label) for the target node, and a
string indicating the target property; string, integer (cell) and boolean properties are
supported.
String parameters
name = <&label>,"property";
where label and property are replaced by suitable values. String parameters can
cause their target properties to grow, shrink, or be created.
Note that properties called status are treated specially; non-zero/true/yes/on values
are converted to the string "okay", while zero/false/no/off becomes "disabled".
Integer parameters
Here, label, property and offset are replaced by suitable values; the offset is
specified in bytes relative to the start of the property (in decimal by default), and the
preceding separator dictates the size of the parameter. In a change from earlier
implementations, integer parameters may refer to non-existent properties or to offsets
beyond the end of an existing property.
Boolean parameters
Device Tree encodes boolean values as zero-length properties; if present then the
property is true, otherwise it is false. They are defined like this:
A property is assigned the value false by not defining it. Boolean parameters are
declared like this, replacing the label and property placeholders with suitable values:
name = <&label>,"property?";
Inverted booleans invert the input value before applying it in the same way as a regular
boolean; they are declared similarly, but use ! to indicate the inversion:
name = <&label>,"<property>!";
Boolean parameters can cause properties to be created or deleted, but they can’t delete
a property that already exists in the base DTB.
Byte string properties are arbitrary sequences of bytes, e.g. MAC addresses. They
accept strings of hexadecimal bytes, with or without colons between the bytes.
mac_address = <ðernet0>,"local_mac_address[";
The [ was chosen to match the DT syntax for declaring a byte string:
There are some situations where it is convenient to be able to set the same value in
multiple locations within the Device Tree. Rather than the ungainly approach of creating
multiple parameters, it is possible to add multiple targets to a single parameter by
concatenating them, like this:
__overrides__ {
gpiopin = <&w1>,"gpios:4",
<&w1_pins>,"brcm,pins:0";
...
};
NOTE
It is even possible to target properties of different types with a single parameter. You
could reasonably connect an "enable" parameter to a status string, cells containing
zero or one, and a proper boolean property.
Literal assignments
The DT parameter mechanism allows multiple targets to be patched from the same
parameter, but the utility is limited by the fact that the same value has to be written to
all locations (except for format conversion and the negation available from inverted
booleans). The addition of embedded literal assignments allows a parameter to write
arbitrary values, regardless of the parameter value supplied by the user.
str_val = <&target>,"strprop=value"; // 1
int_val = <&target>,"intprop:0=42" // 2
int_val2 = <&target>,"intprop:0=",<42>; // 3
bytes = <&target>,"bytestr[=b8:27:eb:01:23:45"; // 4
Lines 1, 2 and 4 are fairly obvious, but line 3 is more interesting because the value
appears as an integer (cell) value. The DT compiler evaluates integer expressions at
compile time, which might be convenient (particularly if macro values are used), but the
cell can also contain a reference to a label:
When the overlay is applied, the label will be resolved against the base DTB in the usual
way. It is a good idea to split multi-part parameters over multiple lines like this to make
them easier to read - something that becomes more necessary with the addition of cell
value assignments.
Bear in mind that parameters do nothing unless they are applied - a default value in a
lookup table is ignored unless the parameter name is used without assigning a value.
Lookup tables
Lookup tables allow parameter input values to be transformed before they are used.
They act as associative arrays, rather like switch/case statements:
A key with no =value means to use the key as the value, an = with no key before it is the
default value in the case of no match, and starting or ending the list with a comma (or
an empty key=value pair anywhere) indicates that the unmatched input value should be
used unaltered; otherwise, not finding a match is an error.
NOTE
The comma separator within the table string after a cell integer value is implicit -
adding one explicitly creates an empty pair (see above).
NOTE
As lookup tables operate on input values and literal assignments ignore them, it’s
not possible to combine the two - characters after the closing } in the lookup
declaration are treated as an error.
Overlay/fragment parameters
Examples:
Special properties
A few property names, when targeted by a parameter, get special handling. One you
may have noticed already - status - will convert a boolean to either okay for true and
disabled for false.
Assigning to the bootargs property appends to it rather than overwriting it - this is how
settings can be added to the kernel command line.
The reg property is used to specify device addresses - the location of a memory-
mapped hardware block, the address on an I2C bus, etc. The names of child nodes
should be qualified with their addresses in hexadecimal, using @ as a separator:
bmp280@76 {
reg = <0x77>;
...
};
When assigning to the reg property, the address portion of the parent node name will
be replaced with the assigned value. This can be used to prevent a node name clash
when using the same overlay multiple times - a technique used by the i2c-gpio
overlay.
The introduction of the Raspberry Pi 4, built around the BCM2711 SoC, brought with it
many changes; some of these changes are additional interfaces, and some are
modifications to (or removals of) existing interfaces. There are new overlays intended
specifically for the Raspberry Pi 4 that don’t make sense on older hardware, e.g.
overlays that enable the new SPI, I2C and UART interfaces, but other overlays don’t
apply correctly even though they control features that are still relevant on the new
device.
There is therefore a need for a method of tailoring an overlay to multiple platforms with
differing hardware. Supporting them all in a single .dtbo file would require heavy use of
hidden ("dormant") fragments and a switch to an on-demand symbol resolution
mechanism so that a missing symbol that isn’t needed doesn’t cause a failure. A
simpler solution is to add a facility to map an overlay name to one of several
implementation files depending on the current platform.
The overlay map is a file that gets loaded by the firmware at bootup. It is written in DTS
source format - overlay_map.dts, compiled to overlay_map.dtb and stored in the
overlays directory.
This is an extract from the current map file (see the full version):
/ {
disable-bt {
bcm2835;
bcm2711;
bcm2712 = "disable-bt-pi5";
};
disable-bt-pi5 {
bcm2712;
};
uart5 {
bcm2711;
};
pi3-disable-bt {
renamed = "disable-bt";
};
lirc-rpi {
deprecated = "use gpio-ir";
};
};
Each node has the name of an overlay that requires special handling. The properties of
each node are either platform names or one of a small number of special directives.
The overlay map supports the following platform names:
bcm2835 for all Raspberry Pis built around the BCM2835, BCM2836, BCM2837, and
RP3A0 SoCs
A platform name with no value (an empty property) indicates that the current overlay is
compatible with the platform; for example, uart5 is compatible with the bcm2711
platform. A non-empty value for a platform is the name of an alternative overlay to use
in place of the requested one; asking for disable-bt on BCM2712 results in disable-
bt-pi5 being loaded instead. Any platform not included in an overlay’s node is not
compatible with that overlay. Any overlay not mentioned in the map is assumed to be
compatible with all platforms.
The second example node - disable-bt-pi5 - could be inferred from the content of
disable-bt, but that intelligence goes into the construction of the file, not its
interpretation.
In the event that a platform is not listed for an overlay, one of the special directives may
apply:
The renamed directive indicates the new name of the overlay (which should be
largely compatible with the original), but also logs a warning about the rename.
The deprecated directive contains a brief explanatory error message which will be
logged after the common prefix overlay '...' is deprecated:.
Remember: only exceptions need to be listed - the absence of a node for an overlay
means that the default file should be used for all platforms.
The dtoverlay and dtmerge utilities have been extended to support the map file:
dtmerge extracts the platform name from the compatible string in the base DTB.
dtoverlay reads the compatible string from the live Device Tree at /proc/device-
tree, but you can use the -p option to supply an alternate platform name (useful for
dry runs on a different platform).
They both send errors, warnings and any debug output to STDERR.
Examples
Here are some examples of different types of properties, with parameters to modify
them:
/ {
fragment@0 {
target-path = "/";
__overlay__ {
test: test_node {
string = "hello";
status = "disabled";
bytes = /bits/ 8 <0x67 0x89>;
u16s = /bits/ 16 <0xabcd 0xef01>;
u32s = /bits/ 32 <0xfedcba98 0x76543210>;
u64s = /bits/ 64 < 0xaaaaa5a55a5a5555 0x0000111122223
333>;
bool1; // Defaults to true
// bool2 defaults to false
mac = [01 23 45 67 89 ab];
spi = <&spi0>;
};
};
};
fragment@1 {
target-path = "/";
__overlay__ {
frag1;
};
};
fragment@2 {
target-path = "/";
__dormant__ {
frag2;
};
};
__overrides__ {
string = <&test>,"string";
enable = <&test>,"status";
byte_0 = <&test>,"bytes.0";
byte_1 = <&test>,"bytes.1";
u16_0 = <&test>,"u16s;0";
u16_1 = <&test>,"u16s;2";
u32_0 = <&test>,"u32s:0";
u32_1 = <&test>,"u32s:4";
u64_0 = <&test>,"u64s#0";
u64_1 = <&test>,"u64s#8";
bool1 = <&test>,"bool1!";
bool2 = <&test>,"bool2?";
entofr = <&test>,"english",
<&test>,"french{hello=bonjour,goodbye='au revoi
r',weekend}";
pi_mac = <&test>,"mac[{1=b8273bfedcba,2=b8273b987654}";
spibus = <&test>,"spi:0[0=",<&spi0>,"1=",<&spi1>,"2=",<&
spi2>;
only1 = <0>,"+1-2";
only2 = <0>,"-1+2";
enable1 = <0>,"=1";
disable2 = <0>,"!2";
};
};
For further examples, a large collection of overlay source files is hosted in the
Raspberry Pi Linux GitHub repository.
Export labels
The overlay handling in the firmware, and the run-time overlay application using the
dtoverlay utility, treat labels defined in an overlay as being private to that overlay. This
avoids the need to invent globally unique names for labels (which keeps them short),
and it allows the same overlay to be used multiple times without clashing (provided
some tricks are used - see Special properties).
Sometimes it is very useful to be able to create a label with one overlay and use it from
another. Firmware released since 14th February 2020 has the ability to declare some
labels as being global - the __exports__ node:
...
public: ...
__exports__ {
public; // Export the label 'public' to the base DT
};
};
When this overlay is applied, the loader strips out all symbols except those that have
been exported, in this case public, and rewrites the path to make it relative to the
target of the fragment containing the label. Overlays loaded after this one can then refer
to &public.
Under most circumstances it shouldn’t matter in which order the fragments are applied,
but for overlays that patch themselves (where the target of a fragment is a label in the
overlay, known as an intra-overlay fragment) it becomes important. In older firmware,
fragments are applied strictly in order, top to bottom. With firmware released since 14th
February 2020, fragments are applied in two passes:
First the fragments that target other fragments are applied and hidden.
On a Raspberry Pi it is the job of the loader (one of the start.elf images) to combine
overlays with an appropriate base device tree, and then to pass a fully resolved Device
Tree to the kernel. The base Device Trees are located alongside start.elf in the FAT
partition (/boot/firmware/ from Linux), named bcm2711-rpi-4-b.dtb, bcm2710-
rpi-3-b-plus.dtb, etc. Note that some models (3A+, A, A+) will use the "b" equivalents
(3B+, B, B+), respectively. This selection is automatic, and allows the same SD card
image to be used in a variety of devices.
NOTE
DT and ATAGs are mutually exclusive, and passing a DT blob to a kernel that doesn’t
understand it will cause a boot failure. The firmware will always try to load the DT
and pass it to the kernel, since all kernels since rpi-4.4.y will not function without a
DTB. You can override this by adding device_tree= in config.txt, which forces the
use of ATAGs, which can be useful for simple bare-metal kernels.
The loader now supports builds using bcm2835_defconfig, which selects the
upstreamed BCM2835 support. This configuration will cause bcm2835-rpi-b.dtb and
bcm2835-rpi-b-plus.dtb to be built. If these files are copied with the kernel, then the
loader will attempt to load one of those DTBs by default.
In order to manage Device Tree and overlays, the loader supports a number of
config.txt directives:
dtoverlay=acme-board
dtparam=foo=bar,level=42
This will cause the loader to look for overlays/acme-board.dtbo in the firmware
partition, which Raspberry Pi OS mounts on /boot/firmware/. It will then search for
parameters foo and level, and assign the indicated values to them.
The loader will also search for an attached HAT with a programmed EEPROM, and load
the supporting overlay from there - either directly or by name from the "overlays"
directory; this happens without any user intervention.
There are multiple ways to tell that the kernel is using Device Tree:
The "Machine model:" kernel message during bootup has a board-specific value such
as "Raspberry Pi 2 Model B", rather than "BCM2709".
/proc/device-tree exists, and contains subdirectories and files that exactly mirror
the nodes and properties of the DT.
With a Device Tree, the kernel will automatically search for and load modules that
support the indicated enabled devices. As a result, by creating an appropriate DT
overlay for a device you save users of the device from having to edit /etc/modules; all
of the configuration goes in config.txt, and in the case of a HAT, even that step is
unnecessary. Note, however, that layered modules such as i2c-dev still need to be
loaded explicitly.
The flipside is that because platform devices don’t get created unless requested by the
DTB, it should no longer be necessary to blacklist modules that used to be loaded as a
result of platform devices defined in the board support code. In fact, current Raspberry
Pi OS images ship with no blacklist files (except for some WLAN devices where multiple
drivers are available).
DT parameters
dtparam=audio=on,i2c_arm=on,i2c_arm_baudrate=400000,spi=on
NOTE
Multiple assignments can be placed on the same line, but ensure you don’t exceed
the 80-character limit.
If you have an overlay that defines some parameters, they can be specified either on
subsequent lines like this:
dtoverlay=lirc-rpi
dtparam=gpio_out_pin=16
dtparam=gpio_in_pin=17
dtparam=gpio_in_pull=down
dtoverlay=lirc-rpi,gpio_out_pin=16,gpio_in_pin=17,gpio_in_pull=down
Overlay parameters are only in scope until the next overlay is loaded. In the event of a
parameter with the same name being exported by both the overlay and the base, the
parameter in the overlay takes precedence; it’s recommended that you avoid doing this.
To expose the parameter exported by the base DTB instead, end the current overlay
scope using:
dtoverlay=
Raspberry Pi boards have two I2C interfaces. These are nominally split: one for the
ARM, and one for VideoCore (the GPU). On almost all models, i2c1 belongs to the ARM
and i2c0 to VC, where it is used to control the camera and read the HAT EEPROM.
However, there are two early revisions of the Model B that have those roles reversed.
To make it possible to use one set of overlays and parameters with all Raspberry Pis,
the firmware creates some board-specific DT parameters. These are:
i2c/i2c_arm
i2c_vc
i2c_baudrate/i2c_arm_baudrate
i2c_vc_baudrate
For people writing overlays, the same aliasing has been applied to the labels on the I2C
DT nodes. Thus, you should write:
fragment@0 {
target = <&i2c_arm>;
__overlay__ {
status = "okay";
};
};
Any overlays using the numeric variants will be modified to use the new aliases.
The HAT overlay is automatically loaded by the firmware after the base DTB, so its
parameters are accessible until any other overlays are loaded, or until the overlay scope
is ended using dtoverlay=. If for some reason you want to suppress the loading of the
HAT overlay, put dtoverlay= before any other dtoverlay or dtparam directive.
As of Linux 4.4, Raspberry Pi kernels support the dynamic loading of overlays and
parameters. Compatible kernels manage a stack of overlays that are applied on top of
the base DTB. Changes are immediately reflected in /proc/device-tree and can
cause modules to be loaded and platform devices to be created and destroyed.
The use of the word "stack" above is important - overlays can only be added and
removed at the top of the stack; changing something further down the stack requires
that anything on top of it must first be removed.
dtoverlay is a command line utility that loads and removes overlays while the system
is running, as well as listing the available overlays and displaying their help information.
Usage:
dtoverlay <overlay> [<param>=<val>...]
Add an overlay (with parameters)
dtoverlay -D [<idx>] Dry-run (prepare overlay, but don't apply
-
save it as dry-run.dtbo)
dtoverlay -r [<overlay>] Remove an overlay (by name, index or the l
ast)
dtoverlay -R [<overlay>] Remove from an overlay (by name, index or
all)
dtoverlay -l List active overlays/params
dtoverlay -a List all overlays (marking the active)
dtoverlay -h Show this usage message
dtoverlay -h <overlay> Display help on an overlay
dtoverlay -h <overlay> <param>.. Or its parameters
where <overlay> is the name of an overlay or 'dtparam' for dtpara
ms
Options applicable to most variants:
-d <dir> Specify an alternate location for the overlays
(defaults to /boot/firmware/overlays or /flash/overla
ys)
-v Verbose operation
Unlike the config.txt equivalent, all parameters to an overlay must be included in the
same command line - the dtparam command is only for parameters of the base DTB.
Command variants that change kernel state (adding and removing things) require root
privilege, so you may need to prefix the command with sudo. Only overlays and
parameters applied at run-time can be unloaded - an overlay or parameter applied by
the firmware becomes "baked in" such that it won’t be listed by dtoverlay and can’t be
removed.
dtparam creates and loads an overlay that has largely the same effect as using a
dtparam directive in config.txt. In usage it is largely equivalent to dtoverlay with an
overlay name of -, but there are a few differences: dtparam will list the help information
for all known parameters of the base DTB. Help on the dtparam command is still
available using dtparam -h. When indicating a parameter for removal, only index
numbers can be used (not names). Not all Linux subsystems respond to the addition of
devices at runtime - I2C, SPI and sound devices work, but some won’t.
Don’t create a node within a fragment that will overwrite an existing node in the base
DTB - the kernel will rename the new node to make it unique. If you want to change the
properties of an existing node, create a fragment that targets it.
ALSA doesn’t prevent its codecs and other components from being unloaded while they
are in use. Removing an overlay can cause a kernel exception if it deletes a codec that
is still being used by a sound card. Experimentation found that devices are deleted in
the reverse of fragment order in the overlay, so placing the node for the card after the
nodes for the components allows an orderly shutdown.
Caveats
The loading of overlays at runtime is a recent addition to the kernel, and at the time of
writing there is no accepted way to do this from userspace. By hiding the details of this
mechanism behind commands, users are insulated from changes in the event that a
different kernel interface becomes standardised.
Some overlays work better at run-time than others. Parts of the Device Tree are only
used at boot time - changing them using an overlay will not have any effect.
Unloading the overlay for an ALSA card can stall if something is actively using ALSA -
the LXPanel volume slider plugin demonstrates this effect. To enable overlays for
sound cards to be removed, the lxpanelctl utility has been given two new options -
alsastop and alsastart - and these are called from the auxiliary scripts
dtoverlay-pre and dtoverlay-post before and after overlays are loaded or
unloaded, respectively.
Removing an overlay will not cause a loaded module to be unloaded, but it may
cause the reference count of some modules to drop to zero. Running rmmod -a
twice will cause unused modules to be unloaded.
Overlays have to be removed in reverse order. The commands will allow you to
remove an earlier one, but all the intermediate ones will be removed and re-applied,
which may have unintended consequences.
Only Device Tree nodes at the top level of the tree and children of a bus node will be
probed. For nodes added at run-time there is the further limitation that the bus must
register for notifications of the addition and removal of children. However, there are
exceptions that break this rule and cause confusion: the kernel explicitly scans the
entire tree for some device types - clocks and interrupt controller being the two main
ones - in order to (for clocks) initialise them early and/or (for interrupt controllers) in
a particular order. This search mechanism only happens during booting and so
doesn’t work for nodes added by an overlay at run-time. It is therefore recommended
for overlays to place fixed-clock nodes in the root of the tree unless it is guaranteed
that the overlay will not be used at run-time.
For a list of supported overlays and parameters, see the README file found alongside
the overlay .dtbo files in /boot/firmware/overlays. It is kept up-to-date with
additions and changes.
Firmware parameters
The firmware uses the special /chosen node to pass parameters between the
bootloader and/or firmware and the operating system. Each property is stored as a 32-
bit integer unless indicated otherwise.
overlay_prefix
(string) The overlay_prefix string selected by config.txt.
os_prefix
(string) The os_prefix string selected by config.txt.
rpi-boardrev-ext
The extended board revision code from OTP row 33.
rpi-country-code
The country code used used by PiWiz. Keyboard models only.
rpi-duid
(string) Raspberry Pi 5 only. A string representation of the QR code on the PCB.
boot-mode
The boot-mode used to load the kernel. See the BOOT_ORDER documentation for
a list of possible boot-mode values.
partition
The partition number used during boot. If a boot.img ramdisk is loaded then this
refers to partition that the ramdisk was loaded from rather than the partition
number within the ramdisk.
pm_rsts
The value of the PM_RSTS register during boot.
tryboot
Set to 1 if the tryboot flag was set at boot.
max_current
The maximum current in mA that the power supply can supply. The firmware
reports the value indicated by the USB-C, USB-PD or PoE interfaces. For bench
power supplies (e.g. connected to the GPIO header) define PSU_MAX_CURRENT in
the bootloader configuration to indicate the power supply current capability.
power_reset
Raspberry Pi 5 only. A bit field indicating the reason why the PMIC was reset.
Bit Reason
0 Over voltage
1 Under voltage
2 Over temperature
3 Enable signal
4 Watchdog
rpi_power_supply
(two 32-bit integers) The USB VID and Product VDO of the official Raspberry Pi
27W power supply (if connected).
usb_max_current_enable
Zero if the USB port current limiter was set to the low-limit during boot; or non-
zero if the high limit was enabled. The high level is automatically enabled if the
power supply claims 5A max-current OR usb_max_current_enable=1 is forced
in config.txt
usb_over_current_detected
Non-zero if a USB over-current event occurred during USB boot.
usbpd_power_data_objects
(binary blob containing multiple 32-bit integers) The raw binary USB-PD objects
(fixed supply only) received by the bootloader during USB-PD negotiation. To
capture this for a bug report, run hexdump -C /proc/device-
tree/chosen/power/usbpd_power_data_objects.
The following properties are specific to the BCM2711 and BCM2712 SPI EEPROM
bootloaders. Each property is stored as a 32-bit integer unless indicated otherwise.
build_timestamp
The UTC build time for the EEPROM bootloader.
capabilities
This bit-field describes the features supported by the current bootloader. This
may be used to check whether a feature (e.g. USB boot) is supported before
enabling it in the bootloader EEPROM config.
Bit Feature
1 Network boot
2 TRYBOOT_A_B mode
3 TRYBOOT
6 NVMe boot
7 Secure Boot
update_timestamp
The UTC update timestamp set by rpi-eeprom-update.
signed
If Secure Boot is enabled, this bit-field will be non-zero. The individual bits indicate
the current Secure Boot configuration.
Bit Description
1 Reserved
4…31 Reserved
version
(string) The Git version string for the bootloader.
The following properties are defined if the system was booted from USB. These may be
used to uniquely identify the USB boot device. Each property is stored as a 32-bit
integer.
usb-version
The USB major protocol version (2 or 3).
route-string
The USB route-string identifier for the device as defined by the USB 3.0
specification.
root-hub-port-number
The root hub port number that the boot device is connected to - possibly via other
USB hubs.
lun
The Logical Unit Number for the mass-storage device.
NVMEM nodes
Example shell script code for reading an NVMEM mode from rpi-eeprom-update:
blconfig_alias="/sys/firmware/devicetree/base/aliases/blconfig"
blconfig_nvmem_path=""
if [ -f "${blconfig_alias}" ]; then
blconfig_ofnode_path="/sys/firmware/devicetree/base"$(strings "${b
lconfig_alias}")""
blconfig_ofnode_link=$(find -L /sys/bus/nvmem -samefile "${blconfi
g_ofnode_path}" 2>/dev/null)
if [ -e "${blconfig_ofnode_link}" ]; then
blconfig_nvmem_path=$(dirname "${blconfig_ofnode_link}")
fi
fi
fi
blconfig
alias that refers to an NVMEM device that stores a copy of the bootloader
EEPROM config file.
blpubkey
alias that points to an NVMEM device that stores a copy of the bootloader
EEPROM public key (if defined) in binary format. The rpi-bootloader-key-convert
utility can be used to convert the data into PEM format for use with OpenSSL.
Troubleshooting
Debugging
The loader will skip over missing overlays and bad parameters, but if there are serious
errors, such as a missing or corrupt base DTB or a failed overlay merge, then the loader
will fall back to a non-DT boot. If this happens, or if your settings don’t behave as you
expect, it is worth checking for warnings or errors from the loader:
You can create a human-readable representation of the current state of DT like this:
$ dtc -I fs /proc/device-tree
This can be useful to see the effect of merging overlays onto the underlying tree.
If kernel modules don’t load as expected, check that they aren’t blacklisted in
/etc/modprobe.d/raspi-blacklist.conf; blacklisting shouldn’t be necessary when
using Device Tree. If that shows nothing untoward, you can also check that the module
is exporting the correct aliases by searching
/lib/modules/<version>/modules.alias for the compatible value. Otherwise, your
driver is probably missing either:
.of_match_table = xxx_of_match,
or:
MODULE_DEVICE_TABLE(of, xxx_of_match);
Failing that, depmod has failed or the updated modules haven’t been installed on the
target filesystem.
Alongside the dtoverlay and dtparam commands is a utility for applying an overlay to
a DTB - dtmerge. To use it you first need to obtain your base DTB, which can be
obtained in one of two ways:
This will include any overlays and parameters you have applied so far, either in
config.txt or by loading them at runtime, which may or may not be what you want.
Alternatively:
Copy it from the source DTBs in /boot/firmware/. This won’t include overlays and
parameters, but it also won’t include any other modifications by the firmware. To allow
testing of all overlays, the dtmerge utility will create some of the board-specific aliases
("i2c_arm", etc.), but this means that the result of a merge will include more differences
from the original DTB than you might expect. The solution to this is to use dtmerge to
make the copy:
sdhost@7e202000 {
- brcm,overclock-50 = <0x0>;
+ brcm,overclock-50 = <0x3e>;
brcm,pio-limit = <0x1>;
bus-width = <0x4>;
clocks = <0x8>;
to get:
spi1_cs_pins {
brcm,function = <0x1>;
- brcm,pins = <0x12>;
+ brcm,pins = <0x12 0x11>;
phandle = <0x3e>;
};
@@ -725,7 +725,7 @@
#size-cells = <0x0>;
clocks = <0x13 0x1>;
compatible = "brcm,bcm2835-aux-spi";
- cs-gpios = <0xc 0x12 0x1>;
+ cs-gpios = <0xc 0x12 0x1 0xc 0x11 0x1>;
interrupts = <0x1 0x1d>;
linux,phandle = <0x30>;
phandle = <0x30>;
@@ -743,6 +743,16 @@
spi-max-frequency = <0x7a120>;
status = "okay";
};
+
+ spidev@1 {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ compatible = "spidev";
+ phandle = <0x41>;
+ reg = <0x1>;
+ spi-max-frequency = <0x7a120>;
+ status = "okay";
+ };
};
spi@7e2150C0 {
The Utils repo includes another DT utility - ovmerge. Unlike dtmerge, ovmerge combines
file and applies overlays in source form. Because the overlay is never compiled, labels
are preserved and the result is usually more readable. It also has a number of other
tricks, such as the ability to list the order of file inclusion.
If you have very specific needs that aren’t supported by the default DTBs, or if you just
want to experiment with writing your own DTs, you can tell the loader to load an
alternate DTB file like this:
device_tree=my-pi.dtb
Device Tree usage is required in Raspberry Pi Linux kernels. For bare metal and other
OSs, DT usage can be disabled by adding:
device_tree=
to config.txt.
dtparam=i2c_arm=on
dtparam=i2s=on
dtparam=i2c,i2s
(i2c is an alias of i2c_arm, and the =on is assumed). It also still accepts the long-form
versions: device_tree_overlay and device_tree_param.
device_tree_address
This is used to override the address where the firmware loads the device tree (not
dt-blob). By default the firmware will choose a suitable place.
device_tree_end
This sets an (exclusive) limit to the loaded device tree. By default the device tree
can grow to the end of usable memory, which is almost certainly what is required.
dtdebug
If non-zero, turn on some extra logging for the firmware’s device tree processing.
enable_uart
Enable the primary/console UART. If the primary UART is ttyAMA0, enable_uart
defaults to 1 (enabled), otherwise it defaults to 0 (disabled). This stops the core
frequency from changing, which would make ttyS0 unusable. As a result,
enable_uart=1 implies core_freq=250 (unless force_turbo=1). In some cases
this is a performance hit, so it is off by default.
overlay_prefix
Specifies a subdirectory/prefix from which to load overlays - defaults to
"overlays/". Note the trailing "/". If desired you can add something after the final "/"
to add a prefix to each file, although this is not likely to be needed.
Further ports can be controlled by the DT. For more details see section 3.
Further help
If you’ve read through this document and have not found the answer to a Device Tree
problem, there is help available. The author can usually be found on Raspberry Pi
forums, particularly the Device Tree forum.
NOTE
Custom default pin configurations via user-provided Device Tree blobs has been
deprecated.
Power-on - pins default to inputs with default pulls, which are described in the
datasheet
Setting by bootcode.bin
Kernel/Device Tree
On a soft reset, the same procedure applies, except for default pulls, which are only
applied on a power-on reset.
It may take a few seconds to run through the process. During this time, the GPIO pins
may not be in the state expected by attached peripherals (as defined in dt-blob.bin or
config.txt). Since different GPIO pins have different default pulls, you should do one
of the following for your peripheral:
Choose a GPIO pin that defaults to pulls as required by the peripheral on reset
videocore
This section contains all of the VideoCore blob information. All subsequent sections
must be enclosed within this section.
pins_*
pins_rev1: Rev1 pin setup. There are some differences because of the moved I2C
pins.
pins_rev2: Rev2 pin setup. This includes the additional codec pins on P5.
pins_bplus1: Raspberry Pi 1 Model B+ rev 1.1, including the full 40pin connector.
pins_bplus2: Raspberry Pi 1 Model B+ rev 1.2, swapping the low-power and lan-run
pins.
pins_2b1: Raspberry Pi 2 Model B rev 1.0; controls the SMPS via I2C0.
pins_2b2: Raspberry Pi 2 Model B rev 1.1; controls the SMPS via software I2C on 42
and 43.
pins_cm: Raspberry Pi Compute Module 1. The default for this is the default for the
chip, so it is a useful source of information about default pull-ups/pull-downs on the
chip.
pin_config
The pin_config section is used to configure the individual pins. Each item in this
section must be a named pin section, such as pin@p32, meaning GPIO32. There is a
special section pin@default, which contains the default settings for anything not
specifically named in the pin_config section.
pin@pinname
polarity
active_high
active_low
termination
pull_up
pull_down
no_pulling
startup_state
active
inactive
function
input
output
sdcard
i2c0
i2c1
spi
spi1
spi2
smi
dpi
pcm
pwm
uart0
uart1
gp_clk
emmc
arm_jtag
drive_strength_mA
The drive strength is used to set a strength for the pins. Please note that you can
only specify a single drive strength for the bank. <8> and <16> are valid values.
pin_defines
This section is used to set specific VideoCore functionality to particular pins. This
enables the user to move the camera power enable pin to somewhere different, or
move the HDMI hotplug position: these are things that Linux does not control. Please
refer to the example DTS file below.
Clock configuration
It is possible to change the configuration of the clocks through this interface, although it
can be difficult to predict the results! The configuration of the clocking system is very
complex. There are five separate PLLs, and each one has its own fixed (or variable, in
the case of PLLC) VCO frequency. Each VCO then has a number of different channels
which can be set up with a different division of the VCO frequency. Each of the clock
destinations can be configured to come from one of the clock channels, although there
is a restricted mapping of source to destination, so not all channels can be routed to all
clock destinations.
Here are a couple of example configurations that you can use to alter specific clocks.
We will add to this resource when requests for clock configurations are made.
clock_routing {
vco@PLLA { freq = <1966080000>; };
chan@APER { div = <4>; };
clock@GPCLK0 { pll = "PLLA"; chan = "APER"; };
};
clock_setup {
clock@PWM { freq = <2400000>; };
clock@GPCLK0 { freq = <12288000>; };
clock@GPCLK1 { freq = <25000000>; };
};
The above will set the PLLA to a source VCO running at 1.96608GHz (the limits for this
VCO are 600MHz - 2.4GHz), change the APER channel to /4, and configure GPCLK0 to
be sourced from PLLA through APER. This is used to give an audio codec the
12288000Hz it needs to produce the 48000 range of frequencies.
You can view and edit the Raspberry Pi documentation source on Github. Please read our usage and contributions policy before you make a Pull
Request.
Raspberry Pi documentation is copyright © 2012-2025 Raspberry Pi Ltd and is licensed under a Creative Commons Attribution-ShareAlike 4.0
International (CC BY-SA) licence.
Some content originates from the eLinux wiki, and is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported licence.
The terms HDMI, HDMI High-Definition Multimedia Interface, HDMI trade dress and the HDMI Logos are trademarks or registered trademarks of
HDMI Licensing Administrator, Inc