basic working buildroot - rauc example

This commit is contained in:
2026-03-04 16:36:09 +01:00
commit f9d514663d
43 changed files with 1709 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
CONFIG_BLKDISCARD=Y
# CONFIG_WATCHDOG is not set
# CONFIG_MOUNT is not set
# CONFIG_KLOGD is not set
# CONFIG_FEATURE_KLOGD_KLOGCTL is not set
# CONFIG_SYSLOGD is not set
# CONFIG_FEATURE_ROTATE_LOGFILE is not set
# CONFIG_FEATURE_REMOTE_LOG is not set
# CONFIG_FEATURE_SYSLOGD_DUP is not set
# CONFIG_FEATURE_SYSLOGD_CFG is not set
# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set
CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0
# CONFIG_FEATURE_IPC_SYSLOG is not set
CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0
# CONFIG_FEATURE_KMSG_SYSLOG is not set

View File

@@ -0,0 +1 @@
root=/dev/mmcblk0p2 rootwait console=tty1 console=ttyAMA0,115200 fw_dtb net.ifnames=0

View File

@@ -0,0 +1,105 @@
# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details
# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1
# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16
# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720
# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1
# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1
# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2
# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4
# uncomment for composite PAL
#sdtv_mode=2
#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800
# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# Uncomment this to enable infrared communication.
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18
# Additional overlays and parameters are documented /boot/overlays/README
# Enable audio (loads snd_bcm2835)
dtparam=audio=on
# Automatically load overlays for detected cameras
camera_auto_detect=1
# Automatically load overlays for detected DSI displays
display_auto_detect=1
# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d
max_framebuffers=2
# Disable compensation for displays with overscan
disable_overscan=1
[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1
[all]
[pi4]
# Run as fast as firmware / board allows
arm_boost=1
[all]
# End of the default Raspberry Pi config.txt file from:
# https://github.com/RPi-Distro/pi-gen/blob/master/stage1/00-boot-files/files/config.txt
# Load U-Boot instead of Linux
kernel=u-boot.bin
# Enable 64-bit support
arm_64bit=1
# fixes rpi (3B, 3B+, 3A+, 4B and Zero W) ttyAMA0 serial console
dtoverlay=miniuart-bt
# Enable watchdog, system will reset if U-Boot and Linux do not boot within 16 seconds
# Requires fairly recent RPi Firmware:
# https://github.com/raspberrypi/firmware/issues/1651
# Comment this line if you expect to be able to use the U-Boot command prompt!
dtparam=watchdog
# GPIO 4 has a pull-up enabled at reset, but let's set it explicitly just to be sure
gpio=4=ip,pu
# Enable early debugging info
uart_2ndstage=1

View File

@@ -0,0 +1,4 @@
#include "../../../arm/boot/dts/bcm2711-rpi-cm4.dts"
#include "custom-cm4.dtsi"

View File

@@ -0,0 +1,65 @@
/**********************************************************************/
/* WARNING: */
/* This file and the resulting dtb installed to the rootfs will be */
/* IGNORED unless you edit config.txt on the boot partition and */
/* remove the fw_dtb argument from cmdline.txt! */
/**********************************************************************/
/* miniuart-bt-overlay to fix serial console on CM4 */
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
status = "okay";
};
&bt {
status = "disabled";
};
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins &bt_pins &fake_bt_cts>;
status = "okay";
};
&uart0_pins {
brcm,pins;
brcm,function;
brcm,pull;
};
&uart1_pins {
brcm,pins = <32 33>;
brcm,function = <2>; /* alt5=UART1 */
brcm,pull = <0 2>;
};
&gpio {
fake_bt_cts: fake_bt_cts {
brcm,pins = <31>;
brcm,function = <1>; /* output */
};
};
/ {
aliases {
serial0 = "/soc/serial@7e201000";
serial1 = "/soc/serial@7e215040";
};
__overrides__ {
krnbt = <&minibt>,"status";
};
};
/* otg_mode=1 */
&usb {
status = "disabled";
};
&xhci {
status = "okay";
};

View File

@@ -0,0 +1,17 @@
image boot.vfat {
vfat {
files = {
"bcm2711-rpi-cm4.dtb",
"custom/cmdline.txt",
"rpi-firmware/config.txt",
"rpi-firmware/fixup4.dat",
"rpi-firmware/start4.elf",
"rpi-firmware/overlays",
"u-boot.bin",
"boot.scr"
}
}
size = 256M
}

View File

