9
0
Fork 0

Merge branch 'for-next/metadata'

Conflicts:
	arch/arm/dts/Makefile
	common/Makefile
	lib/Makefile
This commit is contained in:
Sascha Hauer 2014-08-07 06:15:16 +02:00
commit 5b7b7ee5d9
80 changed files with 1315 additions and 390 deletions

View File

@ -0,0 +1,54 @@
.. _imd:
Image MetaData (IMD)
====================
barebox images can be enriched with metadata. This is useful to get information
the board an image is compiled for and which barebox version an image contains.
There are predefined tags for:
- The build timestamp
- The barebox release version
- The model (board) the image is compiled for
- The toplevel device tree compatible properties the image can handle
Additionally there is a generic key/value tag to add information which does not
fit into the above categories, for example the memory size for boards which come
with different memory sizes which can't be automatically detected.
The informations can be extracted with the ``bareboximd`` tool which lives under
``scripts/`` in the barebox sourcecode. If enabled it is compiled for the compile
host and also for the target architecture. barebox itself has the :ref:`command_imd`
command to extract the informations. Here is an example output of the tool called
without additional options::
# imd barebox-phytec-pbab01dl-1gib.img
build: #890 Wed Jul 30 16:15:24 CEST 2014
release: 2014.07.0-00167-ge6632a9-dirty
parameter: memsize=1024
of_compatible: phytec,imx6x-pbab01 phytec,imx6dl-pfla02 fsl,imx6dl
model: Phytec phyFLEX-i.MX6 Duallite Carrier-Board
Single informations can be extracted with the ``-t <type>`` option::
# imd barebox-phytec-pbab01dl-1gib.img -t release
2014.07.0-00167-ge6632a9-dirty
Since the barebox hush does not have output redirection the barebox too has the
``-s <var>`` option to assign the output to a variable for later evaluation.
Limitations
-----------
The IMD tags are generated in the barebox binary before a SoC specific image is
generated. Some SoCs encrypt or otherwise manipulate the images in a way that the
IMD information is lost. The IMD mechanism does not work on these SoCs. A known
example is the Freescale i.MX28.
IMD and barebox_update
----------------------
The IMD informations could well be used to check if an image is suitable for updating
barebox for a particular board. Support for such a check is planned but not yet implemented.

View File

@ -27,3 +27,6 @@ barebox has been started from is registered as default (marked with a ``*``)::
available for your board. It is recommended to implement it, but you can also
update barebox manually using :ref:`command_erase` and :ref:`command_cp`
commands. The exact commands are board specific.
**NOTE** barebox images can be enriched with metadata which can be used to check
if a given image is suitable for updating barebox, see :ref:`imd`.

View File

@ -19,6 +19,7 @@ Contents:
hush
defaultenv-2
updating
imd
devicetree
pbl
multi-image

View File

@ -18,6 +18,7 @@
#include <fs.h>
#include <fcntl.h>
#include <libbb.h>
#include <libfile.h>
#include <asm/armlinux.h>
#include <of.h>

View File

@ -18,6 +18,7 @@
#include <fs.h>
#include <fcntl.h>
#include <libbb.h>
#include <libfile.h>
#include <asm/armlinux.h>
#include <of.h>

View File

@ -21,6 +21,7 @@
#include <fs.h>
#include <globalvar.h>
#include <libbb.h>
#include <libfile.h>
#include <magicvar.h>
#include <asm/armlinux.h>

View File

@ -2,6 +2,7 @@
#include <mach/esdctl.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <image-metadata.h>
extern char __dtb_imx53_qsb_start[];

View File

