Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 770acbdde7 | |||
| 1e94983f7f | |||
| 4953384b87 | |||
| 2995d45682 |
1
board/raspberrypi/overlay/etc/default/dropbear
Normal file
1
board/raspberrypi/overlay/etc/default/dropbear
Normal file
@@ -0,0 +1 @@
|
||||
DROPBEAR_ARGS="-s -D /etc/dropbear/"
|
||||
1
board/raspberrypi/overlay/etc/dropbear/authorized_keys
Normal file
1
board/raspberrypi/overlay/etc/dropbear/authorized_keys
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCkOLG7nNrQWYtf1H8Lsmg7dHh3/dz7ATaKnmyp/o+tcBXsjg8q1SewBrwUEAIigUjNAlbNu5lnMGihop6Jtq4aV0u3vokeMpnytMMRapF8fLnUSlTCgohHBV0PdEino0SE1d4MzPkzzOT7Naq9pc49aNpGwHLOMH89k7QXFM0uxrXA8e42IhNyGxwePla/Svud70J5jwmFFUi7h5Q69mxLA0wLvGSEDbKrBfTtZH2d4FN7PExJPkltL7rD6Wkwg0W2H8z3NMxhFZJsilj3YsctBhP5UNB4PM7tV6zVpv2W1RmW5xH+cxigbCVaDlEmRFwHkKufGlBZcW6UG2tOTjb1uraWaFxL3gOteGRWzO+fDo/Bt3mQkDpzCPMEZhAFMw1Fkq5gK5fMP91hjLWGxKS2cL3W5f9DIUPCjtLZFQRKBL/vxhXEmjFpnaHOQz4UlAA5ws3vKDYTVw70KFhRoJWSy+Jv+THfDz5e5F0Kx+DMOSB2ldmR6MvLDxE1gyG7schAQmAxus2nW1A3UItaqVpBTxwPfoEi/uylTLp/LeJtVszWe8wTp/0l9P2qDe+BJu/oM9k4d6nL5dOv4HqlESEn+BX8zMou7vrD/Zv3IE7IykWm2Zrap4m28O/imKWQDs6tk5+PqVOO8MgLReyqDOmxkOJIZYQqkok/lOAF5e0NpQ== gabriel@gabriel-a65
|
||||
BIN
board/raspberrypi/overlay/etc/dropbear/dropbear_ecdsa_host_key
Normal file
BIN
board/raspberrypi/overlay/etc/dropbear/dropbear_ecdsa_host_key
Normal file
Binary file not shown.
BIN
board/raspberrypi/overlay/etc/dropbear/dropbear_ed25519_host_key
Normal file
BIN
board/raspberrypi/overlay/etc/dropbear/dropbear_ed25519_host_key
Normal file
Binary file not shown.
BIN
board/raspberrypi/overlay/etc/dropbear/dropbear_rsa_host_key
Normal file
BIN
board/raspberrypi/overlay/etc/dropbear/dropbear_rsa_host_key
Normal file
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
|
||||
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQdYqMPAif9rmbY8dBWey1LjOMTbFMj
|
||||
NpM78M64OGpJ0oqj0/BHLGjJFXgHiDnptJmWjPObcbGpi9UU9k9AjwyGAAAAsNlste7ZbL
|
||||
XuAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBB1iow8CJ/2uZtjx
|
||||
0FZ7LUuM4xNsUyM2kzvwzrg4aknSiqPT8EcsaMkVeAeIOem0mZaM85txsamL1RT2T0CPDI
|
||||
YAAAAhAK4+iOL7T/yz6pAZq9r11B8LNOkNilk9AbtMI/tHlteiAAAAEHJvb3RAcmFzcGJl
|
||||
cnJ5cGkBAgMEBQYH
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBB1iow8CJ/2uZtjx0FZ7LUuM4xNsUyM2kzvwzrg4aknSiqPT8EcsaMkVeAeIOem0mZaM85txsamL1RT2T0CPDIY= root@raspberrypi
|
||||
@@ -0,0 +1,7 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACBQiu65JvR0Vvc86E6Ltb56WOUP+O6ly0jWvz3y+ad8HQAAAJhAtJG0QLSR
|
||||
tAAAAAtzc2gtZWQyNTUxOQAAACBQiu65JvR0Vvc86E6Ltb56WOUP+O6ly0jWvz3y+ad8HQ
|
||||
AAAEBfZMawzfTrqgXQ52Jr3eRJUDo024OotKQva+kS18ZFv1CK7rkm9HRW9zzoTou1vnpY
|
||||
5Q/47qXLSNa/PfL5p3wdAAAAEHJvb3RAcmFzcGJlcnJ5cGkBAgMEBQ==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFCK7rkm9HRW9zzoTou1vnpY5Q/47qXLSNa/PfL5p3wd root@raspberrypi
|
||||
38
board/raspberrypi/overlay/etc/dropbear/ssh_host_rsa_key
Normal file
38
board/raspberrypi/overlay/etc/dropbear/ssh_host_rsa_key
Normal file
@@ -0,0 +1,38 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
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
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCiQmsKmalrn9UV9w9JFssXVLA/sQiWKuOVSsPVSpbkFFum0/zK3RArGyAGmN3yXeGbsfwbOl79P/MsTmrI1cQLYFY63uh6GkWn3M6+ZhaXiTIN639Z02ozspIuTuNYjMHW7OtpYSZbDoVyQR2OQe9y4OxFzGoOTaZrolr32D9mzyoFPG++FM7lRHs6AVNdTWUPkLqg+ZrIlCooPp3NRcm+njeP43EUxvhnjzK3Pq6dkzc1ExAxNv2xtOvvNDfIP3cvUyRJW+c1xjOGCygiHb6CygSpSExA2jSsKNuNi5ELhqytjk0634wgL9ds20YSezbYbzcX8eChzA32vWOWU/pG5NvK5lUrrnhEzGrEZEFTNAwdx2kOPLLzjkbO2w/nvMLiahhlGHtWDBXEZEaiKddh1sT5UnZbEEGrn+PkxFMvHHukttpz6xfDgR32tGoyljML6KyR4ni5TiZwulkNIbD1IOHFWu6wPpIXV5FNe0lY28M9VThWq0NNoWbyn/uw2m8= root@raspberrypi
|
||||
@@ -2,9 +2,12 @@ BR2_arm=y
|
||||
BR2_arm1176jzf_s=y
|
||||
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_6_6=y
|
||||
BR2_TOOLCHAIN_BUILDROOT_CXX=y
|
||||
BR2_PACKAGE_HOST_GDB=y
|
||||
BR2_GDB_VERSION_16=y
|
||||
BR2_GLOBAL_PATCH_DIR="board/raspberrypi/patches"
|
||||
BR2_DOWNLOAD_FORCE_CHECK_HASHES=y
|
||||
BR2_SYSTEM_DHCP="eth0"
|
||||
BR2_ROOTFS_OVERLAY="board/raspberrypi/overlay/"
|
||||
BR2_ROOTFS_POST_BUILD_SCRIPT="board/raspberrypi/post-build.sh"
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="board/raspberrypi/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
@@ -14,19 +17,33 @@ BR2_LINUX_KERNEL_DEFCONFIG="bcmrpi"
|
||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||
BR2_LINUX_KERNEL_INTREE_DTS_NAME="broadcom/bcm2708-rpi-b-rev1 broadcom/bcm2708-rpi-b broadcom/bcm2708-rpi-b-plus broadcom/bcm2708-rpi-cm"
|
||||
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
|
||||
BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
|
||||
BR2_PACKAGE_XZ=y
|
||||
BR2_PACKAGE_GDB=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_BOOTCODE_BIN=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="board/raspberrypi/config_default.txt"
|
||||
# BR2_PACKAGE_RPI_FIRMWARE_INSTALL_DTB_OVERLAYS is not set
|
||||
BR2_PACKAGE_LIBGPIOD2=y
|
||||
BR2_PACKAGE_LIBGPIOD2_TOOLS=y
|
||||
BR2_PACKAGE_DROPBEAR=y
|
||||
BR2_PACKAGE_IPERF3=y
|
||||
BR2_PACKAGE_WPA_SUPPLICANT=y
|
||||
BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
|
||||
BR2_PACKAGE_HTOP=y
|
||||
BR2_PACKAGE_KMOD=y
|
||||
BR2_PACKAGE_KMOD_TOOLS=y
|
||||
BR2_PACKAGE_UTIL_LINUX=y
|
||||
BR2_PACKAGE_UTIL_LINUX_BINARIES=y
|
||||
BR2_PACKAGE_NANO=y
|
||||
# BR2_PACKAGE_NANO_TINY is not set
|
||||
BR2_TARGET_ROOTFS_EXT2=y
|
||||
BR2_TARGET_ROOTFS_EXT2_4=y
|
||||
BR2_TARGET_ROOTFS_EXT2_SIZE="120M"
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_TARGET_ROOTFS_TAR_XZ=y
|
||||
BR2_TARGET_UBOOT=y
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="rpi"
|
||||
BR2_TARGET_UBOOT_NEEDS_OPENSSL=y
|
||||
BR2_TARGET_UBOOT_NEEDS_GNUTLS=y
|
||||
BR2_PACKAGE_HOST_DOSFSTOOLS=y
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_KMOD_XZ=y
|
||||
|
||||
311
flash.sh
Executable file
311
flash.sh
Executable file
@@ -0,0 +1,311 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Flash Buildroot SD card image to SD card
|
||||
# Usage: ./flash.sh /dev/sdX
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default image path
|
||||
IMAGE_PATH="output/images/sdcard.img"
|
||||
|
||||
# Function to print colored messages
|
||||
print_error() {
|
||||
echo -e "${RED}ERROR: $1${NC}" >&2
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}$1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}WARNING: $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "$1"
|
||||
}
|
||||
|
||||
# Function to show usage
|
||||
usage() {
|
||||
echo "Usage: $0 [-y] <device> [image_path]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -y Skip confirmation prompt (automatic yes)"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " device Path to SD card device (e.g., /dev/sdb, /dev/mmcblk0)"
|
||||
echo " image_path Path to image file (default: sdcard.img)"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 /dev/sdb"
|
||||
echo " $0 /dev/mmcblk0 output/images/sdcard.img"
|
||||
echo " $0 -y /dev/sdb sdcard.img"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if running as root
|
||||
check_root() {
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
print_error "This script must be run as root or with sudo"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if device is removable (likely SD card or USB)
|
||||
is_removable() {
|
||||
local device=$1
|
||||
local device_name=$(basename "$device")
|
||||
|
||||
# For mmcblk devices, check the device itself
|
||||
if [[ "$device_name" =~ ^mmcblk[0-9]+p?[0-9]*$ ]]; then
|
||||
device_name=$(echo "$device_name" | sed 's/p[0-9]*$//')
|
||||
fi
|
||||
|
||||
# For sd devices, remove partition number
|
||||
if [[ "$device_name" =~ ^sd[a-z][0-9]*$ ]]; then
|
||||
device_name=$(echo "$device_name" | sed 's/[0-9]*$//')
|
||||
fi
|
||||
|
||||
# Check if removable flag is set
|
||||
local removable_file="/sys/block/${device_name}/removable"
|
||||
if [ -f "$removable_file" ]; then
|
||||
local removable=$(cat "$removable_file")
|
||||
if [ "$removable" = "1" ]; then
|
||||
return 0 # Is removable
|
||||
fi
|
||||
fi
|
||||
|
||||
# Additional check: SD cards often show up in specific subsystems
|
||||
local device_path="/sys/block/${device_name}/device"
|
||||
if [ -d "$device_path" ]; then
|
||||
# Check if it's an MMC/SD device
|
||||
if readlink -f "$device_path" | grep -q "mmc"; then
|
||||
return 0 # Is MMC/SD device
|
||||
fi
|
||||
|
||||
# Check if it's a USB device
|
||||
if readlink -f "$device_path" | grep -q "usb"; then
|
||||
return 0 # Is USB device (could be USB card reader)
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1 # Not removable
|
||||
}
|
||||
|
||||
# Get human-readable device info
|
||||
get_device_info() {
|
||||
local device=$1
|
||||
local device_name=$(basename "$device")
|
||||
|
||||
# Remove partition number if present
|
||||
if [[ "$device_name" =~ ^mmcblk[0-9]+p?[0-9]*$ ]]; then
|
||||
device_name=$(echo "$device_name" | sed 's/p[0-9]*$//')
|
||||
elif [[ "$device_name" =~ ^sd[a-z][0-9]*$ ]]; then
|
||||
device_name=$(echo "$device_name" | sed 's/[0-9]*$//')
|
||||
fi
|
||||
|
||||
# Get model and size info
|
||||
local model_file="/sys/block/${device_name}/device/model"
|
||||
local size_file="/sys/block/${device_name}/size"
|
||||
|
||||
local model="Unknown"
|
||||
local size_bytes=0
|
||||
|
||||
if [ -f "$model_file" ]; then
|
||||
model=$(cat "$model_file" | tr -d '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
fi
|
||||
|
||||
if [ -f "$size_file" ]; then
|
||||
# Size is in 512-byte sectors
|
||||
size_bytes=$(($(cat "$size_file") * 512))
|
||||
fi
|
||||
|
||||
# Convert to GB
|
||||
local size_gb=$(awk "BEGIN {printf \"%.2f\", $size_bytes/1024/1024/1024}")
|
||||
|
||||
echo "Model: $model, Size: ${size_gb}GB"
|
||||
}
|
||||
|
||||
# Validate device path
|
||||
validate_device() {
|
||||
local device=$1
|
||||
|
||||
# Check if device exists
|
||||
if [ ! -b "$device" ]; then
|
||||
print_error "Device $device does not exist or is not a block device"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get device information
|
||||
local device_info=$(get_device_info "$device")
|
||||
print_info "Device info: $device_info"
|
||||
|
||||
# Check if device is removable (SD card or USB)
|
||||
if ! is_removable "$device"; then
|
||||
print_error "Device $device does not appear to be a removable device (SD card or USB)"
|
||||
print_error "This safety check prevents accidentally flashing internal drives"
|
||||
print_warning "If you are certain this is correct, you can modify the script to bypass this check"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Device $device appears to be a removable device (SD card/USB)"
|
||||
}
|
||||
|
||||
# Validate image file
|
||||
validate_image() {
|
||||
local image=$1
|
||||
|
||||
if [ ! -f "$image" ]; then
|
||||
print_error "Image file $image does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -r "$image" ]; then
|
||||
print_error "Image file $image is not readable"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Unmount all partitions of the device
|
||||
unmount_device() {
|
||||
local device=$1
|
||||
|
||||
print_info "Checking for mounted partitions on $device..."
|
||||
|
||||
# Handle both /dev/sdX and /dev/mmcblkX naming schemes
|
||||
if [[ "$device" == *"mmcblk"* ]] || [[ "$device" == *"loop"* ]]; then
|
||||
# For mmcblk devices, partitions are named like mmcblk0p1, mmcblk0p2
|
||||
partitions=$(lsblk -ln -o NAME "$device" | tail -n +2 | sed "s|^|/dev/|")
|
||||
else
|
||||
# For sd devices, partitions are named like sdb1, sdb2
|
||||
partitions=$(lsblk -ln -o NAME "$device" | tail -n +2 | sed "s|^|/dev/|")
|
||||
fi
|
||||
|
||||
# Unmount each partition
|
||||
for partition in $partitions; do
|
||||
if mountpoint -q "$partition" 2>/dev/null || grep -qs "$partition" /proc/mounts; then
|
||||
print_info "Unmounting $partition..."
|
||||
if ! umount "$partition" 2>/dev/null; then
|
||||
print_warning "Failed to unmount $partition, trying lazy unmount..."
|
||||
umount -l "$partition" || true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Give the system a moment to release the device
|
||||
sleep 1
|
||||
|
||||
print_success "All partitions unmounted"
|
||||
}
|
||||
|
||||
# Flash the image
|
||||
flash_image() {
|
||||
local device=$1
|
||||
local image=$2
|
||||
|
||||
# Perform the flash operation
|
||||
print_info "Writing image..."
|
||||
if command -v pv &> /dev/null; then
|
||||
# Use pv for progress if available
|
||||
pv "$image" | dd of="$device" bs=4M conv=fsync status=none
|
||||
else
|
||||
# Fall back to dd with progress
|
||||
dd if="$image" of="$device" bs=4M conv=fsync status=progress
|
||||
fi
|
||||
|
||||
# Ensure all data is written
|
||||
print_info "Syncing filesystem..."
|
||||
sync
|
||||
|
||||
print_success "Image successfully flashed to $device!"
|
||||
}
|
||||
|
||||
# Main script execution
|
||||
main() {
|
||||
local skip_confirm="no"
|
||||
local device=""
|
||||
local image=""
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-y)
|
||||
skip_confirm="yes"
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
print_error "Unknown option: $1"
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if [ -z "$device" ]; then
|
||||
device=$1
|
||||
elif [ -z "$image" ]; then
|
||||
image=$1
|
||||
else
|
||||
print_error "Too many arguments"
|
||||
usage
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if device was provided
|
||||
if [ -z "$device" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
# Set default image if not provided
|
||||
image=${image:-$IMAGE_PATH}
|
||||
|
||||
print_info "================================"
|
||||
print_info "Buildroot SD Card Flash Script"
|
||||
print_info "================================"
|
||||
print_info "Device: $device"
|
||||
print_info "Image: $image"
|
||||
print_info ""
|
||||
|
||||
# Run checks
|
||||
check_root
|
||||
validate_device "$device"
|
||||
validate_image "$image"
|
||||
|
||||
# Get user confirmation before unmounting
|
||||
# (unmount will happen in flash_image after confirmation)
|
||||
local image_size=$(stat -c%s "$image")
|
||||
local image_size_mb=$((image_size / 1024 / 1024))
|
||||
|
||||
print_info "Ready to flash $image (${image_size_mb} MB) to $device"
|
||||
print_warning "This will DESTROY all data on $device!"
|
||||
|
||||
if [ "$skip_confirm" != "yes" ]; then
|
||||
read -p "Continue? [y/N] " -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_info "Aborted by user"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
print_info "Skipping confirmation due to -y flag"
|
||||
fi
|
||||
|
||||
# Now unmount the device after confirmation
|
||||
unmount_device "$device"
|
||||
|
||||
# Flash image
|
||||
flash_image "$device" "$image"
|
||||
|
||||
print_info ""
|
||||
print_success "✓ Flashing complete!"
|
||||
print_info "You can now safely remove the SD card"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user