/* $Id: uboot.c,v 1.2 2021/11/06 17:35:07 khorben Exp $ */ /* Copyright (c) 2011 khorben of Uberwall */ /* 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 version 2 of the License. * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "plugin.h" /* u-boot */ /* public */ /* types */ #define IH_NMLEN 32 #pragma pack(1) struct uboot { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ uint32_t ih_time; /* Image Creation Timestamp */ uint32_t ih_size; /* Image Data Size */ uint32_t ih_load; /* Data Load Address */ uint32_t ih_ep; /* Entry Point Address */ uint32_t ih_dcrc; /* Image Data CRC Checksum */ uint8_t ih_os; /* Operating System */ uint8_t ih_arch; /* CPU architecture */ uint8_t ih_type; /* Image Type */ uint8_t ih_comp; /* Compression Type */ uint8_t ih_name[IH_NMLEN]; /* Image Name */ }; #pragma pack() /* constants */ #define IH_OS_INVALID 0 /* Invalid OS */ #define IH_OS_OPENBSD 1 /* OpenBSD */ #define IH_OS_NETBSD 2 /* NetBSD */ #define IH_OS_FREEBSD 3 /* FreeBSD */ #define IH_OS_4_4BSD 4 /* 4.4BSD */ #define IH_OS_LINUX 5 /* Linux */ #define IH_OS_SVR4 6 /* SVR4 */ #define IH_OS_ESIX 7 /* Esix */ #define IH_OS_SOLARIS 8 /* Solaris */ #define IH_OS_IRIX 9 /* Irix */ #define IH_OS_SCO 10 /* SCO */ #define IH_OS_DELL 11 /* Dell */ #define IH_OS_NCR 12 /* NCR */ #define IH_OS_LYNXOS 13 /* LynxOS */ #define IH_OS_VXWORKS 14 /* VxWorks */ #define IH_OS_PSOS 15 /* pSOS */ #define IH_OS_QNX 16 /* QNX */ #define IH_OS_U_BOOT 17 /* Firmware */ #define IH_OS_RTEMS 18 /* RTEMS */ #define IH_OS_ARTOS 19 /* ARTOS */ #define IH_OS_UNITY 20 /* Unity OS */ #define IH_CPU_INVALID 0 /* Invalid CPU */ #define IH_CPU_ALPHA 1 /* Alpha */ #define IH_CPU_ARM 2 /* ARM */ #define IH_CPU_I386 3 /* Intel x86 */ #define IH_CPU_IA64 4 /* IA64 */ #define IH_CPU_MIPS 5 /* MIPS */ #define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ #define IH_CPU_PPC 7 /* PowerPC */ #define IH_CPU_S390 8 /* IBM S390 */ #define IH_CPU_SH 9 /* SuperH */ #define IH_CPU_SPARC 10 /* Sparc */ #define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ #define IH_CPU_M68K 12 /* M68K */ #define IH_CPU_NIOS 13 /* Nios-32 */ #define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ #define IH_CPU_NIOS2 15 /* Nios-II */ #define IH_CPU_BLACKFIN 16 /* Blackfin */ #define IH_CPU_AVR32 17 /* AVR32 */ #define IH_TYPE_INVALID 0 /* Invalid Image */ #define IH_TYPE_STANDALONE 1 #define IH_TYPE_KERNEL 2 #define IH_TYPE_RAMDISK 3 #define IH_TYPE_MULTI 4 #define IH_TYPE_FIRMWARE 5 #define IH_TYPE_SCRIPT 6 #define IH_TYPE_FILESYSTEM 7 #define IH_TYPE_FLATDT 8 #define IH_COMP_NONE 0 /* No compression used */ #define IH_COMP_GZIP 1 /* gzip compression used */ #define IH_COMP_BZIP2 2 /* bzip2 compression used */ #define UBOOT_MAGIC 0x27051956 /* variables */ /* magic */ static unsigned char sig1[] = "\x27\x05\x19\x56"; static PluginMagic uboot_magic[] = { { sizeof(struct uboot), 0, sig1, sizeof(sig1)-1 }, { 0, 0, NULL, 0 } }; /* functions */ static int uboot_callback(PluginHelper * ph, int signature, FILE * fp); /* plugin */ Plugin plugin = { PT_EXECUTABLE, "U-BOOT", uboot_magic, uboot_callback }; /* private */ /* functions */ /* uboot_callback */ static int _callback_time(PluginHelper * ph, struct uboot * buf); static int _callback_size(PluginHelper * ph, struct uboot * buf); static int _callback_load(PluginHelper * ph, struct uboot * buf); static int _callback_ep(PluginHelper * ph, struct uboot * buf); static int _callback_os(PluginHelper * ph, struct uboot * buf); static int _callback_arch(PluginHelper * ph, struct uboot * buf); static int _callback_type(PluginHelper * ph, struct uboot * buf); static int _callback_comp(PluginHelper * ph, struct uboot * buf); static int _callback_name(PluginHelper * ph, struct uboot * buf); static int uboot_callback(PluginHelper * ph, int signature, FILE * fp) { int score = 0; struct uboot buf; (void) signature; if(fread(&buf, sizeof(buf), 1, fp) != 1) return 0; score += _callback_time(ph, &buf); _callback_size(ph, &buf); _callback_load(ph, &buf); _callback_ep(ph, &buf); score += _callback_os(ph, &buf); score += _callback_arch(ph, &buf); score += _callback_type(ph, &buf); score += _callback_comp(ph, &buf); _callback_name(ph, &buf); ph->printf(ph, "\n"); return score / 5; } static int _callback_time(PluginHelper * ph, struct uboot * buf) { time_t t = buf->ih_time; struct tm tm; char tmp[20] = ""; /* FIXME what about the endian? */ if(gmtime_r(&t, &tm) == NULL || strftime(tmp, sizeof(tmp), "%d/%m/%Y %H:%M:%S", &tm) == 0) { ph->printf(ph, "%s", "unknown date"); return 0; } ph->printf(ph, "%s", tmp); /* between Wed May 1 00:00:00 CEST 1996 and now */ return t > 830901600 && t < time(NULL) ? 100 : 0; } static int _callback_size(PluginHelper * ph, struct uboot * buf) { ph->printf(ph, ", size 0x%08x", buf->ih_size); return buf->ih_size > 0 && buf->ih_size < 2147483648 ? 100 : 0; } static int _callback_load(PluginHelper * ph, struct uboot * buf) { ph->printf(ph, ", load at 0x%08x", buf->ih_load); return 100; } static int _callback_ep(PluginHelper * ph, struct uboot * buf) { ph->printf(ph, ", entrypoint at 0x%08x", buf->ih_ep); return 100; } static int _callback_os(PluginHelper * ph, struct uboot * buf) { struct { int os; char * string; int score; } name[] = { { IH_OS_INVALID, "invalid", 0 }, { IH_OS_OPENBSD, "OpenBSD", 100 }, { IH_OS_NETBSD, "NetBSD", 100 }, { IH_OS_FREEBSD, "FreeBSD", 100 }, { IH_OS_4_4BSD, "4.4BSD", 100 }, { IH_OS_LINUX, "Linux", 100 }, { -1, "unknown", 20 } }; unsigned int i; for(i = 0; name[i].os != -1 && name[i].os != buf->ih_os; i++); ph->printf(ph, ", OS %s", name[i].string); return name[i].score; } static int _callback_arch(PluginHelper * ph, struct uboot * buf) { struct { int arch; char * string; int score; } name[] = { { IH_CPU_INVALID, "invalid", 0 }, { IH_CPU_ALPHA, "Alpha", 100 }, { IH_CPU_ARM, "ARM", 100 }, { IH_CPU_I386, "Intel x86", 100 }, { IH_CPU_IA64, "IA64", 100 }, { IH_CPU_MIPS, "MIPS", 100 }, { IH_CPU_MIPS64, "MIPS 64 bits", 100 }, { IH_CPU_PPC, "PowerPC", 100 }, { IH_CPU_S390, "IBM S390", 100 }, { IH_CPU_SH, "SuperH", 100 }, { IH_CPU_SPARC, "Sparc", 100 }, { IH_CPU_SPARC64, "Sparc 64 bits",100 }, { IH_CPU_M68K, "M68K", 100 }, { IH_CPU_NIOS, "Nios-32", 100 }, { IH_CPU_MICROBLAZE, "MicroBlaze", 100 }, { IH_CPU_NIOS2, "Nios-II", 100 }, { IH_CPU_BLACKFIN, "Blackfin", 100 }, { IH_CPU_AVR32, "AVR32", 100 }, { -1, "unknown", 20 } }; unsigned int i; for(i = 0; name[i].arch != -1 && name[i].arch != buf->ih_arch; i++); ph->printf(ph, ", CPU %s", name[i].string); return name[i].score; } static int _callback_type(PluginHelper * ph, struct uboot * buf) { struct { int type; char * string; int score; } name[] = { { IH_TYPE_INVALID, "invalid", 0 }, { IH_TYPE_STANDALONE, "Standalone", 100 }, { IH_TYPE_KERNEL, "OS Kernel", 100 }, { IH_TYPE_RAMDISK, "RAMDisk" , 100 }, { IH_TYPE_MULTI, "Multi-File", 100 }, { IH_TYPE_FIRMWARE, "Firmware", 100 }, { IH_TYPE_SCRIPT, "Script file", 100 }, { IH_TYPE_FILESYSTEM, "Filesystem", 100 }, { IH_TYPE_FLATDT, "Binary File Device Tree", 100 }, { -1, "unknown", 20 } }; unsigned int i; for(i = 0; name[i].type != -1 && name[i].type != buf->ih_type; i++); ph->printf(ph, ", type %s", name[i].string); return name[i].score; } static int _callback_comp(PluginHelper * ph, struct uboot * buf) { struct { int comp; char * string; int score; } name[] = { { IH_COMP_NONE, "none", 100 }, { IH_COMP_GZIP, "gzip", 100 }, { IH_COMP_BZIP2, "bzip2", 100 }, { -1, "unknown", 20 } }; unsigned int i; for(i = 0; name[i].comp != -1 && name[i].comp != buf->ih_comp; i++); ph->printf(ph, ", comp %s", name[i].string); return name[i].score; } static int _callback_name(PluginHelper * ph, struct uboot * buf) { ph->printf(ph, ", name \"%32s\"", buf->ih_name); return 0; }