@@ -0,0 +1,85 @@
image data.ext4 {
name = "Data"
mountpoint = /data
ext4 {
use-mke2fs = true
label = "Data"
features = "^64bit"
}
size = 128M
}
image upload.ext4 {
name = "Upload"
empty = true
ext4 {
use-mke2fs = true
label = "Upload"
features = "^64bit"
}
size = 900M
}
image sdcard.img {
hdimage {
partition-table-type = mbr
extended-partition = 4
}
partition ubootenv0 {
image = "uboot-env.bin"
in-partition-table = false
offset = 1M
}
partition ubootenv1 {
image = "uboot-env.bin"
in-partition-table = false
offset = 2M
}
partition boot0 {
partition-type = 0xC
bootable = true
image = "boot.vfat"
# Leave room for U-Boot environment
offset = 4M
}
partition boot1 {
image = "boot.vfat"
in-partition-table = false
# 256M + 4M
offset = 260M
}
partition rescue {
partition-type = 0x83
image = "rootfs.squashfs"
size = 256M
}
partition data {
partition-type = 0x83
image = "data.ext4"
size = 128M
}
partition rootfs0 {
partition-type = 0x83
image = "rootfs.ext4"
size = 900M
}
partition rootfs1 {
partition-type = 0x83
image = "rootfs.ext4"
size = 900M
}
partition upload {
partition-type = 0x83
image = "upload.ext4"
size = 900M
}
}

View File

@@ -0,0 +1,9 @@
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_DM_VERITY=y
CONFIG_SQUASHFS=y
CONFIG_CRYPTO_SHA256=y
CONFIG_DM_CRYPT=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_XTS=y

65
board/beacon-cm4/post-build.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/bin/sh
set -u
set -e
RAUC_COMPATIBLE="${2:-beacon-cm4}"
BOARD_DIR="$(dirname $0)"
BOARD_NAME="$(basename ${BOARD_DIR})"
# Pass VERSION as an environment variable (eg: export from a top-level Makefile)
# If VERSION is unset, fallback to the Buildroot version
RAUC_VERSION=${VERSION:-${BR2_VERSION_FULL}}
# Add a console on tty1
if [ -e ${TARGET_DIR}/etc/inittab ]; then
grep -qE '^tty1::' ${TARGET_DIR}/etc/inittab || \
sed -i '/GENERIC_SERIAL/a\
tty1::respawn:/sbin/getty -L tty1 0 vt100 # HDMI console' ${TARGET_DIR}/etc/inittab
# systemd doesn't use /etc/inittab, enable getty.tty1.service instead
elif [ -d ${TARGET_DIR}/etc/systemd ]; then
mkdir -p "${TARGET_DIR}/etc/systemd/system/getty.target.wants"
ln -sf /lib/systemd/system/getty@.service \
"${TARGET_DIR}/etc/systemd/system/getty.target.wants/getty@tty1.service"
fi
# Mount persistent data partitions
if [ -e ${TARGET_DIR}/etc/fstab ]; then
# For configuration data
# WARNING: data=journal is safest, but potentially slow!
grep -qE 'LABEL=Data' ${TARGET_DIR}/etc/fstab || \
echo "LABEL=Data /data ext4 defaults,data=journal,noatime 0 0" >> ${TARGET_DIR}/etc/fstab
# For bulk data (eg: firmware updates)
grep -qE 'LABEL=Upload' ${TARGET_DIR}/etc/fstab || \
echo "LABEL=Upload /upload ext4 defaults,noatime 0 0" >> ${TARGET_DIR}/etc/fstab
fi
# Copy custom cmdline.txt file
install -D -m 0644 ${BR2_EXTERNAL_BEACON_PATH}/board/beacon-cm4/cmdline.txt ${BINARIES_DIR}/custom/cmdline.txt
# Copy RAUC certificate
if [ -e ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/ca.cert.pem ]; then
install -D -m 0644 ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/ca.cert.pem ${TARGET_DIR}/etc/rauc/keyring.pem
else
echo "RAUC CA certificate not found!"
echo "...did you run the openssl-ca.sh script?"
exit 1
fi
# Update RAUC compatible string
sed -i "/compatible/s/=.*\$/=${RAUC_COMPATIBLE}/" ${TARGET_DIR}/etc/rauc/system.conf
# Create rauc version file
echo "${RAUC_VERSION}" > ${TARGET_DIR}/etc/rauc/version
# Customize login prompt with login hints
cat <<- EOF >> ${TARGET_DIR}/etc/issue
Default username:password is [user:beacon]
Root login disabled, use sudo su -
With great power comes great responsibility!
eth0: \4{eth0}
EOF