@ -16,6 +16,7 @@
#include <common.h>
#include <sizes.h>
#include <io.h>
#include <image-metadata.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <asm/sections.h>
@ -57,6 +58,11 @@ extern char __dtb_imx6q_phytec_pbab01_start[];
extern char __dtb_imx6dl_phytec_pbab01_start[];
extern char __dtb_imx6s_phytec_pbab01_start[];
BAREBOX_IMD_TAG_STRING(phyflex_mx6_memsize_512M, IMD_TYPE_PARAMETER, "memsize=512", 0);
BAREBOX_IMD_TAG_STRING(phyflex_mx6_memsize_1G, IMD_TYPE_PARAMETER, "memsize=1024", 0);
BAREBOX_IMD_TAG_STRING(phyflex_mx6_memsize_2G, IMD_TYPE_PARAMETER, "memsize=2048", 0);
BAREBOX_IMD_TAG_STRING(phyflex_mx6_memsize_4G, IMD_TYPE_PARAMETER, "memsize=4096", 0);
ENTRY_FUNCTION(start_phytec_pbab01_1gib, r0, r1, r2)
{
void *fdt;
@ -65,6 +71,8 @@ ENTRY_FUNCTION(start_phytec_pbab01_1gib, r0, r1, r2)
arm_setup_stack(0x00920000 - 8);
IMD_USED(phyflex_mx6_memsize_1G);
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
@ -81,6 +89,8 @@ ENTRY_FUNCTION(start_phytec_pbab01_2gib, r0, r1, r2)
arm_setup_stack(0x00920000 - 8);
IMD_USED(phyflex_mx6_memsize_2G);
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
@ -97,6 +107,8 @@ ENTRY_FUNCTION(start_phytec_pbab01_4gib, r0, r1, r2)
arm_setup_stack(0x00920000 - 8);
IMD_USED(phyflex_mx6_memsize_4G);
fdt = __dtb_imx6q_phytec_pbab01_start - get_runtime_offset();
barebox_arm_entry(0x10000000, 0xEFFFFFF8, fdt);
@ -110,6 +122,8 @@ ENTRY_FUNCTION(start_phytec_pbab01dl_1gib, r0, r1, r2)
arm_setup_stack(0x00920000 - 8);
IMD_USED(phyflex_mx6_memsize_1G);
fdt = __dtb_imx6dl_phytec_pbab01_start - get_runtime_offset();
barebox_arm_entry(0x10000000, SZ_1G, fdt);
@ -123,6 +137,8 @@ ENTRY_FUNCTION(start_phytec_pbab01s_512mb, r0, r1, r2)
arm_setup_stack(0x00920000 - 8);
IMD_USED(phyflex_mx6_memsize_512M);
fdt = __dtb_imx6s_phytec_pbab01_start - get_runtime_offset();
barebox_arm_entry(0x10000000, SZ_512M, fdt);

View File

@ -18,6 +18,7 @@
#include <fs.h>
#include <fcntl.h>
#include <libbb.h>
#include <libfile.h>
#include <asm/armlinux.h>
#include <of.h>

View File

@ -5,6 +5,7 @@
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <mach/imx5.h>
#include <image-metadata.h>
extern char __dtb_imx53_mba53_start[];
@ -34,6 +35,8 @@ static void __noreturn start_imx53_tqma53_common(void *fdt)
imx53_barebox_entry(fdt);
}
BAREBOX_IMD_TAG_STRING(tqma53_memsize_512M, IMD_TYPE_PARAMETER, "memsize=512", 0);
ENTRY_FUNCTION(start_imx53_mba53_512mib, r0, r1, r2)
{
void *fdt;
@ -42,6 +45,8 @@ ENTRY_FUNCTION(start_imx53_mba53_512mib, r0, r1, r2)
arm_setup_stack(0xf8020000 - 8);
IMD_USED(tqma53_memsize_512M);
imx53_init_lowlevel_early(800);
fdt = __dtb_imx53_mba53_start - get_runtime_offset();
@ -49,6 +54,8 @@ ENTRY_FUNCTION(start_imx53_mba53_512mib, r0, r1, r2)
start_imx53_tqma53_common(fdt);
}
BAREBOX_IMD_TAG_STRING(tqma53_memsize_1G, IMD_TYPE_PARAMETER, "memsize=1024", 0);
ENTRY_FUNCTION(start_imx53_mba53_1gib, r0, r1, r2)
{
void *fdt;
@ -57,6 +64,8 @@ ENTRY_FUNCTION(start_imx53_mba53_1gib, r0, r1, r2)
arm_setup_stack(0xf8020000 - 8);
IMD_USED(tqma53_memsize_1G);
imx53_init_lowlevel_early(800);
fdt = __dtb_imx53_mba53_start - get_runtime_offset();

View File

@ -1,95 +1,47 @@
dtb-$(CONFIG_ARCH_AM33XX) += \
am335x-bone.dtb \
am335x-boneblack.dtb \
am335x-bone-common.dtb \
am335x-phytec-phycore.dtb
dtb-$(CONFIG_ARCH_IMX25) += imx25-karo-tx25.dtb
dtb-$(CONFIG_ARCH_IMX27) += imx27-phytec-phycard-s-rdk-bb.dtb \
imx27-phytec-phycore-rdk.dtb
dtb-$(CONFIG_ARCH_IMX51) += imx51-babbage.dtb \
imx51-genesi-efika-sb.dtb
dtb-$(CONFIG_ARCH_IMX53) += imx53-mba53.dtb \
imx53-qsb.dtb \
imx53-qsrb.dtb \
imx53-voipac-bsb.dtb
dtb-$(CONFIG_ARCH_IMX6) += imx6q-gk802.dtb \
imx6dl-dfi-fs700-m60-6s.dtb \
imx6q-dfi-fs700-m60-6q.dtb \
imx6q-dmo-edmqmx6.dtb \
imx6q-sabrelite.dtb \
imx6dl-sabrelite.dtb \
imx6q-sabresd.dtb \
imx6dl-mba6x.dtb \
imx6q-mba6x.dtb \
imx6dl-phytec-pbab01.dtb \
imx6q-phytec-pbab01.dtb \
imx6s-phytec-pbab01.dtb \
imx6dl-hummingboard.dtb \
imx6q-guf-santaro.dtb \
imx6q-nitrogen6x.dtb \
imx6dl-nitrogen6x.dtb \
imx6q-udoo.dtb \
imx6q-var-custom.dtb \
imx6s-riotboard.dtb \
imx6q-phytec-pbaa03.dtb \
imx6q-embedsky-e9.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3188-radxarock.dtb
dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5_sockit.dtb \
socfpga_cyclone5_socrates.dtb
dtb-$(CONFIG_ARCH_TEGRA) += \
tegra20-colibri-iris.dtb \
tegra20-paz00.dtb \
tegra30-beaver.dtb \
tegra124-jetson-tk1.dtb
BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME))
obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o
obj-dtb-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o
pbl-$(CONFIG_MACH_BEAGLEBONE) += am335x-bone.dtb.o am335x-boneblack.dtb.o am335x-bone-common.dtb.o
pbl-$(CONFIG_MACH_DFI_FS700_M60) += imx6q-dfi-fs700-m60-6q.dtb.o imx6dl-dfi-fs700-m60-6s.dtb.o
pbl-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += imx51-genesi-efika-sb.dtb.o
pbl-$(CONFIG_MACH_EMBEDSKY_E9) += imx6q-embedsky-e9.dtb.o
pbl-$(CONFIG_MACH_EMBEST_RIOTBOARD) += imx6s-riotboard.dtb.o
pbl-$(CONFIG_MACH_FREESCALE_MX51_PDK) += imx51-babbage.dtb.o
pbl-$(CONFIG_MACH_FREESCALE_MX53_LOCO) += imx53-qsb.dtb.o imx53-qsrb.dtb.o
pbl-$(CONFIG_MACH_FREESCALE_MX53_VMX53) += imx53-voipac-bsb.dtb.o
pbl-$(CONFIG_MACH_GK802) += imx6q-gk802.dtb.o
pbl-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += kirkwood-guruplug-server-plus-bb.dtb.o
pbl-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += armada-370-mirabox-bb.dtb.o
pbl-$(CONFIG_MACH_GUF_SANTARO) += imx6q-guf-santaro.dtb.o
pbl-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += armada-xp-gp-bb.dtb.o
pbl-$(CONFIG_MACH_NITROGEN6X) += imx6q-nitrogen6x.dtb.o imx6dl-nitrogen6x.dtb.o
pbl-$(CONFIG_MACH_NVIDIA_BEAVER) += tegra30-beaver.dtb.o
pbl-$(CONFIG_MACH_NVIDIA_JETSON) += tegra124-jetson-tk1.dtb.o
pbl-$(CONFIG_MACH_PCA100) += imx27-phytec-phycard-s-rdk-bb.dtb.o
pbl-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o
pbl-$(CONFIG_MACH_PCM038) += imx27-phytec-phycore-rdk.dtb.o
pbl-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore.dtb.o
pbl-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o
pbl-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o
pbl-$(CONFIG_MACH_RADXA_ROCK) += rk3188-radxarock.dtb.o
pbl-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o
pbl-$(CONFIG_MACH_SABRELITE) += imx6q-sabrelite.dtb.o imx6dl-sabrelite.dtb.o
pbl-$(CONFIG_MACH_SABRESD) += imx6q-sabresd.dtb.o
pbl-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += socfpga_cyclone5_socrates.dtb.o
pbl-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT) += socfpga_cyclone5_sockit.dtb.o
pbl-$(CONFIG_MACH_SOLIDRUN_CUBOX) += dove-cubox-bb.dtb.o
pbl-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += imx6dl-hummingboard.dtb.o
pbl-$(CONFIG_MACH_TORADEX_COLIBRI_T20) += tegra20-colibri-iris.dtb.o
pbl-$(CONFIG_MACH_TOSHIBA_AC100) += tegra20-paz00.dtb.o
pbl-$(CONFIG_MACH_TQMA53) += imx53-mba53.dtb.o
pbl-$(CONFIG_MACH_TQMA6X) += imx6dl-mba6x.dtb.o imx6q-mba6x.dtb.o
pbl-$(CONFIG_MACH_TX25) += imx25-karo-tx25.dtb.o
pbl-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o
pbl-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o
pbl-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o
# just to build a built-in.o. Otherwise compilation fails when no devicetree is
# created.
obj-y += empty.o
.SECONDARY: $(obj)/$(BUILTIN_DTB).dtb.S
.SECONDARY: $(patsubst %,$(obj)/%.S,$(dtb-y))
targets += dtbs
targets += $(dtb-y)
extra-y += $(dtb-y)
pbl-dtb-$(CONFIG_MACH_BEAGLEBONE) += am335x-bone.dtb.o am335x-boneblack.dtb.o am335x-bone-common.dtb.o
pbl-dtb-$(CONFIG_MACH_DFI_FS700_M60) += imx6q-dfi-fs700-m60-6q.dtb.o imx6dl-dfi-fs700-m60-6s.dtb.o
pbl-dtb-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += imx51-genesi-efika-sb.dtb.o
pbl-dtb-$(CONFIG_MACH_EMBEST_RIOTBOARD) += imx6s-riotboard.dtb.o
pbl-dtb-$(CONFIG_MACH_EMBEDSKY_E9) += imx6q-embedsky-e9.dtb.o
pbl-dtb-$(CONFIG_MACH_FREESCALE_MX51_PDK) += imx51-babbage.dtb.o
pbl-dtb-$(CONFIG_MACH_FREESCALE_MX53_LOCO) += imx53-qsb.dtb.o imx53-qsrb.dtb.o
pbl-dtb-$(CONFIG_MACH_FREESCALE_MX53_VMX53) += imx53-voipac-bsb.dtb.o
pbl-dtb-$(CONFIG_MACH_GK802) += imx6q-gk802.dtb.o
pbl-dtb-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += kirkwood-guruplug-server-plus-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += armada-370-mirabox-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_GUF_SANTARO) += imx6q-guf-santaro.dtb.o
pbl-dtb-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += armada-xp-gp-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_NITROGEN6X) += imx6q-nitrogen6x.dtb.o imx6dl-nitrogen6x.dtb.o
pbl-dtb-$(CONFIG_MACH_NVIDIA_BEAVER) += tegra30-beaver.dtb.o
pbl-dtb-$(CONFIG_MACH_NVIDIA_JETSON) += tegra124-jetson-tk1.dtb.o
pbl-dtb-$(CONFIG_MACH_PCA100) += imx27-phytec-phycard-s-rdk-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o
pbl-dtb-$(CONFIG_MACH_PCM038) += imx27-phytec-phycore-rdk.dtb.o
pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore.dtb.o
pbl-dtb-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o
pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_RADXA_ROCK) += rk3188-radxarock.dtb.o
pbl-dtb-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o
pbl-dtb-$(CONFIG_MACH_SABRELITE) += imx6q-sabrelite.dtb.o imx6dl-sabrelite.dtb.o
pbl-dtb-$(CONFIG_MACH_SABRESD) += imx6q-sabresd.dtb.o
pbl-dtb-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += socfpga_cyclone5_socrates.dtb.o
pbl-dtb-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT) += socfpga_cyclone5_sockit.dtb.o
pbl-dtb-$(CONFIG_MACH_SOLIDRUN_CUBOX) += dove-cubox-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += imx6dl-hummingboard.dtb.o
pbl-dtb-$(CONFIG_MACH_TORADEX_COLIBRI_T20) += tegra20-colibri-iris.dtb.o
pbl-dtb-$(CONFIG_MACH_TOSHIBA_AC100) += tegra20-paz00.dtb.o
pbl-dtb-$(CONFIG_MACH_TQMA53) += imx53-mba53.dtb.o
pbl-dtb-$(CONFIG_MACH_TQMA6X) += imx6dl-mba6x.dtb.o imx6q-mba6x.dtb.o
pbl-dtb-$(CONFIG_MACH_TX25) += imx25-karo-tx25.dtb.o
pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o
pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o
clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts

3
arch/arm/dts/empty.c Normal file
View File

@ -0,0 +1,3 @@
static inline void empty(void)
{
}

View File

@ -75,6 +75,8 @@ SECTIONS
. = ALIGN(4);
.data : { *(.data*) }
.barebox_imd : { BAREBOX_IMD }
. = .;
__barebox_cmd_start = .;
.barebox_cmd : { BAREBOX_CMDS }

View File

@ -6,6 +6,7 @@
#include <image.h>
#include <init.h>
#include <fs.h>
#include <libfile.h>
#include <linux/list.h>
#include <xfuncs.h>
#include <malloc.h>

View File

@ -54,6 +54,8 @@ SECTIONS
. = ALIGN(4);
.rodata : { *(.rodata*) }
.barebox_imd : { BAREBOX_IMD }
_etext = .; /* End of text and rodata section */
. = ALIGN(4);

View File

@ -7,6 +7,7 @@
#include <common.h>
#include <command.h>
#include <libbb.h>
#include <libfile.h>
#include <getopt.h>
#include <fs.h>
#include <fcntl.h>

View File

@ -20,6 +20,7 @@
#include <io.h>
#include <fs.h>
#include <malloc.h>
#include <libfile.h>
#include <linux/stat.h>
#include <mach/gpmc.h>
#include <mach/generic.h>

View File

@ -5,6 +5,7 @@
#include <init.h>
#include <driver.h>
#include <linux/mtd/mtd.h>
#include <libfile.h>
#include <fs.h>
#include <fcntl.h>
#include <sizes.h>

View File

@ -1,5 +1,6 @@
#include <common.h>
#include <command.h>
#include <libfile.h>
#include <linux/stat.h>
#include <malloc.h>
#include <fs.h>

View File

@ -14,6 +14,7 @@ CONFIG_POLLER=y
CONFIG_DEBUG_INFO=y
CONFIG_LONGHELP=y
CONFIG_CMD_IOMEM=y
CONFIG_CMD_IMD=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_GO=y

View File

@ -2,14 +2,4 @@
BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME))
obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o
dtb-y += ${BUILTIN_DTB}.dtb
.SECONDARY: $(obj)/$(BUILTIN_DTB).dtb.S
.SECONDARY: $(patsubst %,$(obj)/%.S,$(dtb-y))
targets += dtbs
targets += $(dtb-y)
extra-y += $(dtb-y)
clean-files := *.dtb *.dtb.S

View File

@ -49,6 +49,8 @@ SECTIONS
. = ALIGN(4);
.data : { *(.data*) }
.barebox_imd : { BAREBOX_IMD }
. = ALIGN(4);
.got : { *(.got*) }

View File

@ -1,5 +1,6 @@
#include <boot.h>
#include <common.h>
#include <libfile.h>
#include <init.h>
#include <fs.h>
#include <errno.h>

View File

@ -44,6 +44,8 @@ SECTIONS
. = ALIGN(4);
.rodata : { *(.rodata*) }
.barebox_imd : { BAREBOX_IMD }
_etext = .; /* End of text and rodata section */
. = ALIGN(4);

View File

@ -148,6 +148,15 @@ config CMD_IOMEM
Show information about iomem/ioport usage. Pendant to
'cat /proc/iomem' and 'cat /proc/ioports' under Linux.
config CMD_IMD
tristate
prompt "imd"
select IMD
help
barebox images can have metadata in them which contains information
like the barebox version and the build time. Say yes here to get the
imd command which can extract that information from images.
config CMD_MEMINFO
tristate
prompt "meminfo"

View File

@ -100,3 +100,4 @@ obj-$(CONFIG_CMD_MENUTREE) += menutree.o
obj-$(CONFIG_CMD_2048) += 2048.o
obj-$(CONFIG_CMD_REGULATOR) += regulator.o
obj-$(CONFIG_CMD_LSPCI) += lspci.o
obj-$(CONFIG_CMD_IMD) += imd.o

View File

@ -17,6 +17,7 @@
*/
#include <common.h>
#include <command.h>
#include <libfile.h>
#include <getopt.h>
#include <malloc.h>
#include <errno.h>

View File

@ -26,6 +26,7 @@
#include <malloc.h>
#include <libgen.h>
#include <getopt.h>
#include <libfile.h>
/**
* @param[in] argc Argument count from command line

View File

@ -22,6 +22,7 @@
#include <fs.h>
#include <getopt.h>
#include <malloc.h>
#include <libfile.h>
#include <environment.h>
static int crc_from_file(const char* file, ulong *crc)

View File

@ -21,6 +21,7 @@
#include <fs.h>
#include <linux/ctype.h>
#include <fcntl.h>
#include <libfile.h>
#include <readkey.h>
#include <errno.h>
#include <xfuncs.h>

View File

@ -23,6 +23,7 @@
#include <fcntl.h>
#include <linux/stat.h>
#include <errno.h>
#include <libfile.h>
#include <malloc.h>
#include <xfuncs.h>

60
commands/imd.c Normal file
View File

@ -0,0 +1,60 @@
/*
* (C) Copyright 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 as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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 <common.h>
#include <command.h>
#include <complete.h>
#include <environment.h>
#include <image-metadata.h>
int imd_command_setenv(const char *variable_name, const char *value)
{
return setenv(variable_name, value);
}
static int do_imd(int argc, char *argv[])
{
int ret;
ret = imd_command(argc, argv);
if (ret == -ENOSYS)
return COMMAND_ERROR_USAGE;
return ret;
}
BAREBOX_CMD_HELP_START(imd)
BAREBOX_CMD_HELP_TEXT("extract metadata from barebox binary")
BAREBOX_CMD_HELP_TEXT("")
BAREBOX_CMD_HELP_TEXT("Options:")
BAREBOX_CMD_HELP_OPT ("-t <type>", "only show information of <type>")
BAREBOX_CMD_HELP_OPT ("-n <no>", "for tags with multiple strings only show string <no>")
BAREBOX_CMD_HELP_OPT ("-s VARNAME", "set variable VARNAME instead of showing information")
BAREBOX_CMD_HELP_TEXT("")
BAREBOX_CMD_HELP_TEXT("Without options all information available is printed. Valid types are:")
BAREBOX_CMD_HELP_TEXT("release, build, model, of_compatible")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(imd)
.cmd = do_imd,
BAREBOX_CMD_DESC("extract metadata from barebox binary")
BAREBOX_CMD_OPTS("[nst] FILE")
BAREBOX_CMD_GROUP(CMD_GRP_INFO)
BAREBOX_CMD_HELP(cmd_imd_help)
BAREBOX_CMD_END

View File

@ -3,6 +3,7 @@
#include <module.h>
#include <errno.h>
#include <fs.h>
#include <libfile.h>
#include <malloc.h>
static int do_insmod(int argc, char *argv[])

View File

@ -24,6 +24,7 @@
#include <environment.h>
#include <fs.h>
#include <errno.h>
#include <libfile.h>
#include <getopt.h>
#include <malloc.h>
#include <boot.h>

View File

@ -18,6 +18,7 @@
*/
#include <common.h>
#include <libfile.h>
#include <fdt.h>
#include <of.h>
#include <command.h>

