added support for old raspberry pi
This commit is contained in:
parent
9e1a592de4
commit
6679b00bcd
11
Dockerfile
11
Dockerfile
@ -1,8 +1,10 @@
|
|||||||
FROM debian:buster AS uboot
|
FROM debian:buster AS build_base
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y build-essential git wget bison flex gcc-arm-linux-gnueabi device-tree-compiler bc
|
apt-get install -y build-essential git wget bison flex gcc-arm-linux-gnueabi device-tree-compiler bc
|
||||||
|
|
||||||
|
FROM build_base AS uboot
|
||||||
|
|
||||||
RUN mkdir /uboot_build/ && \
|
RUN mkdir /uboot_build/ && \
|
||||||
mkdir /uboot/
|
mkdir /uboot/
|
||||||
|
|
||||||
@ -43,6 +45,12 @@ RUN make CROSS_COMPILE=arm-linux-gnueabi- distclean && \
|
|||||||
make CROSS_COMPILE=arm-linux-gnueabi- -j8 u-boot.bin && \
|
make CROSS_COMPILE=arm-linux-gnueabi- -j8 u-boot.bin && \
|
||||||
cp u-boot.bin /uboot/u-boot_rpi4.bin
|
cp u-boot.bin /uboot/u-boot_rpi4.bin
|
||||||
|
|
||||||
|
FROM build_base AS uboot_tool
|
||||||
|
|
||||||
|
ADD ./resources/uboot.c /uboot.c
|
||||||
|
|
||||||
|
RUN arm-linux-gnueabi-gcc -Wall -static -static-libgcc -o /uboot_tool /uboot.c
|
||||||
|
|
||||||
|
|
||||||
FROM alpine:3.10
|
FROM alpine:3.10
|
||||||
|
|
||||||
@ -70,5 +78,6 @@ RUN cd /genext2fs && \
|
|||||||
|
|
||||||
ADD ./resources /resources
|
ADD ./resources /resources
|
||||||
COPY --from=uboot /uboot/ /uboot/
|
COPY --from=uboot /uboot/ /uboot/
|
||||||
|
COPY --from=uboot_tool /uboot_tool /uboot_tool
|
||||||
|
|
||||||
WORKDIR /work
|
WORKDIR /work
|
||||||
|
@ -1,46 +1,106 @@
|
|||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
# static config
|
# static config
|
||||||
setenv boot_partition_a 2
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
setenv boot_partition_b 3
|
setenv boot_partition_a 0x02
|
||||||
setenv boot_limit 2
|
setenv boot_partition_b 0x03
|
||||||
|
setenv boot_limit 0x02
|
||||||
setenv boot_partition_base "/dev/mmcblk0p"
|
setenv boot_partition_base "/dev/mmcblk0p"
|
||||||
|
|
||||||
|
setenv addr_version 0x10000
|
||||||
|
setenv addr_boot_counter 0x10001
|
||||||
|
setenv addr_boot_partition 0x10002
|
||||||
|
|
||||||
# set default values if env not set
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
if printenv boot_count; then
|
# load persistence values
|
||||||
else
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
setenv boot_count 1
|
# clear memory
|
||||||
|
mw.b 0x10000 0 0x404
|
||||||
|
|
||||||
|
# load uboot file
|
||||||
|
fatload mmc 0:1 0x10000 uboot.dat 0x400
|
||||||
|
|
||||||
|
# check CRC
|
||||||
|
crc32 0x10000 0x3FC 0x10400
|
||||||
|
if itest *0x103FC -ne *0x10400; then
|
||||||
|
echo "invalid CRC -> fallback to default values"
|
||||||
|
|
||||||
|
# default values
|
||||||
|
mw.b ${addr_version} 0x01
|
||||||
|
mw.b ${addr_boot_counter} 0x00
|
||||||
|
mw.b ${addr_boot_partition} ${boot_partition_a}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if printenv boot_partition; then
|
# ensure boot partition is valid
|
||||||
# check if valid partition a or b
|
if itest.b *${addr_boot_partition} -ne ${boot_partition_a} && test.b *${addr_boot_partition} -ne ${boot_partition_b}; then
|
||||||
if test ${boot_partition} -ne ${boot_partition_a} && test ${boot_partition} -ne ${boot_partition_b}; then
|
mw.b ${addr_boot_partition} ${boot_partition_a}
|
||||||
setenv boot_partition ${boot_partition_a}
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
setenv boot_partition ${boot_partition_a}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# fallback boot
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
echo "Check fallback boot"
|
||||||
# switch boot partition if boot count exceed limit
|
# switch boot partition if boot count exceed limit
|
||||||
if test ${boot_count} -ge ${boot_limit}; then
|
if itest.b *${addr_boot_counter} -ge ${boot_limit}; then
|
||||||
echo "!!! Boot limit exceed !!!"
|
echo "!!! Boot limit exceed !!!"
|
||||||
|
|
||||||
if test ${boot_partition} -eq ${boot_partition_a}; then
|
if itest *${addr_boot_partition} -eq ${boot_partition_a}; then
|
||||||
setenv boot_partition ${boot_partition_b}
|
mv.b ${addr_boot_partition} ${boot_partition_b}
|
||||||
else
|
else
|
||||||
setenv boot_partition ${boot_partition_a}
|
mv.b ${addr_boot_partition} ${boot_partition_a}
|
||||||
fi
|
fi
|
||||||
setenv boot_count 0
|
mw.b ${addr_boot_counter} 0
|
||||||
|
|
||||||
|
setexpr.b boot_partition *${addr_boot_partition}
|
||||||
echo "Switch active partition to ${boot_partition_base}${boot_partition}"
|
echo "Switch active partition to ${boot_partition_base}${boot_partition}"
|
||||||
|
else
|
||||||
|
# increase boot_count
|
||||||
|
setexpr.b tmp *${addr_boot_counter} + 1
|
||||||
|
mw.b ${addr_boot_counter} ${tmp}
|
||||||
|
|
||||||
|
setexpr.b boot_partition *${addr_boot_partition}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# increase boot_count
|
|
||||||
setexpr boot_count ${boot_count} + 1
|
|
||||||
|
|
||||||
# store settings
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
saveenv
|
# store persistence values
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
|
||||||
|
# overwrite version
|
||||||
|
mw.b 0x10000 0x01
|
||||||
|
|
||||||
|
# calculate crc
|
||||||
|
crc32 0x10000 0x3FC 0x103FC
|
||||||
|
|
||||||
|
# save to uboot file
|
||||||
|
fatwrite mmc 0:1 0x10000 uboot.dat 0x400
|
||||||
|
|
||||||
|
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# select kernel
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
echo "select kernel"
|
||||||
|
setenv boot_kernel "/boot/uImage"
|
||||||
|
|
||||||
|
# only if new pi a new kernel is required
|
||||||
|
setexpr board_new_pi ${board_revision} \& 0x800000
|
||||||
|
if test ${board_new_pi} > 0; then
|
||||||
|
echo "new board"
|
||||||
|
# get cpu id from revision
|
||||||
|
setexpr board_cpu ${board_revision} \& 0xF000
|
||||||
|
|
||||||
|
# at the moment CPU except the oldest need the new kernel
|
||||||
|
if test ${board_cpu} > 0x0000; then
|
||||||
|
setenv boot_kernel "/boot/uImage2"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "old board"
|
||||||
|
fi
|
||||||
|
echo "Load kernel ${boot_kernel}"
|
||||||
|
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# boot
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
# load bootargs from pi boot loader
|
# load bootargs from pi boot loader
|
||||||
fdt addr ${fdt_addr} && fdt get value bootargs /chosen bootargs
|
fdt addr ${fdt_addr} && fdt get value bootargs /chosen bootargs
|
||||||
|
|
||||||
@ -48,7 +108,7 @@ fdt addr ${fdt_addr} && fdt get value bootargs /chosen bootargs
|
|||||||
setexpr bootargs sub " root=[^ ]+" " root=${boot_partition_base}${boot_partition}" "${bootargs}"
|
setexpr bootargs sub " root=[^ ]+" " root=${boot_partition_base}${boot_partition}" "${bootargs}"
|
||||||
|
|
||||||
# load kernel and boot
|
# load kernel and boot
|
||||||
ext4load mmc 0:${boot_partition} ${kernel_addr_r} /boot/uImage
|
ext4load mmc 0:${boot_partition} ${kernel_addr_r} ${boot_kernel}
|
||||||
bootm ${kernel_addr_r} - ${fdt_addr}
|
bootm ${kernel_addr_r} - ${fdt_addr}
|
||||||
|
|
||||||
reset
|
reset
|
||||||
|
@ -12,8 +12,8 @@ set -e
|
|||||||
: ${DEFAULT_ROOT_PASSWORD:="alpine"}
|
: ${DEFAULT_ROOT_PASSWORD:="alpine"}
|
||||||
|
|
||||||
: ${SIZE_BOOT:="100M"}
|
: ${SIZE_BOOT:="100M"}
|
||||||
: ${SIZE_ROOT_FS:="150M"}
|
: ${SIZE_ROOT_FS:="200M"}
|
||||||
: ${SIZE_ROOT_PART:="250M"}
|
: ${SIZE_ROOT_PART:="500M"}
|
||||||
: ${SIZE_DATA:="20M"}
|
: ${SIZE_DATA:="20M"}
|
||||||
: ${IMG_NAME:="alpine-${ALPINE_BRANCH}-sdcard"}
|
: ${IMG_NAME:="alpine-${ALPINE_BRANCH}-sdcard"}
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ set -e
|
|||||||
# static config
|
# static config
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
RES_PATH=/resources/
|
RES_PATH=/resources/
|
||||||
BASE_PACKAGES="alpine-base tzdata parted ifupdown e2fsprogs-extra util-linux coreutils linux-rpi2 uboot-tools openntpd"
|
BASE_PACKAGES="alpine-base tzdata parted ifupdown e2fsprogs-extra util-linux coreutils linux-rpi linux-rpi2"
|
||||||
|
|
||||||
WORK_PATH="/work"
|
WORK_PATH="/work"
|
||||||
OUTPUT_PATH="/output"
|
OUTPUT_PATH="/output"
|
||||||
@ -139,20 +139,12 @@ mkdir -p ${ROOTFS_PATH}/dev/shm
|
|||||||
mkdir -p ${ROOTFS_PATH}/var/lock
|
mkdir -p ${ROOTFS_PATH}/var/lock
|
||||||
|
|
||||||
# time
|
# time
|
||||||
chroot_exec rc-update add openntpd default
|
chroot_exec rc-update add ntpd default
|
||||||
cat >${ROOTFS_PATH}/etc/conf.d/openntpd <<EOF
|
|
||||||
NTPD_OPTS="-s"
|
|
||||||
EOF
|
|
||||||
cat >${ROOTFS_PATH}/etc/ntpd.conf <<EOF
|
|
||||||
servers pool.ntp.org
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
|
||||||
# uboot tools config
|
# uboot tools
|
||||||
cat >${ROOTFS_PATH}/etc/fw_env.config <<EOF
|
cp /uboot_tool ${ROOTFS_PATH}/sbin/uboot_tool
|
||||||
/uboot/uboot.env 0x0000 0x4000
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# TODO REMOVE THIS
|
# TODO REMOVE THIS
|
||||||
# mark system as booted (should be moved to application)
|
# mark system as booted (should be moved to application)
|
||||||
@ -160,7 +152,7 @@ cat >${ROOTFS_PATH}/etc/local.d/99-uboot.start <<EOF
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
mount -o remount,rw /uboot
|
mount -o remount,rw /uboot
|
||||||
|
|
||||||
fw_setenv boot_count 1
|
/sbin/uboot_tool reset_counter
|
||||||
|
|
||||||
sync
|
sync
|
||||||
mount -o remount,ro /uboot
|
mount -o remount,ro /uboot
|
||||||
@ -182,6 +174,9 @@ ln -s /data/etc/dropbear/dropbear.conf ${ROOTFS_PATH}/etc/conf.d/dropbear
|
|||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
rm -rf ${ROOTFS_PATH}/var/cache/apk/*
|
rm -rf ${ROOTFS_PATH}/var/cache/apk/*
|
||||||
|
rm -rf ${ROOTFS_PATH}/boot/initramfs*
|
||||||
|
rm -rf ${ROOTFS_PATH}/boot/System*
|
||||||
|
rm -rf ${ROOTFS_PATH}/boot/config*
|
||||||
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
echo ">> Move persistent data to /data"
|
echo ">> Move persistent data to /data"
|
||||||
@ -248,7 +243,8 @@ ln -fs /data/etc/shadow ${ROOTFS_PATH}/etc/shadow
|
|||||||
echo ">> Prepare kernel for uboot"
|
echo ">> Prepare kernel for uboot"
|
||||||
|
|
||||||
# build uImage
|
# build uImage
|
||||||
mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000 -n "Linux kernel" -d ${ROOTFS_PATH}/boot/vmlinuz-rpi2 ${ROOTFS_PATH}/boot/uImage
|
mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000 -n "Linux kernel" -d ${ROOTFS_PATH}/boot/vmlinuz-rpi ${ROOTFS_PATH}/boot/uImage
|
||||||
|
mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000 -n "Linux kernel" -d ${ROOTFS_PATH}/boot/vmlinuz-rpi2 ${ROOTFS_PATH}/boot/uImage2
|
||||||
|
|
||||||
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
@ -19,10 +19,8 @@ current_idx=$(rdev | sed 's#/dev/mmcblk0p\([^ ]*\).*#\1#')
|
|||||||
|
|
||||||
if [ $current_idx -eq 2 ]; then
|
if [ $current_idx -eq 2 ]; then
|
||||||
echo "Start update for partition B"
|
echo "Start update for partition B"
|
||||||
flash_idx=3
|
|
||||||
else
|
else
|
||||||
echo "Start update for partition A"
|
echo "Start update for partition A"
|
||||||
flash_idx=2
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
flash_device="/dev/mmcblk0p${flash_idx}"
|
flash_device="/dev/mmcblk0p${flash_idx}"
|
||||||
@ -33,7 +31,7 @@ gunzip -c ${image_file} | dd of=${flash_device} status=progress
|
|||||||
|
|
||||||
# switch active partition
|
# switch active partition
|
||||||
mount -o remount,rw /uboot
|
mount -o remount,rw /uboot
|
||||||
fw_setenv boot_partition ${flash_idx}
|
/sbin/uboot_tool part_switch
|
||||||
sync
|
sync
|
||||||
mount -o remount,ro /uboot
|
mount -o remount,ro /uboot
|
||||||
|
|
||||||
|
125
resources/uboot.c
Normal file
125
resources/uboot.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char* uboot_file = "/uboot/uboot.dat";
|
||||||
|
|
||||||
|
|
||||||
|
void printHelp() {
|
||||||
|
printf("Usage: uboot_tool [COMMAND]\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Commands:\n");
|
||||||
|
printf(" part_current - show current partition\n");
|
||||||
|
printf(" part_switch - switch active partition\n");
|
||||||
|
printf(" reset_counter - reset boot counter\n");
|
||||||
|
printf(" version - show version of file\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t crc32(uint8_t* data, size_t length, uint32_t seed) {
|
||||||
|
uint32_t crc = ~seed;
|
||||||
|
while (length--) {
|
||||||
|
crc ^= (*data++);
|
||||||
|
for (unsigned int j = 0; j < 8; j++) {
|
||||||
|
if (crc & 1) {
|
||||||
|
crc = (crc >> 1) ^ 0xedb88320L;
|
||||||
|
} else {
|
||||||
|
crc = crc >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
// show help if no command given
|
||||||
|
if (argc < 2) {
|
||||||
|
printHelp();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char* cmd = argv[1];
|
||||||
|
|
||||||
|
// read uboot file
|
||||||
|
FILE* file = fopen(uboot_file, "rb");
|
||||||
|
if (file == NULL) {
|
||||||
|
printf("Failed to open uboot file: %s\n", uboot_file);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
uint8_t data[1024];
|
||||||
|
size_t err = fread(data, 1, sizeof(data), file);
|
||||||
|
if (err == 0) {
|
||||||
|
printf("Failed to read uboot file: %s\n", uboot_file);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// get crc from file
|
||||||
|
uint32_t crc = (data[1023] << 24) +
|
||||||
|
(data[1022] << 16) +
|
||||||
|
(data[1021] << 8) +
|
||||||
|
data[1020];
|
||||||
|
|
||||||
|
// check if CRC is valid
|
||||||
|
if (crc != crc32(data, 0x3FC, 0)) {
|
||||||
|
fprintf(stderr, "Invalid CRC -> fallback to default\n");
|
||||||
|
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
|
||||||
|
// file version
|
||||||
|
data[0] = 1;
|
||||||
|
|
||||||
|
// boot counter
|
||||||
|
data[1] = 0;
|
||||||
|
|
||||||
|
// boot partition
|
||||||
|
data[2] = 2; // A=2, B=3
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle commands
|
||||||
|
uint8_t save = 0;
|
||||||
|
if (strcmp(cmd, "version") == 0) {
|
||||||
|
printf("0x%02x\n", data[0]);
|
||||||
|
|
||||||
|
} else if (strcmp(cmd, "part_current") == 0) {
|
||||||
|
printf("%d\n", data[2]);
|
||||||
|
|
||||||
|
} else if (strcmp(cmd, "part_switch") == 0) {
|
||||||
|
if (data[2] == 2) {
|
||||||
|
data[2] = 3;
|
||||||
|
} else {
|
||||||
|
data[2] = 2;
|
||||||
|
}
|
||||||
|
save = 1;
|
||||||
|
|
||||||
|
} else if (strcmp(cmd, "reset_counter") == 0) {
|
||||||
|
data[1] = 0;
|
||||||
|
save = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Unknown command\n");
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save == 1) {
|
||||||
|
// calculate new CRC
|
||||||
|
crc = crc32(data, 0x3FC, 0);
|
||||||
|
data[1023] = (uint8_t)((crc & 0xFF000000U)>>24);
|
||||||
|
data[1022] = (uint8_t)((crc & 0x00FF0000U)>>16);
|
||||||
|
data[1021] = (uint8_t)((crc & 0x0000FF00U)>>8);
|
||||||
|
data[1020] = (uint8_t)((crc & 0x000000FFU));
|
||||||
|
|
||||||
|
// write uboot file
|
||||||
|
file = fopen(uboot_file, "wb");
|
||||||
|
if (file == NULL) {
|
||||||
|
printf("Failed to open uboot file: %s\n", uboot_file);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
size_t err = fwrite(data, 1, sizeof(data), file);
|
||||||
|
if (err == 0) {
|
||||||
|
printf("Failed to write uboot file: %s\n", uboot_file);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user