140
board/beacon-cm4/post-image.sh Executable file
View File

@@ -0,0 +1,140 @@
#!/bin/bash
set -e
BOARD_DIR="$(dirname $0)"
BOARD_NAME="$(basename ${BOARD_DIR})"
GENIMAGE_CFG="${BOARD_DIR}/genimage.cfg"
GENIMAGE_TMP="${BUILD_DIR}/genimage.tmp"
GENBOOTFS_CFG="${BOARD_DIR}/genbootfs.cfg"
RAUC_COMPATIBLE="${2:-beacon-cm4}"
# Pass VERSION as an environment variable (eg: export from a top-level Makefile)
# If VERSION is unset, fallback to the Buildroot version
RAUC_VERSION=${VERSION:-${BR2_VERSION_FULL}}
# Pass an empty rootpath. genimage makes a full copy of the given rootpath to
# ${GENIMAGE_TMP}/root so passing TARGET_DIR would be a waste of time and disk
# space. We don't rely on genimage to build the rootfs image, just to insert a
# pre-built one in the disk image.
trap 'rm -rf "${ROOTPATH_TMP}"' EXIT
ROOTPATH_TMP="$(mktemp -d)"
rm -rf "${GENIMAGE_TMP}"
# Generate the boot filesystem image
genimage \
--rootpath "${ROOTPATH_TMP}" \
--tmppath "${GENIMAGE_TMP}" \
--inputpath "${BINARIES_DIR}" \
--outputpath "${BINARIES_DIR}" \
--config "${GENBOOTFS_CFG}"
# Generate a RAUC update bundle for the full system (bootfs + rootfs)
[ -e ${BINARIES_DIR}/update.raucb ] && rm -rf ${BINARIES_DIR}/update.raucb
[ -e ${BINARIES_DIR}/temp-update ] && rm -rf ${BINARIES_DIR}/temp-update
mkdir -p ${BINARIES_DIR}/temp-update
cat >> ${BINARIES_DIR}/temp-update/manifest.raucm << EOF
[update]
compatible=${RAUC_COMPATIBLE}
version=${RAUC_VERSION}
[bundle]
format=verity
[image.bootloader]
filename=boot.vfat
[image.rootfs]
filename=rootfs.ext4
EOF
ln -L ${BINARIES_DIR}/boot.vfat ${BINARIES_DIR}/temp-update/
ln -L ${BINARIES_DIR}/rootfs.ext4 ${BINARIES_DIR}/temp-update/
${HOST_DIR}/bin/rauc bundle \
--cert ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/development-1.cert.pem \
--key ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/private/development-1.key.pem \
--keyring ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/ca.cert.pem \
${BINARIES_DIR}/temp-update/ \
${BINARIES_DIR}/update.raucb
# Generate a RAUC update bundle for just the root filesystem
[ -e ${BINARIES_DIR}/rootfs.raucb ] && rm -rf ${BINARIES_DIR}/rootfs.raucb
[ -e ${BINARIES_DIR}/temp-rootfs ] && rm -rf ${BINARIES_DIR}/temp-rootfs
mkdir -p ${BINARIES_DIR}/temp-rootfs
cat >> ${BINARIES_DIR}/temp-rootfs/manifest.raucm << EOF
[update]
compatible=${RAUC_COMPATIBLE}
version=${RAUC_VERSION}
[bundle]
format=verity
[image.rootfs]
filename=rootfs.ext4
EOF
ln -L ${BINARIES_DIR}/rootfs.ext4 ${BINARIES_DIR}/temp-rootfs/
${HOST_DIR}/bin/rauc bundle \
--cert ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/development-1.cert.pem \
--key ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/private/development-1.key.pem \
--keyring ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/ca.cert.pem \
${BINARIES_DIR}/temp-rootfs/ \
${BINARIES_DIR}/rootfs.raucb
# Parse update.raucb and generate initial rauc.status file
# FIXME: There is probably a MUCH better way to do this,
# suggestions welcome!
eval $(rauc --keyring ${BR2_EXTERNAL_BEACON_PATH}/openssl-ca/dev/ca.cert.pem --output-format=shell info ${BINARIES_DIR}/update.raucb)
cat > ${BINARIES_DIR}/rauc.status << EOF
[slot.rescue.0]
bundle.compatible=${RAUC_MF_COMPATIBLE}
bundle.version=${RAUC_MF_VERSION}
status=ok
[slot.${RAUC_IMAGE_CLASS_0}.0]
bundle.compatible=${RAUC_MF_COMPATIBLE}
bundle.version=${RAUC_MF_VERSION}
status=ok
sha256=${RAUC_IMAGE_DIGEST_0}
size=${RAUC_IMAGE_SIZE_0}
[slot.${RAUC_IMAGE_CLASS_1}.0]
bundle.compatible=${RAUC_MF_COMPATIBLE}
bundle.version=${RAUC_MF_VERSION}
status=ok
sha256=${RAUC_IMAGE_DIGEST_1}
size=${RAUC_IMAGE_SIZE_1}
[slot.${RAUC_IMAGE_CLASS_1}.1]
bundle.compatible=${RAUC_MF_COMPATIBLE}
bundle.version=${RAUC_MF_VERSION}
status=ok
sha256=${RAUC_IMAGE_DIGEST_1}
size=${RAUC_IMAGE_SIZE_1}
EOF
# Install rauc.status to genimage rootpath
install -D -m 0644 ${BINARIES_DIR}/rauc.status ${ROOTPATH_TMP}/data/rauc.status
# Generate the sdcard image
rm -rf "${GENIMAGE_TMP}"
genimage \
--rootpath "${ROOTPATH_TMP}" \
--tmppath "${GENIMAGE_TMP}" \
--inputpath "${BINARIES_DIR}" \
--outputpath "${BINARIES_DIR}" \
--config "${GENIMAGE_CFG}"
# Create a bmap file for the sdcard image
bmaptool create "${BINARIES_DIR}/sdcard.img" -o "${BINARIES_DIR}/sdcard.img.bmap"
# Compress the sdcard image
[ -e "${BINARIES_DIR}/sdcard.img.xz" ] && rm "${BINARIES_DIR}/sdcard.img.xz"
xz -v -T 0 "${BINARIES_DIR}/sdcard.img"