View File

@ -26,6 +26,7 @@
#include <common.h>
#include <environment.h>
#include <fdt.h>
#include <libfile.h>
#include <of.h>
#include <command.h>
#include <fs.h>

View File

@ -1,6 +1,7 @@
#include <common.h>
#include <command.h>
#include <fs.h>
#include <libfile.h>
#include <malloc.h>
#include <linux/stat.h>
#include <linux/ctype.h>

View File

@ -24,6 +24,7 @@
#include <fs.h>
#include <net.h>
#include <libbb.h>
#include <libfile.h>
#define TFTP_MOUNT_PATH "/.tftp_tmp_path"

View File

@ -40,6 +40,7 @@
#include <malloc.h>
#include <ioctl.h>
#include <libbb.h>
#include <libfile.h>
#include <linux/mtd/mtd.h>
#include <linux/kernel.h>
#include <linux/stat.h>

View File

@ -7,6 +7,7 @@
#include <malloc.h>
#include <errno.h>
#include <getopt.h>
#include <libfile.h>
static int uimage_fd;

View File

@ -465,6 +465,13 @@ config BLSPEC
on a device and it allows the Operating System to install / update
kernels.
config IMD
bool "barebox metadata support"
config IMD_TARGET
bool "build bareboximd target tool"
depends on IMD
config KERNEL_INSTALL_TARGET
bool
depends on !SANDBOX

View File

@ -46,6 +46,8 @@ obj-$(CONFIG_UIMAGE) += image.o uimage.o
obj-$(CONFIG_MENUTREE) += menutree.o
obj-$(CONFIG_EFI_GUID) += efi-guid.o
obj-$(CONFIG_EFI_DEVICEPATH) += efi-devicepath.o
lwl-$(CONFIG_IMD) += imd-barebox.o
obj-$(CONFIG_IMD) += imd.o
quiet_cmd_pwd_h = PWDH $@
ifdef CONFIG_PASSWORD

View File

@ -21,6 +21,7 @@
#include <malloc.h>
#include <block.h>
#include <fcntl.h>
#include <libfile.h>
#include <libbb.h>
#include <init.h>
#include <boot.h>

View File

@ -16,6 +16,7 @@
#include <fs.h>
#include <malloc.h>
#include <memory.h>
#include <libfile.h>
#include <globalvar.h>
#include <init.h>

View File

@ -118,6 +118,7 @@
#include <libbb.h>
#include <glob.h>
#include <getopt.h>
#include <libfile.h>
#include <libbb.h>
#include <magicvar.h>
#include <linux/list.h>

25
common/imd-barebox.c Normal file
View File

@ -0,0 +1,25 @@
#include <common.h>
#include <image-metadata.h>
#include <generated/compile.h>
#include <generated/utsrelease.h>
/*
* Mark a imd entry as used so that the linker cannot
* throw it away.
*/
void imd_used(const void *used)
{
}
struct imd_header imd_start_header
__BAREBOX_IMD_SECTION(.barebox_imd_start) = {
.type = cpu_to_le32(IMD_TYPE_START),
};
struct imd_header imd_end_header
__BAREBOX_IMD_SECTION(.barebox_imd_end) = {
.type = cpu_to_le32(IMD_TYPE_END),
};
BAREBOX_IMD_TAG_STRING(imd_build_tag, IMD_TYPE_BUILD, UTS_VERSION, 1);
BAREBOX_IMD_TAG_STRING(imd_release_tag, IMD_TYPE_RELEASE, UTS_RELEASE, 1);

322
common/imd.c Normal file
View File

