Building an Android Automotive OS is not a difficult task in itself, but the lack of good tutorials makes it extremely difficult. It only gets harder if you don’t have any specialized equipment on hand like the R-Car or Dragonboard. However, you can easily get hold of a Raspberry Pi, a small ARM-powered, all-in-one computer and a perfect candidate for running AAOS. To make the process easier for anyone struggling with such issues, in this article I will explain step-by-step how to build and run the latest version, Android Automotive OS 13.
Let’s get started!
You need Linux to build the system. You can use WSL or MacOS (remember, you need a case-sensitive filesystem), but pure Linux is the best option.
As in the previous article, you need a Raspberry Pi 4B microcomputer, a power adapter (or you can connect it from your computer via a USB cable), a memory card and a screen. It’s nice to have a touchscreen, but you can use your mouse and optionally a keyboard if that’s more convenient.
Another nice feature is the USB-TTL bridge for debugging. Find my previous article for more details on how to use it.
If you are looking for an easy way, visit https://github.com/grapeup/aaos_local_manifest and follow the readme. There are just a few commands to download, create and write an IMG file for your Raspberry. But in any case, you need a few hours to download and build it. Warning: It may not start if you don’t adjust the display settings (see below for details).
Configuring AOSP to make it AAOS
This project is based on Raspberry Vanilla’s KonstaT, a great AOSP port for the Raspberry Pi. It covers everything you need to run pure Android on your Raspberry: a tweaked kernel, hardware drivers, and more. However, there is no vehicle hardware, so you have to build it.
Github.com/grapeup has four repositories about AAOS: three forks based on Raspberry Vanilla and one new one.
The repository aaos_local_manifest contains a list of changed and new repositories. All significant changes are in place
device/brcm/rpi4 and device/brcm/rpi4-car the projects defined in
manifest_brcm_rpi4.xml file. In the readme of this repository you will find steps to clone and build the project.
The next repository, aaos_device_brcm_rpi4, contains three elements:
First and foremost is to use a new one
rpi4-car design and remove conflicting elements from the main design.
aosp_rpi4.mk file, there is a new line
$(call inherit-product, device/brcm/rpi4-car/rpi4_car.mk)
include a new project.
device.mk file, the product specification has changed “
automotive,nosdcard“and all custom overlays are removed along with the encryption directory next to the file.
manifest.xml file that “
android.hardware.automotive.vehicle“ Added HAL (Hardware Abstraction Layer).
The second item is the configuration for the display I’m using. I had to set the screen resolution
vendor.prop and set the screen density
BoardConfig.mk. You probably don’t need these changes if you’re using a standard computer monitor, or if you need a different monitor for your specific display. Be aware that the system will not boot at all if the resolution configured here is not supported on your display.
The last item contains my regional/language settings
aosp_rpi4.mk. I have decided to use this file as it is not related to the car and leave it in the code to show how it can be adapted if needed.
The main part
The most basic changes are in the aaos_device_brcm_rpi4_car repository.
rpi4_car.mk file is based
device/generic/car/common/car.mk with few changes.
Conventional, custom settings for system-wide images are removed along with the emulator configuration (
device/generic/car/common/config.ini) and the emulator audio package (
Instead, you need a mix of vendor-specific and board-specific components that aren’t included total/car makefile for the emulator.
Android Automotive OS is tightly coupled with the audio engine, so you need to add an automotive audio management pack.
(email@example.com) to make it work even if you don’t want to connect any speakers to your board. In addition, AAOS uses a dedicated display controller with the ability to use two displays at the same time (
firstname.lastname@example.org), so you should include it too. The next part is the SELinux policy for real boards (not emulator).
BOARD_SEPOLICY_DIRS += device/generic/car/common/sepolicy
Next, you need to add permissions to several pre-installed, automotive-oriented packages to allow them to run in system or user areas.
PRODUCT_COPY_FILES += device/google/cuttlefish/shared/auto/preinstalled-packages-product-car-cuttlefish.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/sysconfig/preinstalled-packages-product-car-cuttlefish.xml
The next component is EVS, the Appearance System, which was introduced at AAOS 13. Even if you don’t really want to connect multiple cameras to the system, you should include the default implementation of the component and configure it to work as a mock. .
DEVICE_PACKAGE_OVERLAYS += device/google/cuttlefish/shared/auto/overlay
ENABLE_EVS_SERVICE ?= true
ENABLE_MOCK_EVSHAL ?= true
ENABLE_CAREVSSERVICE_SAMPLE ?= true
ENABLE_SAMPLE_EVS_APP ?= true
ENABLE_CARTELEMETRY_SERVICE ?= true
CUSTOMIZE_EVS_SERVICE_PARAMETER := true
PRODUCT_PACKAGES += email@example.com
PRODUCT_COPY_FILES += device/google/cuttlefish/shared/auto/evs/init.evs.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.evs.rc
BOARD_SEPOLICY_DIRS += device/google/cuttlefish/shared/auto/sepolicy/evs
The last part is to set the variables for the system when running. You set two system properties directly in the makefile (to allow forced orientation and to enable the AVRCP Bluetooth profile).
PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
Finally, you override the following system variables using predefined and custom overlays.
PRODUCT_PACKAGE_OVERLAYS += \
PRODUCT_PACKAGE_OVERLAYS allows us to override any value from a properties file in the source code. For example, in our case, the root directory of the cover
device/brcm/rpi4-car/overlayso the file
device/brcm/rpi4-car/overlay/frameworks/base/core/res/res/values/config.xml overwrites the properties from the file
Let’s dive into the changed features.
- Frameworks/base/core/res/res/values/config.xml file::
- config_useVolumeKeySounds disables the use of hardware volume keys, because they are not in our settings,
- config_voice_capable: only enables data mode as there is no way to make a voice call from our board,
- config_sms_capable: disables SMS capabilities for the same reason
- network features and radioAttributes configures the system to use only WiFi, Bluetooth, and ethernet connections since the device does not have a GSM modem.
- config_longPressOnPowerBehavior disables the long press of the power button because the power button is not enabled,
- config_disableUsbPermissionDialogs disables the USB permission screen as it should not be used in AAOS,
- config_defaultUiModeType: enables the car launcher by default,
- config_defaultNightMode: enables night mode as default.
- Frameworks/base/packages/SettingsProvider/res/values/defaults.xml file:
- def_wifi_on turns on WiFi default,
- def_accelerometer_rotation: sets the default orientation,
- def_auto_time: allows you to get time from the Internet when connected,
- def_screen_brightness: sets the default screen brightness,
- def_bluetooth_on: turns on bluetooth by default
- def_location_mode: allows apps to use location services by default,
- def_lockscreen_disabled turns off the lock screen,
- def_stay_on_while_plugged_in: sets the device to stay always on.
packages/apps/Car/LatinIME/res/layout/input_keyboard.xmlfile sets the default foreground color for the default keyboard because the default is not very readable. To define
textColorparameters to configure it.
packages/apps/Car/LatinIME/res/values/colors.xmlsets the colors or symbol characters to the default keyboard, and the letter/symbol switch in the lower right corner.
packages/apps/Car/SystemUI/res/values/colors.xml: sets status bar background color quick settings to make the default font color readable.
packages/apps/Car/SystemUI/res/values/config.xmlhides the brightness settings from the top bar because it doesn’t work without specific display drivers.
- packages/applications/Settings/res/values/config.xml file::
- config_show_call_volume: disables volume control during calls,
- config_show_charging_sounds: turns off charging sounds,
- config_show_top_level_battery: turns off the battery level icon.
- packages/modules/Wifi/service/ServiceWifiResources/res/values/config.xml enables 5GHz WiFi support.
packages/services/Car/service/res/values/config.xmldisables the launch of a specific application when the system is booted or the driver is changed.
You can read more about each of these settings in the comments of the original files from which the settings were derived.
The last repository is aaos_android_hardware_interfaces. You don’t need it, but there is one useful feature here that is hard-coded. Android has a concept called HAL – Hardware Abstraction Layer. There is VHAL – Vehicle Hardware Abstraction Layer for AAOS. It is responsible for air conditioning and heating, ventilation and air conditioning, among others. In our setup, there is no car hardware and no physical air conditioning, so you use
android.hardware.automotive.vehicle@V1-emulator-service whose default implementation is under
hardware/interfaces/automotive/vehicle. To change the default units used by HVAC from Imperial to Rest of World, you must configure
The process of building AAOS 13 for Raspberry Pi is much easier than AAOS 11. The kernel is already pre-compiled and there is much less to do.
Just call those three commands.
make bootimage systemimage vendorimage
On a Windows laptop (using WSL of course) with an i7-12850HX processor and 32GB of RAM, the build takes about 1 hour 40 minutes to complete.
Creating a bootable SD card
There are two options: without or with
mkimg.sh scenario. The script is below
device/brcm/rpi4 directory and linked in the main project directory as
rpi4-mkimg.sh. The script creates a virtual image and puts 4 partitions inside.
boot, system, vendor, and:
userdata. It’s useful because you can use the Raspberry Pi Imager to write it to the SD card, but it has a few limitations. The image is always 7GB (you can change it by setting
IMGSIZE variable script), so you won’t use up the rest of your card, no matter how big it is. Also, you should always write 7 GB to your card, even if you only need to update one section, including zeros on the blank. user data partition
An alternative option is to write by hand on the card. This is difficult on Windows because WSL does not include card reader drivers, but is fine on other operating systems. All necessary files are embedded
out/target/product/rpi4 directory. Let’s make and write the card. Warning: On my system the SD card is visible as
/dev/sdb. Please configure the commands below to not destroy your data.
OK, let’s clear the card. Before erasing the entire device, you must wipe each partition to remove filesystem signatures.
sudo umount /dev/sdb*
sudo wipefs -a /dev/sdb*
sudo wipefs -a /dev/sdb
Now let’s make the card. This line will use
fdisk create 4 partitions and set flags and filesystems.
echo -e "n\n\n\n\n+128M\na\nt\n0c\nn\n\n\n\n+2G\nn\n\n\n\n+256M\nn\np\n\n\nw\n" | sudo fdisk /dev/sdb
The last step is to write the data and prepare the last section.
sudo dd if=boot.img of=/dev/sdb1 bs=1M
sudo dd if=system.img of=/dev/sdb2 bs=1M
sudo dd if=vendor.img of=/dev/sdb3 bs=1M
sudo mkfs.ext4 -L userdata /dev/sdb4
sudo umount /dev/sdb*
Android Automotive OS is a giant leap for the automotive industry. Since there is no production machine with AAOS 13 yet, you can experience the future with this tutorial. What’s more, you can do it with a low-budget Raspberry Pi computer. This way, I hope you can develop your apps and easily play with the system without the extra layer of using emulators. Good luck and happy coding!