├── apps ├── alsa │ └── aml-s905x-cc.state └── xorg │ ├── 10-disable-glx.conf │ ├── 10-meson.conf │ ├── 10-rockchip.conf │ └── 10-sunxi.conf ├── oneshot.sh └── readme.md /apps/alsa/aml-s905x-cc.state: -------------------------------------------------------------------------------- 1 | state.LIBRETECHCC { 2 | control.1 { 3 | iface MIXER 4 | name 'AIU ACODEC I2S Lane Select' 5 | value 0 6 | comment { 7 | access 'read write' 8 | type INTEGER 9 | count 1 10 | range '0 - 3' 11 | } 12 | } 13 | control.2 { 14 | iface MIXER 15 | name 'ACODEC Playback Channel Mode' 16 | value Stereo 17 | comment { 18 | access 'read write' 19 | type ENUMERATED 20 | count 1 21 | item.0 Stereo 22 | item.1 Mono 23 | } 24 | } 25 | control.3 { 26 | iface MIXER 27 | name 'ACODEC Playback Switch' 28 | value true 29 | comment { 30 | access 'read write' 31 | type BOOLEAN 32 | count 1 33 | } 34 | } 35 | control.4 { 36 | iface MIXER 37 | name 'ACODEC Playback Volume' 38 | value.0 204 39 | value.1 204 40 | comment { 41 | access 'read write' 42 | type INTEGER 43 | count 2 44 | range '0 - 255' 45 | dbmin -9999999 46 | dbmax 0 47 | dbvalue.0 -1905 48 | dbvalue.1 -1905 49 | } 50 | } 51 | control.5 { 52 | iface MIXER 53 | name 'ACODEC Ramp Rate' 54 | value Fast 55 | comment { 56 | access 'read write' 57 | type ENUMERATED 58 | count 1 59 | item.0 Fast 60 | item.1 Slow 61 | } 62 | } 63 | control.6 { 64 | iface MIXER 65 | name 'ACODEC Volume Ramp Switch' 66 | value 0 67 | comment { 68 | access 'read write' 69 | type INTEGER 70 | count 1 71 | range '0 - 1' 72 | } 73 | } 74 | control.7 { 75 | iface MIXER 76 | name 'ACODEC Mute Ramp Switch' 77 | value false 78 | comment { 79 | access 'read write' 80 | type BOOLEAN 81 | count 1 82 | } 83 | } 84 | control.8 { 85 | iface MIXER 86 | name 'ACODEC Unmute Ramp Switch' 87 | value false 88 | comment { 89 | access 'read write' 90 | type BOOLEAN 91 | count 1 92 | } 93 | } 94 | control.9 { 95 | iface PCM 96 | device 2 97 | name 'Playback Channel Map' 98 | value.0 0 99 | value.1 0 100 | value.2 0 101 | value.3 0 102 | value.4 0 103 | value.5 0 104 | value.6 0 105 | value.7 0 106 | comment { 107 | access read 108 | type INTEGER 109 | count 8 110 | range '0 - 36' 111 | } 112 | } 113 | control.10 { 114 | iface PCM 115 | device 2 116 | name ELD 117 | value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' 118 | comment { 119 | access 'read volatile' 120 | type BYTES 121 | count 128 122 | } 123 | } 124 | control.11 { 125 | iface MIXER 126 | name 'AIU SPDIF SRC SEL' 127 | value SPDIF 128 | comment { 129 | access 'read write' 130 | type ENUMERATED 131 | count 1 132 | item.0 SPDIF 133 | item.1 I2S 134 | } 135 | } 136 | control.12 { 137 | iface MIXER 138 | name 'AIU HDMI CTRL SRC' 139 | value I2S 140 | comment { 141 | access 'read write' 142 | type ENUMERATED 143 | count 1 144 | item.0 DISABLED 145 | item.1 PCM 146 | item.2 I2S 147 | } 148 | } 149 | control.13 { 150 | iface MIXER 151 | name 'AIU ACODEC SRC' 152 | value I2S 153 | comment { 154 | access 'read write' 155 | type ENUMERATED 156 | count 1 157 | item.0 DISABLED 158 | item.1 I2S 159 | item.2 PCM 160 | } 161 | } 162 | control.14 { 163 | iface MIXER 164 | name 'AIU ACODEC OUT EN Switch' 165 | value true 166 | comment { 167 | access 'read write' 168 | type BOOLEAN 169 | count 1 170 | } 171 | } 172 | control.15 { 173 | iface MIXER 174 | name 'ACODEC Right DAC Sel' 175 | value Right 176 | comment { 177 | access 'read write' 178 | type ENUMERATED 179 | count 1 180 | item.0 Right 181 | item.1 Left 182 | } 183 | } 184 | control.16 { 185 | iface MIXER 186 | name 'ACODEC Left DAC Sel' 187 | value Left 188 | comment { 189 | access 'read write' 190 | type ENUMERATED 191 | count 1 192 | item.0 Left 193 | item.1 Right 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /apps/xorg/10-disable-glx.conf: -------------------------------------------------------------------------------- 1 | Section "Extensions" 2 | Option "GLX" "disable" 3 | EndSection -------------------------------------------------------------------------------- /apps/xorg/10-meson.conf: -------------------------------------------------------------------------------- 1 | Section "OutputClass" 2 | Identifier "Amlogic" 3 | MatchDriver "meson" 4 | Driver "modesetting" 5 | Option "PrimaryGPU" "true" 6 | EndSection 7 | -------------------------------------------------------------------------------- /apps/xorg/10-rockchip.conf: -------------------------------------------------------------------------------- 1 | Section "OutputClass" 2 | Identifier "Rockchip" 3 | MatchDriver "rockchip" 4 | Driver "modesetting" 5 | Option "PrimaryGPU" "true" 6 | EndSection -------------------------------------------------------------------------------- /apps/xorg/10-sunxi.conf: -------------------------------------------------------------------------------- 1 | Section "OutputClass" 2 | Identifier "Allwinner" 3 | MatchDriver "sun4i-drm" 4 | Driver "modesetting" 5 | Option "PrimaryGPU" "true" 6 | EndSection -------------------------------------------------------------------------------- /oneshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: CC BY-NC-ND 4.0 3 | # Copyright (C) 2021 Da Xue 4 | 5 | set -e 6 | 7 | if [ "$USER" != "root" ]; then 8 | echo "Please run this as root." >&2 9 | echo "sudo $0 $@" >&2 10 | exit 1 11 | fi 12 | 13 | if [ -z "$1" ]; then 14 | echo "No board selected. Supported boards:" >&2 15 | echo "all-h3-cc-h3" >&2 16 | echo "all-h3-cc-h5" >&2 17 | echo "aml-s805x-ac" >&2 18 | echo "aml-s905x-cc" >&2 19 | echo "roc-rk3328-cc" >&2 20 | echo "roc-rk3399-pc" >&2 21 | echo "sudo $0 BOARD" >&2 22 | exit 1 23 | fi 24 | 25 | case "$1" in 26 | all-h3-cc-h3) 27 | BOARD_name=all-h3-cc-h3 28 | BOARD_bootSector=16 29 | BOARD_console=S0,115200 30 | BOARD_bootLoader=1 31 | BOARD_arch=armhf 32 | ;; 33 | all-h3-cc-h5) 34 | BOARD_name=all-h3-cc-h5 35 | BOARD_bootSector=16 36 | BOARD_console=S0,115200 37 | BOARD_bootLoader=1 38 | BOARD_arch=arm64 39 | ;; 40 | aml-s805x-ac) 41 | BOARD_name=aml-s805x-ac 42 | BOARD_bootSector=1 43 | BOARD_console=AML0 44 | BOARD_bootLoader=0 45 | BOARD_arch=arm64 46 | ;; 47 | aml-s905x-cc) 48 | BOARD_name=aml-s905x-cc 49 | BOARD_bootSector=1 50 | BOARD_console=AML0 51 | BOARD_bootLoader=1 52 | BOARD_arch=arm64 53 | ;; 54 | roc-rk3328-cc) 55 | BOARD_name=roc-rk3328-cc 56 | BOARD_bootSector=64 57 | BOARD_console=S2,1500000 58 | BOARD_bootLoader=1 59 | BOARD_arch=arm64 60 | ;; 61 | roc-rk3399-pc) 62 | BOARD_name=roc-rk3399-pc 63 | BOARD_bootSector=64 64 | BOARD_console=S2,1500000 65 | BOARD_bootLoader=1 66 | BOARD_arch=arm64 67 | ;; 68 | *) 69 | echo "Unsupported board $1" >&2 70 | exit 1 71 | ;; 72 | esac 73 | 74 | case $BOARD_arch in 75 | armhf) 76 | BOARD_arch_cpu=arm 77 | BOARD_cpu=arm 78 | ;; 79 | arm64) 80 | BOARD_arch_cpu=arm64 81 | BOARD_cpu=aarch64 82 | ;; 83 | *) 84 | echo "Unsupported arch $1" >&2 85 | exit 1 86 | ;; 87 | esac 88 | 89 | cat < "$sfdisk_file" 122 | sfdisk_label=$(grep -Po "label:\\s+\\K.*" "$sfdisk_file") 123 | 124 | if [ -z "$sfdisk_label" ]; then 125 | echo "disk: error disk no label" >&2 126 | exit 1 127 | elif [ "$sfdisk_label" = "dos" ]; then 128 | : 129 | elif [ "$sfdisk_label" = "gpt" ]; then 130 | echo "disk: gpt is not supported" >&2 131 | exit 1 132 | else 133 | echo "disk: unknown partition table" >&2 134 | exit 1 135 | fi 136 | 137 | sfdisk_dev=$(grep -Po "device:\\s+\\K.*" "$sfdisk_file") 138 | sfdisk_dev_p1_file=$(mktemp) 139 | grep -Po "^${sfdisk_dev}p1\\s+:\\s+\\K.*" "$sfdisk_file" | sed "s/,/\\n/g" | sed "s/\\s//g" > "$sfdisk_dev_p1_file" 140 | sfdisk_dev_p1_start=$(awk -F= "/^start/ {print \$2}" "$sfdisk_dev_p1_file") 141 | 142 | if [ -z "$sfdisk_dev_p1_start" ]; then 143 | echo "disk: p1 start not found" >&2 144 | exit 1 145 | elif [ "$sfdisk_dev_p1_start" -lt 2048 ]; then 146 | echo "disk: p1 starts too early" >&2 147 | exit 1 148 | fi 149 | 150 | OS_RELEASE_FILE=/etc/os-release 151 | if [ ! -f "$OS_RELEASE_FILE" ]; then 152 | echo "os-release: missing file" >&2 153 | exit 1 154 | fi 155 | 156 | readarray -t lines < "$OS_RELEASE_FILE" 157 | declare -A TARGET_OS_RELEASE 158 | for line in "${lines[@]}"; do 159 | key="${line%%=*}" 160 | value="${line#*=}" 161 | TARGET_OS_RELEASE["$key"]="$value" 162 | done 163 | 164 | machine_arch=$(uname -m) 165 | case $machine_arch in 166 | aarch64) 167 | if [ "${TARGET_OS_RELEASE[ID]}" != "debian" ]; then 168 | echo "os-release: for 64-bit systems, only Raspbian is supported." >&2 169 | exit 1 170 | elif [ "${TARGET_OS_RELEASE[VERSION_ID]}" != '"11"' ]; then 171 | echo "os-release: for 64-bit systems, only Raspbian 11 is supported." >&2 172 | exit 1 173 | fi 174 | ;; 175 | armv7l) 176 | if [ "${TARGET_OS_RELEASE[ID]}" != "raspbian" ]; then 177 | echo "os-release: for 32-bit systems, only Raspbian is supported." >&2 178 | exit 1 179 | fi 180 | case "${TARGET_OS_RELEASE[VERSION_ID]}" in 181 | '"10"') 182 | if [ "$BOARD_arch" != "arm64" ]; then 183 | skip_grub_shim_hold=1 184 | fi 185 | ;; 186 | '"11"') 187 | : 188 | ;; 189 | *) 190 | echo "os-release-version: for 32-bit systems, only Raspbian 10 and 11 are supported." >&2 191 | exit 1 192 | ;; 193 | esac 194 | ;; 195 | *) 196 | echo "os-release: unsupported architecture $machine_arch." >&2 197 | exit 1 198 | ;; 199 | esac 200 | 201 | dpkg_arch_target=$BOARD_arch 202 | grub_install_cmd="grub-install --directory=/usr/lib/grub/${BOARD_arch_cpu}-efi --efi-directory=/boot --force-extra-removable --no-nvram" 203 | 204 | dpkg_arch=$(dpkg --print-architecture) 205 | case "$dpkg_arch" in 206 | "") 207 | echo "dpkg: failed to get architecture" >&2 208 | exit 1 209 | ;; 210 | armhf) 211 | : 212 | ;; 213 | arm64) 214 | if [ "$BOARD_arch" = "armhf" ]; then 215 | echo "$BOARD_name can only run 32-bit images." >&2 216 | exit 1 217 | fi 218 | ;; 219 | *) 220 | echo "dpkg: architecture is not supported" >&2 221 | exit 1 222 | ;; 223 | esac 224 | 225 | dpkg_arches_foreign=$(dpkg --print-foreign-architectures) 226 | for dpkg_arch_foreign in $dpkg_arches_foreign; do 227 | if [ "$dpkg_arch_foreign" = "$dpkg_arch_target" ]; then 228 | break 229 | fi 230 | done 231 | if [ "$dpkg_arch_foreign" != "$dpkg_arch_target" ]; then 232 | dpkg --add-architecture ${BOARD_arch} 233 | fi 234 | 235 | apt_sources=$(ls /etc/apt/sources.list /etc/apt/sources.list.d/*.list) 236 | apt_source_add=1 237 | for apt_source in $apt_sources; do 238 | sed -Ei "s/^(deb)\\s+(http:\\/\\/)/\\1 [ arch=$dpkg_arch ] \2/" "$apt_source" 239 | if grep "deb.debian.org/debian" "$apt_source" > /dev/null; then 240 | apt_source_add=0 241 | fi 242 | done 243 | 244 | if [ $apt_source_add -eq 1 ]; then 245 | echo "deb [ arch=${BOARD_arch} ] http://deb.debian.org/debian/ ${TARGET_OS_RELEASE[VERSION_CODENAME]} main" > /etc/apt/sources.list.d/debian-main.list 246 | echo "deb [ arch=${BOARD_arch} ] http://deb.debian.org/debian/ ${TARGET_OS_RELEASE[VERSION_CODENAME]}-updates main" >> /etc/apt/sources.list.d/debian-main.list 247 | wget -qO - 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x605c66f00d6c9793' | sudo apt-key add - # Debian Stable Release Key (11/bullseye) 248 | wget -qO - 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x0e98404d386fa1d9' | sudo apt-key add - # Debian Archive Automatic Signing Key (11/bullseye) 249 | wget -qO - 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x648acfd622f3d138' | sudo apt-key add - # Debian Archive Automatic Signing Key (12/bookworm) 250 | wget -qO - 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x0e98404d386fa1d9' | sudo apt-key add - # Debian Archive Automatic Signing Key (11/bullseye) 251 | wget -qO - 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x6ed0e7b82643e131' | sudo apt-key add - # Debian Archive Automatic Signing Key (12/bookworm) 252 | 253 | if [ "${TARGET_OS_RELEASE[VERSION_CODENAME]}" = "buster" ]; then 254 | echo "deb [ arch=${BOARD_arch} ] http://security.debian.org/debian-security ${TARGET_OS_RELEASE[VERSION_CODENAME]}/updates main" >> /etc/apt/sources.list.d/debian-main.list 255 | else 256 | echo "deb [ arch=${BOARD_arch} ] http://security.debian.org/debian-security ${TARGET_OS_RELEASE[VERSION_CODENAME]}-security main" >> /etc/apt/sources.list.d/debian-main.list 257 | fi 258 | wget -qO - 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x112695a0e562b32a' | sudo apt-key add - # Debian Security Archive Automatic Signing Key (10/buster) 259 | fi 260 | 261 | if which rpi-eeprom-update > /dev/null; then 262 | systemctl disable rpi-eeprom-update || true 263 | fi 264 | 265 | wget -O "/usr/share/keyrings/libre-computer-deb.gpg" 'https://deb.libre.computer/repo/libre-computer-deb.gpg' 266 | echo "deb [arch=${BOARD_arch} signed-by=/usr/share/keyrings/libre-computer-deb.gpg] https://deb.libre.computer/repo linux main non-free" > "$root_mount_dir/etc/apt/sources.list.d/libre-computer-deb.list" 267 | 268 | apt update 269 | if [ -z "$skip_grub_shim_hold" ]; then 270 | apt-mark hold shim-signed 271 | fi 272 | 273 | #apt -y dist-upgrade 274 | apt -y install grub-efi-$BOARD_arch_cpu linux-image-lc-lts-$BOARD_arch_cpu linux-headers-lc-lts-$BOARD_arch_cpu 275 | $grub_install_cmd 276 | sed -Ei "s/(GRUB_CMDLINE_LINUX_DEFAULT)=\"quiet/\1=\"noquiet/" /etc/default/grub 277 | update-grub 278 | 279 | if [ "${TARGET_OS_RELEASE[ID]}" != "debian" ]; then 280 | grub_cfg="grub.cfg" 281 | if [ -e "/boot/EFI/${TARGET_OS_RELEASE[ID]}/$grub_cfg" ]; then 282 | debian_grub_cfg_path=/boot/EFI/debian 283 | mkdir -p "$debian_grub_cfg_path" 284 | cp "/boot/EFI/${TARGET_OS_RELEASE[ID]}/$grub_cfg" "$debian_grub_cfg_path/$grub_cfg" 285 | fi 286 | fi 287 | 288 | if [ "$BOARD_bootLoader" -eq 1 ]; then 289 | BOOT_LOADER_URL="http://boot.libre.computer/ci/$BOARD_name" 290 | boot_loader_file=$(mktemp) 291 | wget -O "$boot_loader_file" "$BOOT_LOADER_URL" 292 | dd if="$boot_loader_file" of=/dev/"$target_disk" bs=512 seek=$BOARD_bootSector 293 | fi 294 | 295 | if [ ! -d /usr/share/X11/xorg.conf.d ]; then 296 | mkdir -p /usr/share/X11/xorg.conf.d 297 | fi 298 | cp $SRC_DIR/apps/xorg/10-*.conf /usr/share/X11/xorg.conf.d 299 | 300 | if [ -f $SRC_DIR/apps/alsa/${BOARD_name}.state ]; then 301 | cp $SRC_DIR/apps/alsa/${BOARD_name}.state /var/lib/alsa/asound.state 302 | fi 303 | 304 | read -n 1 -p "Modifications complete. Press any key to shutdown. Once the green LED stops blinking and turns off for 10 seconds, remove power and move the MicroSD card to the Libre Computer Board." 305 | shutdown -H now 306 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Libre Computer Raspbian Portability 2 | ## Objective 3 | This script is designed to run on existing Raspbian images and enables them 4 | to boot on any Libre Computer board. It uses an upstream FOSS software stack 5 | developed by the community and Libre Computer to support booting Raspbian. 6 | 7 | It is a proof-of-concept and there are no warranties implied or otherwise. 8 | We highly recommend backing up the image if it holds important data in case 9 | something unexpected occurs. While the image should still boot on the original 10 | device, this is not fully tested or guaranteed so continue at your own risk. 11 | 12 | This script installs/configures/overwrites data on the device's MicroSD card. 13 | It is designed to run on Raspberry Pi®s and requires internet access to 14 | download additional necessary components. Once the script finishes, the card 15 | should still remain bootable on the original board. 16 | 17 | ## Prerequisites 18 | - Raspberry Pi 2 Model B or higher 19 | - Reliable MicroSD Card (Samsung/SanDisk recommended) 20 | - MicroUSB Power Supply 21 | - Internet Connection 22 | - [Any Libre Computer board (Amazon Link)](https://amzn.to/3c2xvAS) 23 | 24 | ## Supported Distributions 25 | - [Raspbian 10 Buster Lite and Desktop armhf](https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy) 26 | - [Raspbian 11 Bullseye Lite and Desktop armhf](https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-32-bit) 27 | - [Raspbian 11 Bullseye Lite and Desktop arm64](https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-64-bit) 28 | - NOOBS (New Out Of Box Software) installations are not supported. 29 | - If you want to use Ubuntu, you can use these [Ubuntu 22.04 images](https://hub.libre.computer/t/ubuntu-22-04-1-jammy-lts-for-libre-computer-boards/20). 30 | - If you want to use Raspbian, you can use these [Raspbian 11 images](https://hub.libre.computer/t/raspbian-11-bullseye-for-libre-computer-boards/82). 31 | 32 | ## Supported Features 33 | - GPIOs and Device Tree Overlays (dtoverlay) for I2C, SPI, UART, PWM need to be mapped via [libretech-wiring-tool](https://github.com/libre-computer-project/libretech-wiring-tool.git). 34 | - Software designed around specific Raspberry Pi® hardware such as MIPI cameras, DPI displays, DSI pannels are not supported. 35 | 36 | ## How to Use 37 | [YouTube Video RunThrough](https://www.youtube.com/watch?v=IK9hq4qYVeE) 38 | On your Raspberry Pi:registered:, run: 39 | ```bash 40 | sudo apt install -y git 41 | git clone https://github.com/libre-computer-project/libretech-raspbian-portability.git lrp 42 | sudo lrp/oneshot.sh aml-s905x-cc 43 | ``` 44 | Replace aml-s905x-cc with the appropriate board you want the image to run on and follow the instructions. 45 | For a list of boards, run sudo lrp/oneshot.sh 46 | 47 | ## Help and Support 48 | - [Libre Computer Hub](https://hub.libre.computer/t/feedback-for-raspbian-portability/32) 49 | - [Libera Chat IRC #librecomputer](https://web.libera.chat/#librecomputer) 50 | 51 | ## Roadmap 52 | - Refactor to robust coding standards 53 | - Device tree overlay translation via our [wiring tool](https://github.com/libre-computer-project/libretech-wiring-tool.git) 54 | - Firmware for specific boards 55 | 56 | We provide commercial support for porting specific distros or images, [please reach out to us](https://libre.computer/#contact). 57 | --------------------------------------------------------------------------------