@ -0,0 +1,322 @@
/*
* (C) Copyright 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 as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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.
*
*/
#ifdef __BAREBOX__
#include <common.h>
#include <image-metadata.h>
#include <libfile.h>
#include <getopt.h>
#include <malloc.h>
#include <fs.h>
#endif
/*
* imd_next - return a pointer to the next metadata field.
* @imd The current metadata field
*/
struct imd_header *imd_next(struct imd_header *imd)
{
int length;
length = imd_read_length(imd);
length = ALIGN(length, 4);
length += 8;
return (void *)imd + length;
}
struct imd_header *imd_find_type(struct imd_header *imd, uint32_t type)
{
imd_for_each(imd, imd)
if (imd_read_type(imd) == type)
return imd;
return NULL;
}
static int imd_next_validate(void *buf, int bufsize, int start_ofs)
{
int length, size;
struct imd_header *imd = buf + start_ofs;
size = bufsize - start_ofs;
if (size < 8) {
debug("trunkated tag at offset %dd\n", start_ofs);
return -EINVAL;
}
length = imd_read_length(imd);
length = ALIGN(length, 4);
length += 8;
if (size < length) {
debug("tag at offset %d with size %d exceeds bufsize %d\n",
start_ofs, size, bufsize);
return -EINVAL;
}
debug("tag at offset %d has length %d\n", start_ofs, length);
return length;
}
static int imd_validate_tags(void *buf, int bufsize, int start_ofs)
{
int ret;
struct imd_header *imd = buf + start_ofs;
while (1) {
uint32_t type;
ret = imd_next_validate(buf, bufsize, start_ofs);
if (ret < 0) {
debug("Invalid tag at offset %d\n", start_ofs);
return -EINVAL;
}
imd = (void *)imd + ret;
start_ofs += ret;
type = imd_read_type(imd);
if (!imd_type_valid(type)) {
debug("Invalid: tag: 0x%08x\n", type);
return -EINVAL;
}
if (type == IMD_TYPE_END)
return 0;
}
}
/*
* imd_search_validate - find valid metadata in a buffer
* @buf the buffer
* @size buffer size
* @start The returned pointer to the metadata
*
* This iterates over a buffer and searches for metadata. The metadata
* is checked for consistency (length fields not exceeding buffer and
* presence of end header) and returned in @start. The returned pointer
* is only valid when 0 is returned. The returned data may be unaligned.
*/
static int imd_search_validate(void *buf, int size, struct imd_header **start)
{
int start_ofs = 0;
int i, ret;
for (i = start_ofs; i < size - 32; i++) {
uint32_t type;
type = imd_read_le32(buf + i);
if (type != IMD_TYPE_START)
continue;
debug("Start tag found at offset %d\n", i);
ret = imd_validate_tags(buf, size, i);
if (!ret) {
*start = buf + i;
return 0;
}
}
return -EINVAL;
}
struct imd_type_names {
uint32_t type;
const char *name;
};
static struct imd_type_names imd_types[] = {
{
.type = IMD_TYPE_RELEASE,
.name = "release",
}, {
.type = IMD_TYPE_BUILD,
.name = "build",
}, {
.type = IMD_TYPE_MODEL,
.name = "model",
}, {
.type = IMD_TYPE_PARAMETER,
.name = "parameter",
}, {
.type = IMD_TYPE_OF_COMPATIBLE,
.name = "of_compatible",
},
};
static const char *imd_type_to_name(uint32_t type)
{
int i;
for (i = 0; i < ARRAY_SIZE(imd_types); i++)
if (imd_types[i].type == type)
return imd_types[i].name;
return "unknown";
}
static uint32_t imd_name_to_type(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(imd_types); i++)
if (!strcmp(imd_types[i].name, name))
return imd_types[i].type;
return IMD_TYPE_INVALID;
}
static char *imd_string_data(struct imd_entry_string *imd_string, int index)
{
int i, total = 0, l = 0;
int len = imd_read_length(&imd_string->header);
char *p = imd_string->data;
for (i = 0; total < len; total += l, p += l) {
l = strlen(p) + 1;
if (i++ == index)
return p;
}
return NULL;
}
static char *imd_concat_strings(struct imd_entry_string *imd_string)
{
int i, len = imd_read_length(&imd_string->header);
char *str;
str = malloc(len);
if (!str)
return NULL;
memcpy(str, imd_string->data, len);
for (i = 0; i < len - 1; i++)
if (str[i] == 0)
str[i] = ' ';
return str;
}
int imd_command_verbose;
int imd_command(int argc, char *argv[])
{
int ret, opt, strno = -1;
void *buf;
size_t size;
uint32_t type = IMD_TYPE_INVALID;
struct imd_header *imd_start, *imd;
const char *filename;
const char *variable_name = NULL;
char *str;
imd_command_verbose = 0;
while ((opt = getopt(argc, argv, "vt:s:n:")) > 0) {
switch(opt) {
case 't':
type = imd_name_to_type(optarg);
if (type == IMD_TYPE_INVALID) {
fprintf(stderr, "no such type: %s\n", optarg);
return -ENOSYS;
}
break;
case 's':
variable_name = optarg;
break;
case 'v':
imd_command_verbose = 1;
break;
case 'n':
strno = simple_strtoul(optarg, NULL, 0);
break;
default:
return -ENOSYS;
}
}
if (optind == argc) {
fprintf(stderr, "No image given\n");
return -ENOSYS;
}
filename = argv[optind];
ret = read_file_2(filename, &size, &buf, 0x100000);
if (ret && ret != -EFBIG)
return -errno;
ret = imd_search_validate(buf, size, &imd_start);
if (ret)
return ret;
if (type == IMD_TYPE_INVALID) {
imd_for_each(imd_start, imd) {
uint32_t type = imd_read_type(imd);
if (imd_is_string(type)) {
struct imd_entry_string *imd_string =
(struct imd_entry_string *)imd;
str = imd_concat_strings(imd_string);
printf("%s: %s\n", imd_type_to_name(type), str);
} else {
debug("Unknown tag 0x%08x\n", type);
}
}
} else {
imd = imd_find_type(imd_start, type);
if (!imd) {
debug("No tag of type 0x%08x found\n", type);
return -ENODATA;
}
if (imd_is_string(type)) {
struct imd_entry_string *imd_string =
(struct imd_entry_string *)imd;
if (strno >= 0)
str = imd_string_data(imd_string, strno);
else
str = imd_concat_strings(imd_string);
if (!str)
return -ENODATA;
if (variable_name)
imd_command_setenv(variable_name, str);
else
printf("%s\n", str);
if (strno < 0)
free(str);
} else {
printf("tag 0x%08x present\n", type);
}
}
return 0;
}

View File

@ -15,6 +15,7 @@
#include <glob.h>
#include <menu.h>
#include <fs.h>
#include <libfile.h>
#include <linux/stat.h>

View File

@ -22,6 +22,7 @@
#include <malloc.h>
#include <errno.h>
#include <libbb.h>
#include <libfile.h>
#include <uncompress.h>
#include <fcntl.h>
#include <fs.h>

View File

@ -43,6 +43,7 @@
#include <linux/list.h>
#include <usb/gadget.h>
#include <linux/stat.h>
#include <libfile.h>
#include <usb/ch9.h>
#include <usb/dfu.h>
#include <config.h>

72
fs/fs.c
View File

