diff --git a/Documentation/user/variables.rst b/Documentation/user/variables.rst index a13de1b..974ab88 100644 --- a/Documentation/user/variables.rst +++ b/Documentation/user/variables.rst @@ -25,6 +25,47 @@ to assigning a value with ``global.myvar1=foobar``, but the latter fails when a variable has not been created before. +.. _config_device: + +Non volatile variables +---------------------- + +Additionally to global variables barebox also has non volatile (nv) variables. +Unlike the global variables the config variables are persistent over reboots. + +Each nv variable is linked with the global variable of the same name. +Whenever the nv variable changes its value the corresponding global +variable also changes its value. The other way round though is not true: +Changing a global variable does not change the corresponding nv variable. +This means that changing a global variable changes the behaviour for the +currently running barebox, while changing a nv variable changes the +behaviour persistently over reboots. + +nv variables can be created or removed with the :ref:`command_nv` +command. The nv variables are made persistent using the environment +facilities of barebox, so a :ref:`saveenv` must be issued to store the actual +values. + +examples: + +.. code-block:: sh + + barebox@Phytec phyCARD-i.MX27:/ devinfo nv + barebox@Phytec phyCARD-i.MX27:/ nv model=myboard + barebox@myboard:/ devinfo nv + Parameters: + model: myboard + barebox@myboard:/ devinfo global + Parameters: + [...] + model: myboard + [...] + barebox@myboard:/ global.model=yourboard + barebox@yourboard:/ devinfo nv + Parameters: + model: myboard + barebox@yourboard:/ + .. _magicvars: Magic variables diff --git a/arch/arm/boards/archosg9/env/init/bootsource b/arch/arm/boards/archosg9/env/init/bootsource index b3df447..6145a76 100644 --- a/arch/arm/boards/archosg9/env/init/bootsource +++ b/arch/arm/boards/archosg9/env/init/bootsource @@ -1,5 +1,9 @@ #!/bin/sh +if [ -n "$nv.boot.default" ]; then + exit +fi + if [ -f /mnt/sd/zImage ]; then global.boot.default=sd-card-linux elif [ -f /mnt/sd/android ]; then diff --git a/arch/arm/boards/at91sam9m10ihd/env/config b/arch/arm/boards/at91sam9m10ihd/env/config deleted file mode 100644 index db2713c..0000000 --- a/arch/arm/boards/at91sam9m10ihd/env/config +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# change network settings in /env/network/eth0 -# change mtd partition settings and automountpoints in /env/init/* - -# set to false if you do not want to have colors -global.allow_color=true - -# user (used for network filenames) -global.user=none - -# timeout in seconds before the default boot entry is started -global.autoboot_timeout=3 - -# default boot entry (one of /env/boot/*) -global.boot.default=android - -# base bootargs -#global.linux.bootargs.base="console=ttyS0,115200" diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/config-board b/arch/arm/boards/at91sam9m10ihd/env/init/config-board deleted file mode 100644 index 32c1071..0000000 --- a/arch/arm/boards/at91sam9m10ihd/env/init/config-board +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.hostname=at91sam9m10ihd -global.linux.bootargs.base="console=ttyS0,115200" -global.boot.default=android diff --git a/arch/arm/boards/at91sam9m10ihd/env/nv/boot.default b/arch/arm/boards/at91sam9m10ihd/env/nv/boot.default new file mode 100644 index 0000000..7473a25 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/nv/boot.default @@ -0,0 +1 @@ +android diff --git a/arch/arm/boards/at91sam9m10ihd/env/nv/hostname b/arch/arm/boards/at91sam9m10ihd/env/nv/hostname new file mode 100644 index 0000000..9361c5a --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/nv/hostname @@ -0,0 +1 @@ +at91sam9m10ihd diff --git a/arch/arm/boards/at91sam9m10ihd/env/nv/linux.bootargs.base b/arch/arm/boards/at91sam9m10ihd/env/nv/linux.bootargs.base new file mode 100644 index 0000000..476b1fb --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttyS0,115200 diff --git a/arch/arm/boards/avnet-zedboard/env/init/config-board b/arch/arm/boards/avnet-zedboard/env/init/config-board deleted file mode 100644 index f3032a4..0000000 --- a/arch/arm/boards/avnet-zedboard/env/init/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttyPS1,115200" diff --git a/arch/arm/boards/avnet-zedboard/env/init/nv/linux.bootargs.base b/arch/arm/boards/avnet-zedboard/env/init/nv/linux.bootargs.base new file mode 100644 index 0000000..6c9f9da --- /dev/null +++ b/arch/arm/boards/avnet-zedboard/env/init/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttyPS1,115200 diff --git a/arch/arm/boards/beagle/env/config-board b/arch/arm/boards/beagle/env/config-board deleted file mode 100644 index dcabf4c..0000000 --- a/arch/arm/boards/beagle/env/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttyO2,115200" diff --git a/arch/arm/boards/beagle/env/nv/linux.bootargs.base b/arch/arm/boards/beagle/env/nv/linux.bootargs.base new file mode 100644 index 0000000..5fef726 --- /dev/null +++ b/arch/arm/boards/beagle/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttyO2,115200 diff --git a/arch/arm/boards/ccxmx51/env/config-board b/arch/arm/boards/ccxmx51/env/config-board deleted file mode 100644 index 1405344..0000000 --- a/arch/arm/boards/ccxmx51/env/config-board +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Timeout in seconds before the default boot entry is started -global.autoboot_timeout=2 - -# Default boot entry (one of /env/boot/*) -global.boot.default=nand - -# Board bootargs -global.linux.bootargs.base="earlyprintk console=ttymxc0,115200n8" diff --git a/arch/arm/boards/ccxmx51/env/nv/autoboot_timeout b/arch/arm/boards/ccxmx51/env/nv/autoboot_timeout new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/arch/arm/boards/ccxmx51/env/nv/autoboot_timeout @@ -0,0 +1 @@ +2 diff --git a/arch/arm/boards/ccxmx51/env/nv/boot.default b/arch/arm/boards/ccxmx51/env/nv/boot.default new file mode 100644 index 0000000..026a25c --- /dev/null +++ b/arch/arm/boards/ccxmx51/env/nv/boot.default @@ -0,0 +1 @@ +nand diff --git a/arch/arm/boards/ccxmx51/env/nv/linux.bootargs.base b/arch/arm/boards/ccxmx51/env/nv/linux.bootargs.base new file mode 100644 index 0000000..d83eb94 --- /dev/null +++ b/arch/arm/boards/ccxmx51/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +earlyprintk console=ttymxc0,115200n8 diff --git a/arch/arm/boards/clep7212/env/config-board b/arch/arm/boards/clep7212/env/config-board deleted file mode 100644 index f7a8f60..0000000 --- a/arch/arm/boards/clep7212/env/config-board +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -# Timeout in seconds before the default boot entry is started -global.autoboot_timeout=2 - -# Default boot entry (one of /env/boot/*) -if [ -e /dev/nor0 ]; then - global.boot.default=nor -fi - -# Board bootargs -global.linux.bootargs.base="earlyprintk console=ttyCL0,57600n8" diff --git a/arch/arm/boards/clep7212/env/init/bootsource b/arch/arm/boards/clep7212/env/init/bootsource new file mode 100644 index 0000000..2f09c0c --- /dev/null +++ b/arch/arm/boards/clep7212/env/init/bootsource @@ -0,0 +1,9 @@ +#!/bin/sh + +if [ -n "$nv.boot.default" ]; then + exit +fi + +if [ -e /dev/nor0 ]; then + global.boot.default=nor +fi diff --git a/arch/arm/boards/clep7212/env/nv/autoboot_timeout b/arch/arm/boards/clep7212/env/nv/autoboot_timeout new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/arch/arm/boards/clep7212/env/nv/autoboot_timeout @@ -0,0 +1 @@ +2 diff --git a/arch/arm/boards/clep7212/env/nv/linux.bootargs.base b/arch/arm/boards/clep7212/env/nv/linux.bootargs.base new file mode 100644 index 0000000..77ea2ec --- /dev/null +++ b/arch/arm/boards/clep7212/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +earlyprintk console=ttyCL0,57600n8 diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/config-board b/arch/arm/boards/crystalfontz-cfa10036/env/config-board deleted file mode 100644 index fff4caa..0000000 --- a/arch/arm/boards/crystalfontz-cfa10036/env/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttyAMA0,115200" diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/init/general b/arch/arm/boards/crystalfontz-cfa10036/env/init/general deleted file mode 100644 index 5cb3a75..0000000 --- a/arch/arm/boards/crystalfontz-cfa10036/env/init/general +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "general config settings" - exit -fi - -# timeout in seconds before the default boot entry is started -global.autoboot_timeout=3 - -# default boot entry (one of /env/boot/*) -global.boot.default=mmc-ext3 diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/nv/boot.default b/arch/arm/boards/crystalfontz-cfa10036/env/nv/boot.default new file mode 100644 index 0000000..1bbb823 --- /dev/null +++ b/arch/arm/boards/crystalfontz-cfa10036/env/nv/boot.default @@ -0,0 +1 @@ +mmc-ext3 diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/nv/linux.bootargs.base b/arch/arm/boards/crystalfontz-cfa10036/env/nv/linux.bootargs.base new file mode 100644 index 0000000..5b56caf --- /dev/null +++ b/arch/arm/boards/crystalfontz-cfa10036/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttyAMA0,115200 diff --git a/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/config b/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/config deleted file mode 100644 index c63c6a1..0000000 --- a/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/config +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -# change network settings in /env/network/eth0 -# change mtd partition settings and automountpoints in /env/init/* - -#global.hostname= - -# set to false if you do not want to have colors -global.allow_color=true - -# user (used for network filenames) -global.user=none - -# timeout in seconds before the default boot entry is started -global.autoboot_timeout=1 - -# default boot entry (one of /env/boot/*) -# (if not overwritten here, the bootdevice barebox comes from -# is used) -#global.boot.default=net - -# base bootargs -global.linux.bootargs.base="console=tty1" - -# suitable for 800MHz -global linux.bootargs.lpj="lpj=3997696" - -# speed up booting by being more quiet -global linux.bootargs.quiet="quiet" diff --git a/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/bootsource b/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/bootsource index 380e855..eb98a3c 100644 --- a/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/bootsource +++ b/arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/init/bootsource @@ -1,5 +1,9 @@ #!/bin/sh +if [ -n "$nv.boot.default" ]; then + exit +fi + # by default pick kernel from MMC card if booting from # it, otherwise default to boot from internal harddisk diff --git a/arch/arm/boards/efika-mx-smartbook/env/nv/autoboot_timeout b/arch/arm/boards/efika-mx-smartbook/env/nv/autoboot_timeout new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/arch/arm/boards/efika-mx-smartbook/env/nv/autoboot_timeout @@ -0,0 +1 @@ +1 diff --git a/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.base b/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.base new file mode 100644 index 0000000..04415e6 --- /dev/null +++ b/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=tty1 diff --git a/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.lpj b/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.lpj new file mode 100644 index 0000000..e5c753e --- /dev/null +++ b/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.lpj @@ -0,0 +1 @@ +lpj=3997696 diff --git a/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.quiet b/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.quiet new file mode 100644 index 0000000..2448b2c --- /dev/null +++ b/arch/arm/boards/efika-mx-smartbook/env/nv/linux.bootargs.quiet @@ -0,0 +1 @@ +quiet diff --git a/arch/arm/boards/embedsky-e9/defaultenv-e9/config-board b/arch/arm/boards/embedsky-e9/defaultenv-e9/config-board deleted file mode 100644 index 6cba769..0000000 --- a/arch/arm/boards/embedsky-e9/defaultenv-e9/config-board +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.hostname=e9 -global.boot.default=$bootsource$bootsource_instance diff --git a/arch/arm/boards/embedsky-e9/defaultenv-e9/init/bootsource b/arch/arm/boards/embedsky-e9/defaultenv-e9/init/bootsource new file mode 100644 index 0000000..42a0c5c --- /dev/null +++ b/arch/arm/boards/embedsky-e9/defaultenv-e9/init/bootsource @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ -n "$nv.boot.default" ]; then + exit +fi + +global.boot.default=$bootsource$bootsource_instance diff --git a/arch/arm/boards/embedsky-e9/defaultenv-e9/nv/hostname b/arch/arm/boards/embedsky-e9/defaultenv-e9/nv/hostname new file mode 100644 index 0000000..0c1945a --- /dev/null +++ b/arch/arm/boards/embedsky-e9/defaultenv-e9/nv/hostname @@ -0,0 +1 @@ +e9 diff --git a/arch/arm/boards/gk802/env/config-board b/arch/arm/boards/gk802/env/config-board deleted file mode 100644 index e25a419..0000000 --- a/arch/arm/boards/gk802/env/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttymxc3,115200" diff --git a/arch/arm/boards/guf-vincell/env/init/config-board b/arch/arm/boards/guf-vincell/env/init/config-board deleted file mode 100644 index 77e9fc8..0000000 --- a/arch/arm/boards/guf-vincell/env/init/config-board +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.hostname=vincell -global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/guf-vincell/env/init/nv/hostname b/arch/arm/boards/guf-vincell/env/init/nv/hostname new file mode 100644 index 0000000..922106e --- /dev/null +++ b/arch/arm/boards/guf-vincell/env/init/nv/hostname @@ -0,0 +1 @@ +vincell diff --git a/arch/arm/boards/guf-vincell/env/init/nv/linux.bootargs.base b/arch/arm/boards/guf-vincell/env/init/nv/linux.bootargs.base new file mode 100644 index 0000000..d775310 --- /dev/null +++ b/arch/arm/boards/guf-vincell/env/init/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttymxc0,115200 diff --git a/arch/arm/boards/highbank/env/config-board b/arch/arm/boards/highbank/env/config-board deleted file mode 100644 index da8fcf6..0000000 --- a/arch/arm/boards/highbank/env/config-board +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.allow_color=true -global.autoboot_timeout=3 -global.bootm.oftree="/dev/dtb" -global.linux.bootargs.base="console=ttyAMA0,115200n8 CONSOLE=/dev/ttyAMA0" -global.boot.default=/env/boot.d diff --git a/arch/arm/boards/highbank/env/nv/boot.default b/arch/arm/boards/highbank/env/nv/boot.default new file mode 100644 index 0000000..c47e1b2 --- /dev/null +++ b/arch/arm/boards/highbank/env/nv/boot.default @@ -0,0 +1 @@ +/env/boot.d diff --git a/arch/arm/boards/highbank/env/nv/bootargs.base b/arch/arm/boards/highbank/env/nv/bootargs.base new file mode 100644 index 0000000..826debe --- /dev/null +++ b/arch/arm/boards/highbank/env/nv/bootargs.base @@ -0,0 +1 @@ +console=ttyAMA0,115200n8 CONSOLE=/dev/ttyAMA0 diff --git a/arch/arm/boards/highbank/env/nv/bootm.oftree b/arch/arm/boards/highbank/env/nv/bootm.oftree new file mode 100644 index 0000000..c373173 --- /dev/null +++ b/arch/arm/boards/highbank/env/nv/bootm.oftree @@ -0,0 +1 @@ +/dev/dtb diff --git a/arch/arm/boards/mx31moboard/env/config-board b/arch/arm/boards/mx31moboard/env/config-board deleted file mode 100644 index f67b333..0000000 --- a/arch/arm/boards/mx31moboard/env/config-board +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.boot.default="usbmsd sd nor" -global.linux.bootargs.base="console=ttymxc0,921600" diff --git a/arch/arm/boards/mx31moboard/env/nv/boot.default b/arch/arm/boards/mx31moboard/env/nv/boot.default new file mode 100644 index 0000000..7957ab3 --- /dev/null +++ b/arch/arm/boards/mx31moboard/env/nv/boot.default @@ -0,0 +1 @@ +usbmsd sd nor diff --git a/arch/arm/boards/mx31moboard/env/nv/linux.bootargs.base b/arch/arm/boards/mx31moboard/env/nv/linux.bootargs.base new file mode 100644 index 0000000..84e488d --- /dev/null +++ b/arch/arm/boards/mx31moboard/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttymxc0,921600 diff --git a/arch/arm/boards/panda/env/config-board b/arch/arm/boards/panda/env/config-board deleted file mode 100644 index dcabf4c..0000000 --- a/arch/arm/boards/panda/env/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttyO2,115200" diff --git a/arch/arm/boards/panda/env/nv/linux.bootargs.base b/arch/arm/boards/panda/env/nv/linux.bootargs.base new file mode 100644 index 0000000..5fef726 --- /dev/null +++ b/arch/arm/boards/panda/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttyO2,115200 diff --git a/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/config-board b/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/config-board deleted file mode 100644 index 4d7b37c..0000000 --- a/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/config-board +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.boot.default=nand - -global.hostname=phyCARD-i.MX6 -global.linux.bootargs.base="console=ttymxc2,115200" diff --git a/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/boot.default b/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/boot.default new file mode 100644 index 0000000..026a25c --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/boot.default @@ -0,0 +1 @@ +nand diff --git a/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/bootargs.base b/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/bootargs.base new file mode 100644 index 0000000..6b62c99 --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/bootargs.base @@ -0,0 +1 @@ +console=ttymxc2,115200 diff --git a/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/hostname b/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/hostname new file mode 100644 index 0000000..47b16cc --- /dev/null +++ b/arch/arm/boards/phytec-phycard-imx6/defaultenv-phycard-imx6/nv/hostname @@ -0,0 +1 @@ +phyCARD-i.MX6 diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/config-board b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/config-board deleted file mode 100644 index a492ed1..0000000 --- a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/config-board +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.hostname=pcm051 -global.linux.bootargs.base="console=ttyO0,115200" - -if [ $bootsource = mmc ]; then - global.boot.default="mmc nand spi net" -elif [ $boosource = nand ]; then - global.boot.default="nand spi mmc net" -elif [ $boosource = spi ]; then - global.boot.default="spi nand mmc net" -elif [ $boosource = net ]; then - global.boot.default="net nand spi mmc" -fi diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/init/bootsource b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/init/bootsource new file mode 100644 index 0000000..76d1f9b --- /dev/null +++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/init/bootsource @@ -0,0 +1,15 @@ +#!/bin/sh + +if [ -n "$nv.boot.default" ]; then + exit +fi + +if [ $bootsource = mmc ]; then + global.boot.default="mmc nand spi net" +elif [ $boosource = nand ]; then + global.boot.default="nand spi mmc net" +elif [ $boosource = spi ]; then + global.boot.default="spi nand mmc net" +elif [ $boosource = net ]; then + global.boot.default="net nand spi mmc" +fi diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/init/init-usbserial b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/init/init-usbserial new file mode 100644 index 0000000..a154fd1 --- /dev/null +++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/init/init-usbserial @@ -0,0 +1,4 @@ +#!/bin/sh + +#otg1.mode=peripheral +usbgadget -a -A /dev/nand0.kernel.bb(kernel) diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/nv/bootargs.base b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/nv/bootargs.base new file mode 100644 index 0000000..d7b01a1 --- /dev/null +++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/nv/bootargs.base @@ -0,0 +1 @@ +console=ttyO0,115200 diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/nv/hostname b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/nv/hostname new file mode 100644 index 0000000..988ab6d --- /dev/null +++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/nv/hostname @@ -0,0 +1 @@ +pcm051 diff --git a/arch/arm/boards/phytec-phycore-imx31/env/config-board b/arch/arm/boards/phytec-phycore-imx31/env/config-board deleted file mode 100644 index e8e8378..0000000 --- a/arch/arm/boards/phytec-phycore-imx31/env/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/phytec-phycore-imx31/env/nv/linux.bootargs.base b/arch/arm/boards/phytec-phycore-imx31/env/nv/linux.bootargs.base new file mode 100644 index 0000000..d775310 --- /dev/null +++ b/arch/arm/boards/phytec-phycore-imx31/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttymxc0,115200 diff --git a/arch/arm/boards/phytec-phycore-imx35/env/config-board b/arch/arm/boards/phytec-phycore-imx35/env/config-board deleted file mode 100644 index e8e8378..0000000 --- a/arch/arm/boards/phytec-phycore-imx35/env/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/phytec-phycore-imx35/env/nv/linux.bootargs.base b/arch/arm/boards/phytec-phycore-imx35/env/nv/linux.bootargs.base new file mode 100644 index 0000000..d775310 --- /dev/null +++ b/arch/arm/boards/phytec-phycore-imx35/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttymxc0,115200 diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board deleted file mode 100644 index b620ac1..0000000 --- a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.hostname=pfla03 -global.linux.bootargs.base="console=ttyO0,115200" - -if [ $bootsource = mmc ]; then - global.boot.default="mmc nand spi net" -elif [ $boosource = nand ]; then - global.boot.default="nand spi mmc net" -elif [ $boosource = spi ]; then - global.boot.default="spi nand mmc net" -elif [ $boosource = net ]; then - global.boot.default="net nand spi mmc" -fi diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/init/bootsource b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/init/bootsource new file mode 100644 index 0000000..76d1f9b --- /dev/null +++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/init/bootsource @@ -0,0 +1,15 @@ +#!/bin/sh + +if [ -n "$nv.boot.default" ]; then + exit +fi + +if [ $bootsource = mmc ]; then + global.boot.default="mmc nand spi net" +elif [ $boosource = nand ]; then + global.boot.default="nand spi mmc net" +elif [ $boosource = spi ]; then + global.boot.default="spi nand mmc net" +elif [ $boosource = net ]; then + global.boot.default="net nand spi mmc" +fi diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/nv/hostname b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/nv/hostname new file mode 100644 index 0000000..09c5821 --- /dev/null +++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/nv/hostname @@ -0,0 +1 @@ +pfla03 diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/nv/linux.bootargs.base b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/nv/linux.bootargs.base new file mode 100644 index 0000000..d7b01a1 --- /dev/null +++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttyO0,115200 diff --git a/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/config-board b/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/config-board deleted file mode 100644 index b40a4de..0000000 --- a/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/config-board +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.boot.default=nand - -global.hostname=phyFLEX-i.MX6 -global.linux.bootargs.base="console=ttymxc3,115200" diff --git a/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/boot.default b/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/boot.default new file mode 100644 index 0000000..026a25c --- /dev/null +++ b/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/boot.default @@ -0,0 +1 @@ +nand diff --git a/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/hostname b/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/hostname new file mode 100644 index 0000000..192f6b4 --- /dev/null +++ b/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/hostname @@ -0,0 +1 @@ +phyFLEX-i.MX6 diff --git a/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/linux.bootargs.base b/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/linux.bootargs.base new file mode 100644 index 0000000..c61c603 --- /dev/null +++ b/arch/arm/boards/phytec-phyflex-imx6/defaultenv-phyflex-imx6/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttymxc3,115200 diff --git a/arch/arm/boards/radxa-rock/env/config-board b/arch/arm/boards/radxa-rock/env/config-board deleted file mode 100644 index d986e30..0000000 --- a/arch/arm/boards/radxa-rock/env/config-board +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.linux.bootargs.base="console=ttyS2,115200" \ No newline at end of file diff --git a/arch/arm/boards/radxa-rock/env/nv/linux.bootargs.base b/arch/arm/boards/radxa-rock/env/nv/linux.bootargs.base new file mode 100644 index 0000000..37a03fd --- /dev/null +++ b/arch/arm/boards/radxa-rock/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +console=ttyS2,115200 diff --git a/arch/arm/boards/telit-evk-pro3/env/config-board b/arch/arm/boards/telit-evk-pro3/env/config-board deleted file mode 100644 index 741b902..0000000 --- a/arch/arm/boards/telit-evk-pro3/env/config-board +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# board defaults, do not change in running system. Change /env/config -# instead - -global.hostname=evk-pro3 -global.linux.bootargs.base="console=ttyS0,115200" -global.boot.default=nand-ubi diff --git a/arch/arm/boards/telit-evk-pro3/env/nv/boot.default b/arch/arm/boards/telit-evk-pro3/env/nv/boot.default new file mode 100644 index 0000000..d9dfbbc --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/env/nv/boot.default @@ -0,0 +1 @@ +nand-ubi diff --git a/arch/arm/boards/telit-evk-pro3/env/nv/bootargs.base b/arch/arm/boards/telit-evk-pro3/env/nv/bootargs.base new file mode 100644 index 0000000..476b1fb --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/env/nv/bootargs.base @@ -0,0 +1 @@ +console=ttyS0,115200 diff --git a/arch/arm/boards/telit-evk-pro3/env/nv/hostname b/arch/arm/boards/telit-evk-pro3/env/nv/hostname new file mode 100644 index 0000000..92941fa --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/env/nv/hostname @@ -0,0 +1 @@ +evk-pro3 diff --git a/commands/Kconfig b/commands/Kconfig index 52ba8b3..2a73bf1 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -674,6 +674,20 @@ menu "Environment" +config CMD_NV + select GLOBALVAR + tristate + prompt "nv" + help + create, set or remove non volatile variables. + + Usage: nv [-r] VAR[=VALUE] + + Add a new config non volatile named VAR, optionally set to VALUE. + + Options: + -r remove a non volatile variable + config CMD_EXPORT depends on ENVIRONMENT_VARIABLES tristate @@ -685,6 +699,13 @@ Export an environment variable to subsequently executed scripts. +config CMD_DEFAULTENV + tristate + select ENV_HANDLING + prompt "defaultenv" + help + restore environment from default environment + config CMD_GLOBAL select GLOBALVAR tristate diff --git a/commands/Makefile b/commands/Makefile index be17496..99a65d4 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -107,3 +107,5 @@ obj-$(CONFIG_CMD_USBGADGET) += usbgadget.o obj-$(CONFIG_CMD_FIRMWARELOAD) += firmwareload.o obj-$(CONFIG_CMD_CMP) += cmp.o +obj-$(CONFIG_CMD_NV) += nv.o +obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o diff --git a/commands/cp.c b/commands/cp.c index af7a3d4..4f1c068 100644 --- a/commands/cp.c +++ b/commands/cp.c @@ -39,14 +39,17 @@ int last_is_dir = 0; int i; int opt; - int verbose = 0; + int verbose = 0, recursive = 0; int argc_min; - while ((opt = getopt(argc, argv, "v")) > 0) { + while ((opt = getopt(argc, argv, "vr")) > 0) { switch (opt) { case 'v': verbose = 1; break; + case 'r': + recursive = 1; + break; } } @@ -60,24 +63,31 @@ last_is_dir = 1; } - if (argc > argc_min && !last_is_dir) { + if (((recursive && argc - optind > 2) || (argc > argc_min)) && !last_is_dir) { printf("cp: target `%s' is not a directory\n", argv[argc - 1]); return 1; } + if (recursive && argc - optind == 2 && !last_is_dir) { + ret = make_directory(argv[argc - 1]); + if (ret) + goto out; + } + for (i = optind; i < argc - 1; i++) { - if (last_is_dir) { - char *dst; - dst = concat_path_file(argv[argc - 1], basename(argv[i])); + char *dst; + dst = concat_path_file(argv[argc - 1], basename(argv[i])); + + if (recursive) + ret = copy_recursive(argv[i], dst); + else if (last_is_dir) ret = copy_file(argv[i], dst, verbose); - free(dst); - if (ret) - goto out; - } else { + else ret = copy_file(argv[i], argv[argc - 1], verbose); - if (ret) - goto out; - } + + free(dst); + if (ret) + goto out; } ret = 0; diff --git a/commands/defaultenv.c b/commands/defaultenv.c new file mode 100644 index 0000000..bae2d78 --- /dev/null +++ b/commands/defaultenv.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014 Sascha Hauer , Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int do_defaultenv(int argc, char *argv[]) +{ + char *dirname; + int opt, ret; + char *restorepath = "/"; + char *from, *to; + int restore = 0, scrub = 0; + + while ((opt = getopt(argc, argv, "p:rs")) > 0) { + switch (opt) { + case 'r': + restore = 1; + break; + case 'p': + restorepath = optarg; + break; + case 's': + scrub = 1; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (!restore || argc != optind) + return COMMAND_ERROR_USAGE; + + dirname = "/env"; + + make_directory(dirname); + + ret = defaultenv_load("/.defaultenv", 0); + if (ret) + return ret; + + from = asprintf("/.defaultenv/%s", restorepath); + to = asprintf("%s/%s", dirname, restorepath); + + printf("Restoring %s from default environment\n", restorepath); + + if (scrub) + unlink_recursive(to, NULL); + + ret = copy_recursive(from, to); + free(from); + free(to); + + nvvar_load(); + + unlink_recursive("/.defaultenv", NULL); + + return ret; +} + +BAREBOX_CMD_HELP_START(defaultenv) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT("-r", "restore default environment") +BAREBOX_CMD_HELP_OPT("-s", "scrub, remove files not in default environment") +BAREBOX_CMD_HELP_OPT("-p ", "limit to ") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(defaultenv) + .cmd = do_defaultenv, + BAREBOX_CMD_DESC("Restore environment from default environment") + BAREBOX_CMD_OPTS("[-rs] [-p ]") + BAREBOX_CMD_GROUP(CMD_GRP_ENV) + BAREBOX_CMD_HELP(cmd_defaultenv_help) +BAREBOX_CMD_END diff --git a/commands/global.c b/commands/global.c index f14df38..581913d 100644 --- a/commands/global.c +++ b/commands/global.c @@ -37,6 +37,11 @@ } } + if (argc == optind) { + globalvar_print(); + return 0; + } + argc -= optind; argv += optind; diff --git a/commands/loadenv.c b/commands/loadenv.c index 8b15af4..91ce5e7 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -27,12 +27,13 @@ #include #include #include +#include static int do_loadenv(int argc, char *argv[]) { char *filename = NULL, *dirname; unsigned flags = 0; - int opt; + int opt, ret; int scrub = 0; int defaultenv = 0; @@ -97,9 +98,13 @@ printf("loading environment from %s\n", defaultenv ? "defaultenv" : filename); if (defaultenv) - return defaultenv_load(dirname, flags); + ret = defaultenv_load(dirname, flags); else - return envfs_load(filename, dirname, flags); + ret = envfs_load(filename, dirname, flags); + + nvvar_load(); + + return ret; } BAREBOX_CMD_HELP_START(loadenv) diff --git a/commands/magicvar.c b/commands/magicvar.c index cf1fe45..6737eb5 100644 --- a/commands/magicvar.c +++ b/commands/magicvar.c @@ -3,34 +3,118 @@ #include #include #include +#include + +static LIST_HEAD(magicvars); + +struct magicvar_dyn { + char *name; + char *description; + struct list_head list; +}; + +static void magicvar_print_one(struct magicvar_dyn *md, int verbose) +{ + printf("%-32s %s\n", md->name, md->description); + + if (verbose) { + const char *val = getenv(md->name); + if (val && strlen(val)) + printf(" %s\n", val); + } +} + +struct magicvar_dyn *magicvar_find(const char *name) +{ + struct magicvar_dyn *md; + + list_for_each_entry(md, &magicvars, list) + if (!strcmp(md->name, name)) + return md; + + return NULL; +} + +static void magicvar_remove(struct magicvar_dyn *md) +{ + free(md->name); + free(md->description); + list_del(&md->list); + free(md); +} + +static int compare(struct list_head *a, struct list_head *b) +{ + char *na = (char*)list_entry(a, struct magicvar_dyn, list)->name; + char *nb = (char*)list_entry(b, struct magicvar_dyn, list)->name; + + return strcmp(na, nb); +} + +static int magicvar_add(const char *name, const char *description) +{ + struct magicvar_dyn *md; + + md = magicvar_find(name); + if (md) + magicvar_remove(md); + + md = xzalloc(sizeof(*md)); + md->name = xstrdup(name); + md->description = xstrdup(description); + + list_add_sort(&md->list, &magicvars, compare); + + return 0; +} + +static void magicvar_build(void) +{ + static int first = 1; + struct magicvar *m; + + if (!first) + return; + + for (m = &__barebox_magicvar_start; + m != &__barebox_magicvar_end; + m++) + magicvar_add(m->name, m->description); + + first = 0; +} static int do_magicvar(int argc, char *argv[]) { - struct magicvar *m; + struct magicvar_dyn *md; int opt; - int verbose = 0; + int verbose = 0, add = 0; - while ((opt = getopt(argc, argv, "v")) > 0) { + magicvar_build(); + + while ((opt = getopt(argc, argv, "va")) > 0) { switch (opt) { case 'v': verbose = 1; break; + case 'a': + add = 1; + break; default: return COMMAND_ERROR_USAGE; } } - for (m = &__barebox_magicvar_start; - m != &__barebox_magicvar_end; - m++) { - printf("%-32s %s\n", m->name, m->description); - if (verbose) { - const char *val = getenv(m->name); - if (val && strlen(val)) - printf(" %s\n", val); - } + if (add) { + if (optind + 2 != argc) + return COMMAND_ERROR_USAGE; + + return magicvar_add(argv[optind], argv[optind + 1]); } + list_for_each_entry(md, &magicvars, list) + magicvar_print_one(md, verbose); + return 0; } @@ -38,12 +122,13 @@ BAREBOX_CMD_HELP_START(magicvar) BAREBOX_CMD_HELP_TEXT("Options:") BAREBOX_CMD_HELP_OPT ("-v", "verbose (list all value if there is one)") +BAREBOX_CMD_HELP_OPT ("-a ", "Add a new magicvar") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(magicvar) .cmd = do_magicvar, BAREBOX_CMD_DESC("list information about magic variables") - BAREBOX_CMD_OPTS("[-v]") + BAREBOX_CMD_OPTS("[-va]") BAREBOX_CMD_HELP(cmd_magicvar_help) BAREBOX_CMD_GROUP(CMD_GRP_ENV) BAREBOX_CMD_END diff --git a/commands/nv.c b/commands/nv.c new file mode 100644 index 0000000..8cebb85 --- /dev/null +++ b/commands/nv.c @@ -0,0 +1,84 @@ +/* + * nv.c - non volatile shell variables + * + * Copyright (c) 2014 Sascha Hauer , Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include + +static int do_nv(int argc, char *argv[]) +{ + int opt; + int do_remove = 0; + int ret; + char *value; + + while ((opt = getopt(argc, argv, "r")) > 0) { + switch (opt) { + case 'r': + do_remove = 1; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (argc == optind) { + nvvar_print(); + return 0; + } + + argc -= optind; + argv += optind; + + if (argc != 1) + return COMMAND_ERROR_USAGE; + + value = strchr(argv[0], '='); + if (value) { + *value = 0; + value++; + } + + if (do_remove) + ret = nvvar_remove(argv[0]); + else + ret = nvvar_add(argv[0], value); + + return ret; +} + +BAREBOX_CMD_HELP_START(nv) +BAREBOX_CMD_HELP_TEXT("Add a new non volatile variable named VAR, optionally set to VALUE.") +BAREBOX_CMD_HELP_TEXT("non volatile variables are persistent variables that overwrite the") +BAREBOX_CMD_HELP_TEXT("global variables of the same name. Their value is saved with") +BAREBOX_CMD_HELP_TEXT("'saveenv'.") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT("-r", "remove a non volatile variable") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(nv) + .cmd = do_nv, + BAREBOX_CMD_DESC("create or set non volatile variables") + BAREBOX_CMD_OPTS("[-r] VAR[=VALUE]") + BAREBOX_CMD_GROUP(CMD_GRP_ENV) + BAREBOX_CMD_HELP(cmd_nv_help) +BAREBOX_CMD_END diff --git a/common/Kconfig b/common/Kconfig index 5627980..7f55194 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -632,6 +632,7 @@ select CMD_BASENAME select CMD_READLINK select CMD_DIRNAME + select CMD_NV select FLEXIBLE_BOOTARGS select CMD_BOOT select NET_CMD_IFUP if NET diff --git a/common/environment.c b/common/environment.c index e55c7b7..2639411 100644 --- a/common/environment.c +++ b/common/environment.c @@ -36,19 +36,32 @@ #include #include #include +#include +#include #else # define errno_str(x) ("void") #define EXPORT_SYMBOL(x) #endif +struct envfs_entry { + char *name; + void *buf; + int size; + struct envfs_entry *next; + mode_t mode; +}; + struct action_data { - int fd; const char *base; void *writep; + struct envfs_entry *env; }; #define PAD4(x) ((x + 3) & ~3) #ifdef __BAREBOX__ + +#define TMPDIR "/.defaultenv" + static char *default_environment_path = "/dev/env0"; void default_environment_path_set(char *path) @@ -60,6 +73,21 @@ { return default_environment_path; } + +static int do_compare_file(const char *filename, const char *base) +{ + int ret; + char *cmp; + const char *relname = filename + strlen(base) + 1; + + cmp = asprintf("%s/%s", TMPDIR, relname); + ret = compare_file(cmp, filename); + + free(cmp); + + return ret; +} + #else static inline int protect(int fd, size_t count, unsigned long offset, int prot) { @@ -70,96 +98,140 @@ { return 0; } + +static int do_compare_file(const char *filename, const char *base) +{ + return 1; +} #endif -static int file_size_action(const char *filename, struct stat *statbuf, +static int file_action(const char *filename, struct stat *statbuf, void *userdata, int depth) { struct action_data *data = userdata; + struct envfs_entry *env; + int fd, ret; - data->writep += sizeof(struct envfs_inode); - data->writep += PAD4(strlen(filename) + 1 - strlen(data->base)); - data->writep += sizeof(struct envfs_inode_end); + if (!do_compare_file(filename, data->base)) + return 1; + + env = xzalloc(sizeof(*env)); + env->name = strdup(filename + strlen(data->base)); + env->size = statbuf->st_size; + + env->buf = calloc(env->size + 1, 1); + if (!env->buf) + goto out; + + env->mode = S_IRWXU | S_IRWXG | S_IRWXO; + if (S_ISLNK(statbuf->st_mode)) { - char path[PATH_MAX]; + env->size++; - memset(path, 0, PATH_MAX); - - if (readlink(filename, path, PATH_MAX - 1) < 0) { + ret = readlink(filename, env->buf, env->size); + if (ret < 0) { perror("read"); - return 0; + goto out; } - data->writep += PAD4(strlen(path) + 1); + + env->mode |= S_IFLNK; } else { - data->writep += PAD4(statbuf->st_size); + fd = open(filename, O_RDONLY); + if (fd < 0) + return fd; + + ret = read(fd, env->buf, env->size); + + close(fd); + + if (ret < env->size) { + perror("read"); + goto out; + } } + env->next = data->env; + data->env = env; +out: return 1; } -static int file_save_action(const char *filename, struct stat *statbuf, - void *userdata, int depth) +static void envfs_save_inode(struct action_data *data, struct envfs_entry *env) { - struct action_data *data = userdata; struct envfs_inode *inode; struct envfs_inode_end *inode_end; - int fd; - int namelen = strlen(filename) + 1 - strlen(data->base); + int namelen = strlen(env->name) + 1; - inode = (struct envfs_inode*)data->writep; + inode = data->writep; inode->magic = ENVFS_32(ENVFS_INODE_MAGIC); - inode->headerlen = ENVFS_32(PAD4(namelen + sizeof(struct envfs_inode_end))); + inode->headerlen = ENVFS_32(PAD4(namelen) + sizeof(struct envfs_inode_end)); + inode->size = ENVFS_32(env->size); + data->writep += sizeof(struct envfs_inode); - strcpy(data->writep, filename + strlen(data->base)); + strcpy(data->writep, env->name); data->writep += PAD4(namelen); - inode_end = (struct envfs_inode_end*)data->writep; - data->writep += sizeof(struct envfs_inode_end); + + inode_end = data->writep; inode_end->magic = ENVFS_32(ENVFS_INODE_END_MAGIC); - inode_end->mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO); + inode_end->mode = ENVFS_32(env->mode); + data->writep += sizeof(struct envfs_inode_end); - if (S_ISLNK(statbuf->st_mode)) { - char path[PATH_MAX]; - int len; + memcpy(data->writep, env->buf, env->size); + data->writep += PAD4(env->size); +} - memset(path, 0, PATH_MAX); +#ifdef __BAREBOX__ +static int file_remove_action(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + struct action_data *data = userdata; + char *envname; + struct stat s; + int ret; + struct envfs_entry *env; - if (readlink(filename, path, PATH_MAX - 1) < 0) { - perror("read"); + filename += sizeof(TMPDIR) - 1; + + envname = asprintf("%s/%s", data->base, filename); + + ret = stat(envname, &s); + if (ret) { + char *base; + + base = basename(envname); + + env = xzalloc(sizeof(*env)); + env->name = strdup(filename); + env->size = strlen(base) + 1; + + env->buf = strdup(base); + if (!env->buf) goto out; - } - len = strlen(path) + 1; - inode_end->mode |= ENVFS_32(S_IFLNK); + env->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFLNK; - memcpy(data->writep, path, len); - inode->size = ENVFS_32(len); - data->writep += PAD4(len); - debug("handling symlink %s size %d namelen %d headerlen %d\n", - filename + strlen(data->base), - len, namelen, ENVFS_32(inode->headerlen)); - } else { - debug("handling file %s size %lld namelen %d headerlen %d\n", - filename + strlen(data->base), - statbuf->st_size, namelen, ENVFS_32(inode->headerlen)); - - inode->size = ENVFS_32(statbuf->st_size); - fd = open(filename, O_RDONLY); - if (fd < 0) { - printf("Open %s %s\n", filename, errno_str()); - goto out; - } - - if (read(fd, data->writep, statbuf->st_size) < statbuf->st_size) { - perror("read"); - goto out; - } - close(fd); - - data->writep += PAD4(statbuf->st_size); + env->next = data->env; + data->env = env; } - out: + free(envname); + + return 1; +} +#else +static int file_remove_action(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + return 0; +} +#endif + +static int dir_remove_action(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + rmdir(filename); + return 1; } @@ -177,26 +249,39 @@ { struct envfs_super *super; int envfd, size, ret; - struct action_data data; + struct action_data data = {}; void *buf = NULL, *wbuf; + struct envfs_entry *env; data.writep = NULL; data.base = dirname; +#ifdef __BAREBOX__ + defaultenv_load(TMPDIR, 0); +#endif + if (flags & ENVFS_FLAGS_FORCE_BUILT_IN) { size = 0; /* force no content */ } else { /* first pass: calculate size */ - recursive_action(dirname, ACTION_RECURSE, file_size_action, + recursive_action(dirname, ACTION_RECURSE, file_action, NULL, &data, 0); + recursive_action("/.defaultenv", ACTION_RECURSE, + file_remove_action, NULL, &data, 0); + size = 0; - size = (unsigned long)data.writep; + for (env = data.env; env; env = env->next) { + size += PAD4(env->size); + size += sizeof(struct envfs_inode); + size += PAD4(strlen(env->name) + 1); + size += sizeof(struct envfs_inode_end); + } } buf = xzalloc(size + sizeof(struct envfs_super)); data.writep = buf + sizeof(struct envfs_super); - super = (struct envfs_super *)buf; + super = buf; super->magic = ENVFS_32(ENVFS_MAGIC); super->major = ENVFS_MAJOR; super->minor = ENVFS_MINOR; @@ -205,8 +290,17 @@ if (!(flags & ENVFS_FLAGS_FORCE_BUILT_IN)) { /* second pass: copy files to buffer */ - recursive_action(dirname, ACTION_RECURSE, file_save_action, - NULL, &data, 0); + env = data.env; + while (env) { + struct envfs_entry *next = env->next; + + envfs_save_inode(&data, env); + + free(env->buf); + free(env->name); + free(env); + env = next; + } } super->crc = ENVFS_32(crc32(0, buf + sizeof(struct envfs_super), size)); @@ -264,6 +358,9 @@ close(envfd); out1: free(buf); +#ifdef __BAREBOX__ + unlink_recursive(TMPDIR, NULL); +#endif return ret; } EXPORT_SYMBOL(envfs_save); @@ -320,7 +417,7 @@ struct envfs_inode_end *inode_end; uint32_t inode_size, inode_headerlen, namelen; - inode = (struct envfs_inode *)buf; + inode = buf; buf += sizeof(struct envfs_inode); if (ENVFS_32(inode->magic) != ENVFS_INODE_MAGIC) { @@ -334,15 +431,12 @@ if (super->major < 1) inode_end = &inode_end_dummy; else - inode_end = (struct envfs_inode_end *)(buf + PAD4(namelen)); + inode_end = buf + PAD4(namelen); debug("loading %s size %d namelen %d headerlen %d\n", inode->data, inode_size, namelen, inode_headerlen); str = concat_path_file(dir, inode->data); - tmp = strdup(str); - make_directory(dirname(tmp)); - free(tmp); headerlen_full = PAD4(inode_headerlen); buf += headerlen_full; @@ -353,11 +447,19 @@ goto out; } + tmp = strdup(str); + make_directory(dirname(tmp)); + free(tmp); + if (S_ISLNK(ENVFS_32(inode_end->mode))) { debug("symlink: %s -> %s\n", str, (char*)buf); - if (symlink((char*)buf, str) < 0) { - printf("symlink: %s -> %s :", str, (char*)buf); - perror(""); + if (!strcmp(buf, basename(str))) { + unlink(str); + } else { + ret = symlink(buf, str); + if (ret < 0) + printf("symlink: %s -> %s : %s\n", + str, (char*)buf, strerror(-errno)); } free(str); } else { @@ -392,6 +494,9 @@ sizeof(struct envfs_inode); } + recursive_action(dir, ACTION_RECURSE | ACTION_DEPTHFIRST, NULL, + dir_remove_action, NULL, 0); + ret = 0; out: return ret; @@ -498,6 +603,7 @@ goto out; ret = 0; + out: close(envfd); free(buf); diff --git a/common/globalvar.c b/common/globalvar.c index c72f147..9a793ac 100644 --- a/common/globalvar.c +++ b/common/globalvar.c @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #include struct device_d global_device = { @@ -12,6 +15,11 @@ .id = DEVICE_ID_SINGLE, }; +struct device_d nv_device = { + .name = "nv", + .id = DEVICE_ID_SINGLE, +}; + int globalvar_add(const char *name, int (*set)(struct device_d *dev, struct param_d *p, const char *val), const char *(*get)(struct device_d *, struct param_d *p), @@ -25,6 +33,175 @@ return 0; } +static int nv_save(const char *name, const char *val) +{ + int fd, ret; + char *fname; + + ret = make_directory("/env/nv"); + if (ret) + return ret; + + fname = asprintf("/env/nv/%s", name); + + fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC); + + free(fname); + + if (fd < 0) + return fd; + + fprintf(fd, "%s", val); + + close(fd); + + return 0; +} + +static int nv_set(struct device_d *dev, struct param_d *p, const char *val) +{ + struct param_d *gp; + int ret; + + if (!val) + val = ""; + + gp = get_param_by_name(&global_device, p->name); + if (!gp) + return -EINVAL; + + ret = gp->set(&global_device, gp, val); + if (ret) + return ret; + + free(p->value); + p->value = xstrdup(val); + + return nv_save(p->name, val); +} + +static const char *nv_get(struct device_d *dev, struct param_d *p) +{ + return p->value ? p->value : ""; +} + +int nvvar_add(const char *name, const char *value) +{ + struct param_d *p, *gp; + int ret; + + gp = get_param_by_name(&nv_device, name); + if (gp) { + ret = dev_set_param(&global_device, name, value); + if (ret) + return ret; + + ret = dev_set_param(&nv_device, name, value); + if (ret) + return ret; + + return 0; + } + + ret = globalvar_add_simple(name, value); + if (ret && ret != -EEXIST) + return ret; + + p = dev_add_param(&nv_device, name, nv_set, nv_get, 0); + if (IS_ERR(p)) + return PTR_ERR(p); + + if (value) { + ret = dev_set_param(&global_device, name, value); + if (ret) + return ret; + } else { + value = dev_get_param(&global_device, name); + if (!value) + value = ""; + } + + p->value = xstrdup(value); + + return nv_save(p->name, value); +} + +int nvvar_remove(const char *name) +{ + struct param_d *p; + char *fname; + + p = get_param_by_name(&nv_device, name); + if (!p) + return -ENOENT; + + fname = asprintf("/env/nv/%s", p->name); + unlink(fname); + free(fname); + + list_del(&p->list); + free(p->name); + free(p); + + return 0; +} + +int nvvar_load(void) +{ + char *val; + int ret; + DIR *dir; + struct dirent *d; + + dir = opendir("/env/nv"); + if (!dir) + return -ENOENT; + + while ((d = readdir(dir))) { + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + + val = read_file_line("/env/nv/%s", d->d_name); + + pr_debug("%s: Setting \"%s\" to \"%s\"\n", + __func__, d->d_name, val); + + ret = nvvar_add(d->d_name, val); + if (ret) + pr_err("failed to create nv variable %s: %s\n", + d->d_name, strerror(-ret)); + } + + closedir(dir); + + return 0; +} + +static void device_param_print(struct device_d *dev) +{ + struct param_d *param; + + list_for_each_entry(param, &dev->parameters, list) { + const char *p = dev_get_param(dev, param->name); + const char *nv = NULL; + + if (dev != &nv_device) + nv = dev_get_param(&nv_device, param->name); + + printf("%s%s: %s\n", nv ? "* " : " ", param->name, p); + } +} + +void nvvar_print(void) +{ + device_param_print(&nv_device); +} + +void globalvar_print(void) +{ + device_param_print(&global_device); +} + /* * globalvar_get_match * @@ -87,6 +264,7 @@ static int globalvar_init(void) { register_device(&global_device); + register_device(&nv_device); globalvar_add_simple("version", UTS_RELEASE); diff --git a/common/startup.c b/common/startup.c index ceb597b..2b92efc 100644 --- a/common/startup.c +++ b/common/startup.c @@ -40,6 +40,7 @@ #include #include #include +#include extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[], __barebox_initcalls_end[]; @@ -78,17 +79,13 @@ pr_debug("initcalls done\n"); if (IS_ENABLED(CONFIG_ENV_HANDLING)) { - int ret; char *default_environment_path = default_environment_path_get(); - ret = envfs_load(default_environment_path, "/env", 0); - - if (ret && IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) { - pr_err("no valid environment found on %s. " - "Using default environment\n", - default_environment_path); + if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) defaultenv_load("/env", 0); - } + + envfs_load(default_environment_path, "/env", 0); + nvvar_load(); } if (IS_ENABLED(CONFIG_COMMAND_SUPPORT)) { diff --git a/defaultenv/defaultenv-2-base/bin/init b/defaultenv/defaultenv-2-base/bin/init index 3a0e93b..34807bc 100644 --- a/defaultenv/defaultenv-2-base/bin/init +++ b/defaultenv/defaultenv-2-base/bin/init @@ -16,9 +16,12 @@ [ -z "${global.hostname}" ] && global.hostname=generic [ -z "${global.user}" ] && global.user=none +magicvar -a global.user "username (used in network filenames)" [ -z "${global.autoboot_timeout}" ] && global.autoboot_timeout=3 +magicvar -a global.autoboot_timeout "timeout in seconds before automatic booting" [ -z "${global.boot.default}" ] && global.boot.default=net [ -z "${global.allow_color}" ] && global.allow_color=true +magicvar -a global.allow_color "Allow color on the console (boolean)" [ -z "${global.editcmd}" ] && global.editcmd=sedit [ -e /env/config-board ] && /env/config-board diff --git a/defaultenv/defaultenv-2-base/config b/defaultenv/defaultenv-2-base/config index 784ae52..49fa605 100644 --- a/defaultenv/defaultenv-2-base/config +++ b/defaultenv/defaultenv-2-base/config @@ -3,23 +3,5 @@ # change network settings in /env/network/eth0 # change mtd partition settings and automountpoints in /env/init/* -#global.hostname= - -# set to false if you do not want to have colors -#global.allow_color=true - -# user (used for network filenames) -#global.user=none - -# timeout in seconds before the default boot entry is started -#global.autoboot_timeout=3 - -# list of boot entries. These are executed in order until one -# succeeds. An entry can be: -# - a filename in /env/boot/ -# - a full path to a directory. All files in this directory are -# treated as boot files and executed in alphabetical order -#global.boot.default=net - -# base bootargs -#global.linux.bootargs.base="console=ttyS0,115200" +# The settings that used to be here are in nv variables now. +# See 'help nv', 'magicvar' diff --git a/defaultenv/defaultenv-2-base/nv/allow_color b/defaultenv/defaultenv-2-base/nv/allow_color new file mode 100644 index 0000000..f32a580 --- /dev/null +++ b/defaultenv/defaultenv-2-base/nv/allow_color @@ -0,0 +1 @@ +true \ No newline at end of file diff --git a/defaultenv/defaultenv-2-base/nv/autoboot_timeout b/defaultenv/defaultenv-2-base/nv/autoboot_timeout new file mode 100644 index 0000000..e440e5c --- /dev/null +++ b/defaultenv/defaultenv-2-base/nv/autoboot_timeout @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/defaultenv/defaultenv-2-base/nv/user b/defaultenv/defaultenv-2-base/nv/user new file mode 100644 index 0000000..c86c3f3 --- /dev/null +++ b/defaultenv/defaultenv-2-base/nv/user @@ -0,0 +1 @@ +none \ No newline at end of file diff --git a/include/globalvar.h b/include/globalvar.h index 456e8cd..8b2caf1 100644 --- a/include/globalvar.h +++ b/include/globalvar.h @@ -72,6 +72,13 @@ return 0; } + +int nvvar_load(void); +void nvvar_print(void); +int nvvar_add(const char *name, const char *value); +int nvvar_remove(const char *name); +void globalvar_print(void); + #else static inline int globalvar_add_simple(const char *name, const char *value) { @@ -116,6 +123,12 @@ } static inline void globalvar_set_match(const char *match, const char *val) {} + +static inline int nvvar_load(void) +{ + return 0; +} + #endif #endif /* __GLOBALVAR_H */ diff --git a/include/libfile.h b/include/libfile.h index 6c48ce0..d5b914a 100644 --- a/include/libfile.h +++ b/include/libfile.h @@ -15,6 +15,8 @@ int copy_file(const char *src, const char *dst, int verbose); +int copy_recursive(const char *src, const char *dst); + int compare_file(const char *f1, const char *f2); #endif /* __LIBFILE_H */ diff --git a/lib/libfile.c b/lib/libfile.c index 7ed4b93..8acff04 100644 --- a/lib/libfile.c +++ b/lib/libfile.c @@ -332,6 +332,46 @@ } EXPORT_SYMBOL(copy_file); +int copy_recursive(const char *src, const char *dst) +{ + struct stat s; + DIR *dir; + struct dirent *d; + int ret; + + ret = stat(src, &s); + if (ret) + return ret; + + if (!S_ISDIR(s.st_mode)) + return copy_file(src, dst, 0); + + ret = make_directory(dst); + if (ret) + return ret; + + dir = opendir(src); + if (!dir) + return -EIO; + + while ((d = readdir(dir))) { + char *from, *to; + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + + from = asprintf("%s/%s", src, d->d_name); + to = asprintf("%s/%s", dst, d->d_name); + ret = copy_recursive(from, to); + if (ret) + break; + free(from); + free(to); + } + closedir(dir); + + return ret; +} + /** * compare_file - Compare two files * @f1: The first file