View File

@@ -0,0 +1,3 @@
bootargs_force=
bootargs_extra=

View File

@@ -0,0 +1,2 @@
/dev/mmcblk0 0x100000 0x8000
/dev/mmcblk0 0x200000 0x8000

View File

@@ -0,0 +1,31 @@
[system]
compatible=beacon-cm4
mountprefix=/run/rauc
statusfile=/data/rauc.status
bootloader=uboot
bundle-formats=-plain
[keyring]
path=/etc/rauc/keyring.pem
use-bundle-signing-time=true
[slot.bootloader.0]
device=/dev/mmcblk0
type=boot-mbr-switch
region-start=4M
region-size=512M
[slot.rescue.0]
device=/dev/mmcblk0p2
type=raw
[slot.rootfs.0]
device=/dev/mmcblk0p5
type=ext4
bootname=A
[slot.rootfs.1]
device=/dev/mmcblk0p6
type=ext4
bootname=B

View File

@@ -0,0 +1 @@
user ALL=(ALL) NOPASSWD: ALL

View File

@@ -0,0 +1,6 @@
[Manager]
RuntimeWatchdogSec=10
#RebootWatchdogSec=10min
#KExecWatchdogSec=off
#WatchdogDevice=

View File

@@ -0,0 +1,8 @@
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_OFFSET_REDUND=0x200000
CONFIG_ENV_SIZE=0x8000
# CONFIG_ENV_IS_IN_FAT is not set
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_CMD_SQUASHFS=y
CONFIG_USB_XHCI_BRCM=y

View File