@ -34,78 +34,6 @@
#include <libgen.h>
#include <block.h>
void *read_file(const char *filename, size_t *size)
{
int fd;
struct stat s;
void *buf = NULL;
const char *tmpfile = "/.read_file_tmp";
int ret;
again:
if (stat(filename, &s))
return NULL;
if (s.st_size == FILESIZE_MAX) {
ret = copy_file(filename, tmpfile, 0);
if (ret)
return NULL;
filename = tmpfile;
goto again;
}
buf = xzalloc(s.st_size + 1);
fd = open(filename, O_RDONLY);
if (fd < 0)
goto err_out;
ret = read_full(fd, buf, s.st_size);
if (ret < 0)
goto err_out1;
close(fd);
if (size)
*size = s.st_size;
if (filename == tmpfile)
unlink(tmpfile);
return buf;
err_out1:
close(fd);
err_out:
free(buf);
if (filename == tmpfile)
unlink(tmpfile);
return NULL;
}
EXPORT_SYMBOL(read_file);
int write_file(const char *filename, void *buf, size_t size)
{
int fd, ret;
fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT);
if (fd < 0)
return fd;
ret = write_full(fd, buf, size);
close(fd);
if (ret < 0)
return ret;
return 0;
}
EXPORT_SYMBOL(write_file);
char *mkmodestr(unsigned long mode, char *str)
{
static const char *l = "xwr";

View File

@ -17,6 +17,7 @@
#include <uimagefs.h>
#include <libbb.h>
#include <rtc.h>
#include <libfile.h>
static bool uimagefs_is_data_file(struct uimagefs_handle_data *d)
{

View File

@ -53,6 +53,12 @@
KEEP(*(.dtb.rodata.*)); \
__dtb_end = .;
#define BAREBOX_IMD \
KEEP(*(.barebox_imd_start)) \
KEEP(*(.barebox_imd_1*)) \
*(.barebox_imd_0*) \
KEEP(*(.barebox_imd_end))
#if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \
CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE
#define MAX_BARE_INIT_SIZE CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE

View File

@ -163,20 +163,6 @@ int ls(const char *path, ulong flags);
char *mkmodestr(unsigned long mode, char *str);
/*
* Read a file into memory. Memory is allocated with malloc and must
* be freed with free() afterwards. This function allocates one
* byte more than actually needed and sets this to zero, so that
* it can be used for text files.
* If size is nonzero it s set to the file size.
*/
void *read_file(const char *filename, size_t *size);
/*
* Write a buffer to a file. This file is newly created.
*/
int write_file(const char *filename, void *buf, size_t size);
/*
* This function turns 'path' into an absolute path and removes all occurrences
* of "..", "." and double slashes. The returned string must be freed wit free().

117
include/image-metadata.h Normal file
View File

@ -0,0 +1,117 @@
#ifndef __INCLUDE_IMAGE_METADTA_H
#define __INCLUDE_IMAGE_METADTA_H
/*
* barebox Image MetaData (IMD)
*
* IMD is a mechanism to store metadata in barebox images. With IMD
* it's possible to extract the release, the build timestamp and the
* board type from a barebox image.
*
* Since there is no fixed place in the image suitable for all SoC image
* types the metadata can be stored anywhere in the image and is found
* by iterating over the image. The metadata starts with a start header
* and ends with an end header. All tags in between carry the payload.
*
* Make sure source files containing IMD data are compiled with lwl-y so
* that the tags end up in the PBL if one exists and in the regular image
* without PBL.
*
* The following types exist:
*/
#define IMD_TYPE_START 0x640c0001
#define IMD_TYPE_RELEASE 0x640c8002 /* The barebox release aka UTS_RELEASE */
#define IMD_TYPE_BUILD 0x640c8003 /* build number and timestamp (UTS_VERSION) */
#define IMD_TYPE_MODEL 0x640c8004 /* The board name this image is for */
#define IMD_TYPE_OF_COMPATIBLE 0x640c8005 /* the device tree compatible string */
#define IMD_TYPE_PARAMETER 0x640c8006 /* A generic parameter. Use key=value as data */
#define IMD_TYPE_END 0x640c7fff
#define IMD_TYPE_INVALID 0xffffffff
/*
* The IMD header. All data is stored in little endian format in the image.
* The next header starts at the next 4 byte boundary after the data.
*/
struct imd_header {
uint32_t type; /* One of IMD_TYPE_* above */
uint32_t datalength; /* Length of the data (exluding the header) */
};
/*
* A IMD string. Set bit 15 of the IMD_TYPE to indicate the data is printable
* as string.
*/
struct imd_entry_string {
struct imd_header header;
char data[];
};
static inline int imd_is_string(uint32_t type)
{
return (type & 0x8000) ? 1 : 0;
}
static inline int imd_type_valid(uint32_t type)
{
return (type & 0xffff0000) == 0x640c0000;
}
struct imd_header *imd_next(struct imd_header *imd);
#define imd_for_each(start, imd) \
for (imd = imd_next(start); imd_read_type(imd) != IMD_TYPE_END; imd = imd_next(imd))
static inline uint32_t imd_read_le32(void *_ptr)
{
uint8_t *ptr = _ptr;
return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
}
static inline uint32_t imd_read_type(struct imd_header *imd)
{
return imd_read_le32(&imd->type);
}
static inline uint32_t imd_read_length(struct imd_header *imd)
{
return imd_read_le32(&imd->datalength);
}
struct imd_header *imd_find_type(struct imd_header *imd, uint32_t type);
extern int imd_command_verbose;
int imd_command_setenv(const char *variable_name, const char *value);
int imd_command(int argc, char *argv[]);
#ifdef __BAREBOX__
#include <linux/stringify.h>
#define __BAREBOX_IMD_SECTION(_section) \
__attribute__ ((unused,section (__stringify(_section)))) \
__attribute__((aligned(4)))
#define BAREBOX_IMD_TAG_STRING(_name, _type, _string, _keep_if_unused) \
const struct imd_entry_string __barebox_imd_##_name \
__BAREBOX_IMD_SECTION(.barebox_imd_ ## _keep_if_unused ## _ ## _name) = { \
.header.type = cpu_to_le32(_type), \
.header.datalength = cpu_to_le32(sizeof(_string)), \
.data = _string, \
}
#ifdef CONFIG_IMD
void imd_used(const void *);
#else
static inline void imd_used(const void *unused)
{
}
#endif
#define IMD_USED(_name) \
imd_used(&__barebox_imd_##_name)
#endif /* __BAREBOX__ */
#endif /* __INCLUDE_IMAGE_METADTA_H */

View File

@ -26,15 +26,8 @@ int recursive_action(const char *fileName, unsigned flags,
char * safe_strncpy(char *dst, const char *src, size_t size);
int copy_file(const char *src, const char *dst, int verbose);
int process_escape_sequence(const char *source, char *dest, int destlen);
char *simple_itoa(unsigned int i);
int write_full(int fd, void *buf, size_t size);
int read_full(int fd, void *buf, size_t size);
char *read_file_line(const char *fmt, ...);
#endif /* __LIBBB_H */

18
include/libfile.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __LIBFILE_H
#define __LIBFILE_H
int write_full(int fd, void *buf, size_t size);
int read_full(int fd, void *buf, size_t size);
char *read_file_line(const char *fmt, ...);
void *read_file(const char *filename, size_t *size);
int read_file_2(const char *filename, size_t *size, void **outbuf,
loff_t max_size);
int write_file(const char *filename, void *buf, size_t size);
int copy_file(const char *src, const char *dst, int verbose);
#endif /* __LIBFILE_H */

View File

@ -25,7 +25,6 @@ obj-$(CONFIG_GLOB) += fnmatch.o
obj-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
obj-y += glob.o
obj-y += notifier.o
obj-y += copy_file.o
obj-y += random.o
obj-y += lzo/
obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
@ -45,3 +44,4 @@ obj-$(CONFIG_XYMODEM) += xymodem.o
obj-y += unlink-recursive.o
obj-$(CONFIG_STMP_DEVICE) += stmp-device.o
obj-y += wchar.o
obj-y += libfile.o

View File

@ -11,6 +11,7 @@
#include <sizes.h>
#include <errno.h>
#include <malloc.h>
#include <libfile.h>
#include <bootstrap.h>
void* bootstrap_read_disk(char *dev, char *fstype)

View File

@ -1,86 +0,0 @@
#include <common.h>
#include <fs.h>
#include <fcntl.h>
#include <errno.h>
#include <malloc.h>
#include <libbb.h>
#include <progress.h>
/**
* @param[in] src FIXME
* @param[out] dst FIXME
* @param[in] verbose FIXME
*/
int copy_file(const char *src, const char *dst, int verbose)
{
char *rw_buf = NULL;
int srcfd = 0, dstfd = 0;
int r, w;
int ret = 1;
void *buf;
int total = 0;
struct stat statbuf;
rw_buf = xmalloc(RW_BUF_SIZE);
srcfd = open(src, O_RDONLY);
if (srcfd < 0) {
printf("could not open %s: %s\n", src, errno_str());
goto out;
}
dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC);
if (dstfd < 0) {
printf("could not open %s: %s\n", dst, errno_str());
goto out;
}
if (verbose) {
if (stat(src, &statbuf) < 0)
statbuf.st_size = 0;
init_progression_bar(statbuf.st_size);
}
while(1) {
r = read(srcfd, rw_buf, RW_BUF_SIZE);
if (r < 0) {
perror("read");
goto out;
}
if (!r)
break;
buf = rw_buf;
while (r) {
w = write(dstfd, buf, r);
if (w < 0) {
perror("write");
goto out;
}
buf += w;
r -= w;
total += w;
}
if (verbose) {
if (statbuf.st_size && statbuf.st_size != FILESIZE_MAX)
show_progress(total);
else
show_progress(total / 16384);
}
}
ret = 0;
out:
if (verbose)
putchar('\n');
free(rw_buf);
if (srcfd > 0)
close(srcfd);
if (dstfd > 0)
close(dstfd);
return ret;
}

View File

@ -10,6 +10,7 @@
#include <errno.h>
#include <fs.h>
#include <malloc.h>
#include <libfile.h>
static LIST_HEAD(image_renderers);

View File

@ -126,96 +126,3 @@ char *simple_itoa(unsigned int i)
return p + 1;
}
EXPORT_SYMBOL(simple_itoa);
/*
* write_full - write to filedescriptor
*
* Like write, but guarantees to write the full buffer out, else
* it returns with an error.
*/
int write_full(int fd, void *buf, size_t size)
{
size_t insize = size;
int now;
while (size) {
now = write(fd, buf, size);
if (now <= 0)
return now;
size -= now;
buf += now;
}
return insize;
}
EXPORT_SYMBOL(write_full);
/*
* read_full - read from filedescriptor
*
* Like read, but this function only returns less bytes than
* requested when the end of file is reached.
*/
int read_full(int fd, void *buf, size_t size)
{
size_t insize = size;
int now;
int total = 0;
while (size) {
now = read(fd, buf, size);
if (now == 0)
return total;
if (now < 0)
return now;
total += now;
size -= now;
buf += now;
}
return insize;
}
EXPORT_SYMBOL(read_full);
/*
* read_file_line - read a line from a file
*
* Used to compose a filename from a printf format and to read a line from this
* file. All leading and trailing whitespaces (including line endings) are
* removed. The returned buffer must be freed with free(). This function is
* supposed for reading variable like content into a buffer, so files > 1024
* bytes are ignored.
*/
char *read_file_line(const char *fmt, ...)
{
va_list args;
char *filename;
char *buf, *line = NULL;
size_t size;
int ret;
struct stat s;
va_start(args, fmt);
filename = vasprintf(fmt, args);
va_end(args);
ret = stat(filename, &s);
if (ret)
goto out;
if (s.st_size > 1024)
goto out;
buf = read_file(filename, &size);
if (!buf)
goto out;
line = strim(buf);
line = xstrdup(line);
free(buf);
out:
free(filename);
return line;
}
EXPORT_SYMBOL_GPL(read_file_line);

331
lib/libfile.c Normal file
View File

@ -0,0 +1,331 @@
/*
* Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, 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 <common.h>
#include <fs.h>
#include <fcntl.h>
#include <malloc.h>
#include <libfile.h>
#include <progress.h>
#include <linux/stat.h>
/*
* write_full - write to filedescriptor
*
* Like write, but guarantees to write the full buffer out, else
* it returns with an error.
*/
int write_full(int fd, void *buf, size_t size)
{
size_t insize = size;
int now;
while (size) {
now = write(fd, buf, size);
if (now <= 0)
return now;
size -= now;
buf += now;
}
return insize;
}
EXPORT_SYMBOL(write_full);
/*
* read_full - read from filedescriptor
*
* Like read, but this function only returns less bytes than
* requested when the end of file is reached.
*/
int read_full(int fd, void *buf, size_t size)
{
size_t insize = size;
int now;
int total = 0;
while (size) {
now = read(fd, buf, size);
if (now == 0)
return total;
if (now < 0)
return now;
total += now;
size -= now;
buf += now;
}
return insize;
}
EXPORT_SYMBOL(read_full);
/*
* read_file_line - read a line from a file
*
* Used to compose a filename from a printf format and to read a line from this
* file. All leading and trailing whitespaces (including line endings) are
* removed. The returned buffer must be freed with free(). This function is
* supposed for reading variable like content into a buffer, so files > 1024
* bytes are ignored.
*/
char *read_file_line(const char *fmt, ...)
{
va_list args;
char *filename;
char *buf, *line = NULL;
size_t size;
int ret;
struct stat s;
va_start(args, fmt);
filename = vasprintf(fmt, args);
va_end(args);
ret = stat(filename, &s);
if (ret)
goto out;
if (s.st_size > 1024)
goto out;
buf = read_file(filename, &size);
if (!buf)
goto out;
line = strim(buf);
line = xstrdup(line);
free(buf);
out:
free(filename);
return line;
}
EXPORT_SYMBOL_GPL(read_file_line);
/**
* read_file_2 - read a file to an allocated buffer
* @filename: The filename to read
* @size: After successful return contains the size of the file
* @outbuf: contains a pointer to the file data after successful return
* @max_size: The maximum size to read. Use FILESIZE_MAX for reading files
* of any size.
*
* This function reads a file to an allocated buffer. At maximum @max_size
* bytes are read. The actual read size is returned in @size. -EFBIG is
* returned if the file is bigger than @max_size, but the buffer is read
* anyway up to @max_size in this case. Free the buffer with free() after
* usage.
*
* Return: 0 for success, or negative error code. -EFBIG is returned
* when the file has been bigger than max_size.
*/
int read_file_2(const char *filename, size_t *size, void **outbuf,
loff_t max_size)
{
int fd;
struct stat s;
void *buf = NULL;
const char *tmpfile = "/.read_file_tmp";
int ret;
loff_t read_size;
again:
ret = stat(filename, &s);
if (ret)
return ret;
if (max_size == FILESIZE_MAX)
read_size = s.st_size;
else
read_size = max_size;
if (read_size == FILESIZE_MAX) {
ret = copy_file(filename, tmpfile, 0);
if (ret)
return ret;
filename = tmpfile;
goto again;
}
buf = xzalloc(read_size + 1);
fd = open(filename, O_RDONLY);
if (fd < 0)
goto err_out;
ret = read_full(fd, buf, read_size);
if (ret < 0)
goto err_out1;
close(fd);
if (size)
*size = ret;
if (filename == tmpfile)
unlink(tmpfile);
*outbuf = buf;
if (read_size < s.st_size)
return -EFBIG;
else
return 0;
err_out1:
close(fd);
err_out:
free(buf);
if (filename == tmpfile)
unlink(tmpfile);
return ret;
}
EXPORT_SYMBOL(read_file_2);
/**
* read_file - read a file to an allocated buffer
* @filename: The filename to read
* @size: After successful return contains the size of the file
*
* This function reads a file to an allocated buffer.
* Some TFTP servers do not transfer the size of a file. In this case
* a the file is first read to a temporary file.
*
* Return: The buffer conataining the file or NULL on failure
*/
void *read_file(const char *filename, size_t *size)
{
int ret;
void *buf;
ret = read_file_2(filename, size, &buf, FILESIZE_MAX);
if (!ret)
return buf;
return NULL;
}
EXPORT_SYMBOL(read_file);
/**
* write_file - write a buffer to a file
* @filename: The filename to write
* @size: The size of the buffer
*
* Return: 0 for success or negative error value
*/
int write_file(const char *filename, void *buf, size_t size)
{
int fd, ret;
fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT);
if (fd < 0)
return fd;
ret = write_full(fd, buf, size);
close(fd);
if (ret < 0)
return ret;
return 0;
}
EXPORT_SYMBOL(write_file);
/**
* copy_file - Copy a file
* @src: The source filename
* @dst: The destination filename
* @verbose: if true, show a progression bar
*
* Return: 0 for success or negative error code
*/
int copy_file(const char *src, const char *dst, int verbose)
{
char *rw_buf = NULL;
int srcfd = 0, dstfd = 0;
int r, w;
int ret = 1;
void *buf;
int total = 0;
struct stat statbuf;
rw_buf = xmalloc(RW_BUF_SIZE);
srcfd = open(src, O_RDONLY);
if (srcfd < 0) {
printf("could not open %s: %s\n", src, errno_str());
goto out;
}
dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC);
if (dstfd < 0) {
printf("could not open %s: %s\n", dst, errno_str());
goto out;
}
if (verbose) {
if (stat(src, &statbuf) < 0)
statbuf.st_size = 0;
init_progression_bar(statbuf.st_size);
}
while (1) {
r = read(srcfd, rw_buf, RW_BUF_SIZE);
if (r < 0) {
perror("read");
goto out;
}
if (!r)
break;
buf = rw_buf;
while (r) {
w = write(dstfd, buf, r);
if (w < 0) {
perror("write");
goto out;
}
buf += w;
r -= w;
total += w;
}
if (verbose) {
if (statbuf.st_size && statbuf.st_size != FILESIZE_MAX)
show_progress(total);
else
show_progress(total / 16384);
}
}
ret = 0;
out:
if (verbose)
putchar('\n');
free(rw_buf);
if (srcfd > 0)
close(srcfd);
if (dstfd > 0)
close(dstfd);
return ret;
}
EXPORT_SYMBOL(copy_file);

