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 && \
|
||||
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/ && \
|
||||
mkdir /uboot/
|
||||
|
||||
@ -43,6 +45,12 @@ RUN make CROSS_COMPILE=arm-linux-gnueabi- distclean && \
|
||||
make CROSS_COMPILE=arm-linux-gnueabi- -j8 u-boot.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
|
||||
|
||||
@ -70,5 +78,6 @@ RUN cd /genext2fs && \
|
||||
|
||||
ADD ./resources /resources
|
||||
COPY --from=uboot /uboot/ /uboot/
|
||||
COPY --from=uboot_tool /uboot_tool /uboot_tool
|
||||
|
||||
WORKDIR /work
|
||||
|
@ -1,46 +1,106 @@
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# static config
|
||||
setenv boot_partition_a 2
|
||||
setenv boot_partition_b 3
|
||||
setenv boot_limit 2
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
setenv boot_partition_a 0x02
|
||||
setenv boot_partition_b 0x03
|
||||
setenv boot_limit 0x02
|
||||
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
|
||||
else
|
||||
setenv boot_count 1
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# load persistence values
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# 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
|
||||
|
||||
if printenv boot_partition; then
|
||||
# check if valid partition a or b
|
||||
if test ${boot_partition} -ne ${boot_partition_a} && test ${boot_partition} -ne ${boot_partition_b}; then
|
||||
setenv boot_partition ${boot_partition_a}
|
||||
fi
|
||||
else
|
||||
setenv boot_partition ${boot_partition_a}
|
||||
# ensure boot partition is valid
|
||||
if itest.b *${addr_boot_partition} -ne ${boot_partition_a} && test.b *${addr_boot_partition} -ne ${boot_partition_b}; then
|
||||
mw.b ${addr_boot_partition} ${boot_partition_a}
|
||||
fi
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# fallback boot
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
echo "Check fallback boot"
|
||||
# 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 !!!"
|
||||
|
||||
if test ${boot_partition} -eq ${boot_partition_a}; then
|
||||
setenv boot_partition ${boot_partition_b}
|
||||
if itest *${addr_boot_partition} -eq ${boot_partition_a}; then
|
||||
mv.b ${addr_boot_partition} ${boot_partition_b}
|
||||
else
|
||||
setenv boot_partition ${boot_partition_a}
|
||||
mv.b ${addr_boot_partition} ${boot_partition_a}
|
||||
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}"
|
||||
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
|
||||
|
||||
# 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
|
||||
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}"
|
||||
|
||||
# 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}
|
||||
|
||||
reset
|
||||
reset
|
||||
|
@ -12,8 +12,8 @@ set -e
|
||||
: ${DEFAULT_ROOT_PASSWORD:="alpine"}
|
||||
|
||||
: ${SIZE_BOOT:="100M"}
|
||||
: ${SIZE_ROOT_FS:="150M"}
|
||||
: ${SIZE_ROOT_PART:="250M"}
|
||||
: ${SIZE_ROOT_FS:="200M"}
|
||||
: ${SIZE_ROOT_PART:="500M"}
|
||||
: ${SIZE_DATA:="20M"}
|
||||
: ${IMG_NAME:="alpine-${ALPINE_BRANCH}-sdcard"}
|
||||
|
||||
@ -22,7 +22,7 @@ set -e
|
||||
# static config
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
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"
|
||||
OUTPUT_PATH="/output"
|
||||
@ -139,20 +139,12 @@ mkdir -p ${ROOTFS_PATH}/dev/shm
|
||||
mkdir -p ${ROOTFS_PATH}/var/lock
|
||||
|
||||
# time
|
||||
chroot_exec rc-update add openntpd 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
|
||||
chroot_exec rc-update add ntpd default
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
# uboot tools config
|
||||
cat >${ROOTFS_PATH}/etc/fw_env.config <<EOF
|
||||
/uboot/uboot.env 0x0000 0x4000
|
||||
EOF
|
||||
# uboot tools
|
||||
cp /uboot_tool ${ROOTFS_PATH}/sbin/uboot_tool
|
||||
|
||||
# TODO REMOVE THIS
|
||||
# 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
|
||||
mount -o remount,rw /uboot
|
||||
|
||||
fw_setenv boot_count 1
|
||||
/sbin/uboot_tool reset_counter
|
||||
|
||||
sync
|
||||
mount -o remount,ro /uboot
|
||||
@ -182,6 +174,9 @@ ln -s /data/etc/dropbear/dropbear.conf ${ROOTFS_PATH}/etc/conf.d/dropbear
|
||||
|
||||
# cleanup
|
||||
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"
|
||||
@ -248,7 +243,8 @@ ln -fs /data/etc/shadow ${ROOTFS_PATH}/etc/shadow
|
||||
echo ">> Prepare kernel for uboot"
|
||||
|
||||
# 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
|
||||
echo "Start update for partition B"
|
||||
flash_idx=3
|
||||
else
|
||||
echo "Start update for partition A"
|
||||
flash_idx=2
|
||||
fi
|
||||
|
||||
flash_device="/dev/mmcblk0p${flash_idx}"
|
||||
@ -33,7 +31,7 @@ gunzip -c ${image_file} | dd of=${flash_device} status=progress
|
||||
|
||||
# switch active partition
|
||||
mount -o remount,rw /uboot
|
||||
fw_setenv boot_partition ${flash_idx}
|
||||
/sbin/uboot_tool part_switch
|
||||
sync
|
||||
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