@@ -0,0 +1,114 @@
test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "A B"
test -n "${BOOT_A_LEFT}" || setenv BOOT_A_LEFT 3
test -n "${BOOT_B_LEFT}" || setenv BOOT_B_LEFT 3
test -n "${bootargs_default}" || setenv bootargs_default coherent_pool=1M vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 rootwait console=tty1 console=ttyAMA0,115200
test -n "${DTB_FILE}" || setenv DTB_FILE bcm2711-rpi-cm4.dtb
# RPi firmware uses a dynamic fdt_addr, but U-Boot does not use the fw
# provided address if fdt_addr is already defined in the environment!
# Copy fdt_addr to a local variable and delete the environment variable
# so it never gets accidentally saved:
fdt_addr=${fdt_addr}
env delete fdt_addr
# To boot from the rescue partition, tie GPIO4 (pin 7) to GND (pin 9)
# The gpio input command will return an exit status of 0 (true)
# If the pin is high (pulled up by default) the exit status is 1 (false)
if gpio input gpio4 ; then
# GPIO4 is shorted to ground so boot in rescue mode
echo "Booting from rescue partition"
setenv load_uenv "load mmc 0:2 ${kernel_addr_r} /boot/uEnv.txt"
setenv load_fdt "load mmc 0:2 ${fdt_addr_r} /boot/${DTB_FILE}"
setenv load_kernel "load mmc 0:2 ${kernel_addr_r} /boot/Image"
raucargs="root=/dev/mmcblk0p2"
rescue=true
else
raucargs=unset
for BOOT_SLOT in "${BOOT_ORDER}"; do
if test "x${raucargs}" != "xunset"; then
# skip remaining slots
elif test "x${BOOT_SLOT}" = "xA"; then
if test ${BOOT_A_LEFT} -gt 0; then
echo "Found valid slot A, ${BOOT_A_LEFT} attempts remaining"
setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1
setenv load_uenv "load mmc 0:5 ${kernel_addr_r} /boot/uEnv.txt"
setenv load_fdt "load mmc 0:5 ${fdt_addr_r} /boot/${DTB_FILE}"
setenv load_kernel "load mmc 0:5 ${kernel_addr_r} /boot/Image"
raucargs="root=/dev/mmcblk0p5 rauc.slot=A"
fi
elif test "x${BOOT_SLOT}" = "xB"; then
if test ${BOOT_B_LEFT} -gt 0; then
echo "Found valid slot B, ${BOOT_B_LEFT} attempts remaining"
setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1
setenv load_uenv "load mmc 0:6 ${kernel_addr_r} /boot/uEnv.txt"
setenv load_fdt "load mmc 0:6 ${fdt_addr_r} /boot/${DTB_FILE}"
setenv load_kernel "load mmc 0:6 ${kernel_addr_r} /boot/Image"
raucargs="root=/dev/mmcblk0p6 rauc.slot=B"
fi
fi
done
fi
if test "x${raucargs}" = "xunset"; then
echo "No valid slot found, resetting tries to 3"
setenv BOOT_A_LEFT 3
setenv BOOT_B_LEFT 3
saveenv
reset
fi
# Examine the fdt loaded by the firmware
# Pass fw_dtb to use the dtb loaded by the firmware
fdt_live=unset
fdt addr ${fdt_addr}
fdt get value bootargs_fw /chosen bootargs
for arg in ${bootargs_fw} ; do
if test "x${arg}" = "xfw_dtb" ; then
fdt_live=${fdt_addr}
fi
done
# Save bootargs_fw in a local variable for later use
bootargs_fw=${bootargs_fw}
env del bootargs_fw
if test "x${rescue}" = "xtrue" -o "x${fdt_live}" = "xunset"; then
# Using device-tree from rootfs
# Check to see if we have any customizations in a uEnv.txt file
env del bootargs_force bootargs_extra
echo "Checking for /boot/uEnv.txt"
if run load_uenv ; then
echo "Importing uEnv.txt"
env import -t -r ${fileaddr} ${filesize}
fi
# Load our actual device-tree file
echo "Loading device-tree"
run load_fdt
# Point to run-time device-tree
fdt_live=${fdt_addr_r}
# Setup kernel parameters
if test -n "${bootargs_force}" ; then
setenv bootargs "${bootargs_force} ${raucargs}"
else
setenv bootargs "${bootargs_default} ${bootargs_extra} ${raucargs}"
fi
else
# Using FW provided device-tree
# Append rauc boot arguments to FW generated command line
# This setting will override /chosen/bootargs in the device-tree
echo "Using firmware device-tree"
setenv bootargs "${bootargs_fw} ${raucargs}"
fi
# Store updated boot state...
# ...above code should have modified BOOT_(AB)_LEFT and bootargs
saveenv
echo "Loading kernel"
run load_kernel
echo "Starting kernel"
booti ${kernel_addr_r} - ${fdt_live}

2
board/beacon-cm4/users Normal file
View File

@@ -0,0 +1,2 @@
user 1000 user 1000 $6$XUtVBGdpmufH8R2H$olowG.5WTG7pEth5D..PyeKEmAze3SM9.I6Raf9k.OfS0OiS0wxbdOBJH.BgklLEKWH6REmXRUGyDylyWfDmg/ /home/user /bin/sh adm,audio,cdrom,dialout,floppy,plugdev,staff,sudo,video Default user