View File

@ -10,6 +10,7 @@ hostprogs-y += fix_size
hostprogs-y += bareboxenv
hostprogs-y += bareboxcrc32
hostprogs-y += kernel-install
hostprogs-$(CONFIG_IMD) += bareboximd
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
hostprogs-$(CONFIG_ARCH_MVEBU) += kwbimage kwboot
hostprogs-$(CONFIG_ARCH_NETX) += gen_netx_image
@ -29,6 +30,7 @@ subdir-$(CONFIG_ARCH_TEGRA) += tegra
targetprogs-$(CONFIG_BAREBOXENV_TARGET) += bareboxenv-target
targetprogs-$(CONFIG_KERNEL_INSTALL_TARGET) += kernel-install-target
targetprogs-$(CONFIG_BAREBOXCRC32_TARGET) += bareboxcrc32-target
targetprogs-$(CONFIG_IMD_TARGET) += bareboximd-target
# Let clean descend into subdirs
subdir- += basic kconfig setupmbr

View File

@ -14,6 +14,13 @@ obj-m := $(filter-out $(obj-y),$(obj-m))
lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
pbl-y += $(pbl-dtb-y)
obj-y += $(obj-dtb-y)
extra-y += $(patsubst %.dtb.o,%.dtb.S,$(obj-dtb-y))
extra-y += $(patsubst %.dtb.o,%.dtb,$(obj-dtb-y))
extra-y += $(patsubst %.dtb.o,%.dtb.S,$(pbl-dtb-y))
extra-y += $(patsubst %.dtb.o,%.dtb,$(pbl-dtb-y))
# Handle objects in subdirs
# ---------------------------------------------------------------------------
# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o
@ -203,21 +210,9 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
# Generate an assembly file to wrap the output of the device tree compiler
quiet_cmd_dt_S_dtb = DTB $@
cmd_dt_S_dtb= \
( \
echo '\#include <asm-generic/barebox.lds.h>'; \
echo '.section .dtb.rodata.$(subst -,_,$(*F)),"a"'; \
echo '.balign STRUCT_ALIGNMENT'; \
echo '.global __dtb_$(subst -,_,$(*F))_start'; \
echo '__dtb_$(subst -,_,$(*F))_start:'; \
echo '.incbin "$<" '; \
echo '__dtb_$(subst -,_,$(*F))_end:'; \
echo '.global __dtb_$(subst -,_,$(*F))_end'; \
echo '.balign STRUCT_ALIGNMENT'; \
) > $@
$(obj)/%.dtb.S: $(obj)/%.dtb
$(call cmd,dt_S_dtb)
cmd_dt_S_dtb = $(srctree)/scripts/gen-dtb-s $(subst -,_,$(*F)) $< $(CONFIG_IMD) > $@
$(obj)/%.dtb.S: $(obj)/%.dtb $(srctree)/scripts/gen-dtb-s FORCE
$(call if_changed,dt_S_dtb)
quiet_cmd_dtc = DTC $@
cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \

161
scripts/bareboximd.c Normal file
View File

@ -0,0 +1,161 @@
/*
* (C) Copyright 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 as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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.
*
*/
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#include <stdio.h>
#include <sys/types.h>
#include <stdint.h>
#include <asm-generic/errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include "../include/image-metadata.h"
static void debug(const char *fmt, ...)
{
va_list ap;
if (!imd_command_verbose)
return;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
int imd_command_setenv(const char *variable_name, const char *value)
{
fprintf(stderr, "-s option ignored\n");
return -EINVAL;
}
static int read_file_2(const char *filename, size_t *size, void **outbuf, loff_t max_size)
{
off_t fsize;
ssize_t rsize;
int ret, fd;
void *buf;
*size = 0;
*outbuf = NULL;
fd = open(filename, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno));
return -errno;
}
fsize = lseek(fd, 0, SEEK_END);
if (fsize == -1) {
fprintf(stderr, "Cannot get size %s: %s\n", filename, strerror(errno));
ret = -errno;
goto close;
}
if (fsize < max_size)
max_size = fsize;
if (lseek(fd, 0, SEEK_SET) == -1) {
fprintf(stderr, "Cannot seek to start %s: %s\n", filename, strerror(errno));
ret = -errno;
goto close;
}
buf = malloc(max_size);
if (!buf) {
fprintf(stderr, "Cannot allocate memory\n");
ret = -ENOMEM;
goto close;
}
*outbuf = buf;
while (*size < max_size) {
rsize = read(fd, buf, max_size-*size);
if (rsize == 0) {
ret = -EIO;
goto free;
} else if (rsize < 0) {
if (errno == EAGAIN)
continue;
else {
ret = -errno;
goto free;
}
} /* ret > 0 */
buf += rsize;
*size += rsize;
}
ret = 0;
goto close;
free:
*outbuf = NULL;
free(buf);
close:
close(fd);
return ret;
}
static unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
{
return strtoul(cp, endp, base);
}
#include "../common/imd.c"
static void usage(const char *prgname)
{
printf(
"Extract metadata from a barebox image\n"
"\n"
"Usage: %s [OPTIONS] FILE\n"
"Options:\n"
"-t <type> only show information of <type>\n"
"-n <no> for tags with multiple strings only show string <no>\n"
"\n"
"Without options all information available is printed. Valid types are:\n"
"release, build, model, of_compatible\n",
prgname);
}
int main(int argc, char *argv[])
{
int ret;
ret = imd_command(argc, argv);
if (ret == -ENOSYS) {
usage(argv[0]);
exit(1);
}
if (ret)
fprintf(stderr, "%s\n", strerror(-ret));
return ret ? 1 : 0;
}

View File

@ -2,3 +2,4 @@ dtc
dtc-lexer.lex.c
dtc-parser.tab.c
dtc-parser.tab.h
fdtget

View File

@ -1,15 +1,20 @@
# scripts/dtc makefile
hostprogs-y := dtc
hostprogs-y := dtc fdtget
always := $(hostprogs-y)
dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
srcpos.o checks.o util.o
dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
libfdt-objs = fdt.o fdt_ro.o fdt_strerror.o fdt_wip.o
libfdt-objs += fdt_empty_tree.o fdt_rw.o fdt_sw.o
fdtget-objs += fdtget.o $(libfdt-objs) util.o
# Source files need to get at the userspace version of libfdt_env.h to compile
HOSTCFLAGS_DTC := -I$(src) -I$(src)/libfdt
HOSTCFLAGS_DTC := -I$(src)
HOSTCFLAGS_checks.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_data.o := $(HOSTCFLAGS_DTC)
@ -21,6 +26,15 @@ HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdt.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdt_ro.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdt_strerror.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdt_wip.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdt_empty_tree.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdt_rw.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdt_sw.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_fdtget.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC)
HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)

56
scripts/gen-dtb-s Executable file
View File

@ -0,0 +1,56 @@
#!/bin/bash
name=$1
dtb=$2
imd=$3
echo "#include <asm-generic/barebox.lds.h>"
le32() {
printf ".byte 0x%02x, 0x%02x, 0x%02x, 0x%02x\n" \
$(($1 & 0xff)) \
$((($1 >> 8) & 0xff)) \
$((($1 >> 16) & 0xff)) \
$((($1 >> 24) & 0xff))
}
FDTGET=scripts/dtc/fdtget
if [ "$imd" = "y" ]; then
echo ".section .barebox_imd_0.${name},\"a\""
echo ".global __imd_${name}_start"
echo "__imd_${name}_start:"
compat=$($FDTGET -d notfound -t bi "$dtb" / compatible | sed "s^ ^,^g")
if [ "$compat" != "notfound" ]; then
compatlen=$($FDTGET -t s "$dtb" / compatible | wc -c)
le32 0x640c8005
le32 $compatlen
echo ".byte " $compat
echo ".balign 4"
fi
model=$($FDTGET -d notfound -t bi "$dtb" / model | sed "s^ ^,^g")
if [ "$model" != "notfound" ]; then
modellen=$($FDTGET -t s "$dtb" / model | wc -c)
le32 0x640c8004
le32 $compatlen
echo ".byte " $model
echo ".balign 4"
fi
fi
echo ".section .dtb.rodata.${name},\"a\""
echo ".balign STRUCT_ALIGNMENT"
echo ".global __dtb_${name}_start"
echo "__dtb_${name}_start:"
echo ".incbin \"$dtb\""
echo "__dtb_${name}_end:"
echo ".global __dtb_${name}_end"
echo ".balign STRUCT_ALIGNMENT"
if [ "$imd" = "y" ]; then
echo ".word __imd_${name}_start"
fi