Date: Tue, 2 Oct 2012 18:07:07 +0300 From: Boris Astardzhiev <boris.astardzhiev@gmail.com> To: freebsd-fs@freebsd.org Cc: stanislav_galabov@smartcom.bg Subject: CRC32 feature in FreeBSD's boot loader Message-ID: <CAP=KkTx9x0WbTMUbxHKaGhnCj0vLWOSw15tD27KFbVdc6shefA@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hello,
I'm not sure that this is the right mailing list but I couldn't find a
dedicated one.
I would like to contribute a new feature for the FreeBSD boot loader - a
command that
calculates the CRC32 of a specified file name. It uses libz's CRC32
implementation.
While attempting to make libstand's nandfs to work adequately I've
experienced NAND flash
page/block misreadings from U-Boot's API side. Therefore I was in a need of
a tool that could
prove that a file had been read correctly in this very stage of the FreeBSD
boot process.
So here it is.
In addition to the CRC calculation the size of the stipulated file is
printed as well.
Any comments will be appreciated.
Greetings,
Boris Astardzhiev / Smartcom Bulgaria AD
[-- Attachment #2 --]
diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile
index a26c51d..095f962 100644
--- a/lib/libstand/Makefile
+++ b/lib/libstand/Makefile
@@ -39,9 +39,9 @@ CFLAGS+= -msoft-float -D_STANDALONE
.endif
# standalone components and stuff we have modified locally
-SRCS+= zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
- globals.c pager.c printf.c strdup.c strerror.c strtol.c random.c \
- sbrk.c twiddle.c zalloc.c zalloc_malloc.c
+SRCS+= zutil.h __main.c assert.c bcd.c bswap.c crc.c environment.c getopt.c \
+ gets.c globals.c pager.c printf.c strdup.c strerror.c strtol.c \
+ random.c sbrk.c twiddle.c zalloc.c zalloc_malloc.c
# private (pruned) versions of libc string functions
SRCS+= strcasecmp.c
diff --git a/lib/libstand/crc.c b/lib/libstand/crc.c
new file mode 100644
index 0000000..331d390
--- /dev/null
+++ b/lib/libstand/crc.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2012 Boris Astardzhiev / Smartcom Bulgaria AD
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Simple CRC calculation of a file.
+ */
+
+#include <sys/cdefs.h>
+#include "stand.h"
+#include <string.h>
+#include "../libz/zlib.h"
+
+/*
+ * Display checksum.
+ */
+
+int
+crc32_file(const char *fname)
+{
+ unsigned long crc = 0UL;
+ char buf[80];
+ size_t bytes;
+ int fd;
+ int res;
+ off_t end_off;
+ struct stat st;
+
+ res = 0;
+ fd = open(fname, O_RDONLY);
+ if (fd == -1) {
+ printf("can't open '%s': %s\n", fname, strerror(errno));
+ res = -1;
+ return (res);
+ }
+
+ /*
+ * Check if it is a regular file.
+ */
+ memset(&st, 0, sizeof(st));
+ if (fstat(fd, &st) == -1) {
+ printf("can't get statistics of '%s': %s\n", fname,
+ strerror(errno));
+ close(fd);
+ res = -1;
+ return (res);
+ }
+
+ if (!(S_ISREG(st.st_mode))) {
+ printf("'%s' is not a regular file\n", fname);
+ close(fd);
+ res = -1;
+ return (res);
+ }
+
+ /*
+ * Grab file size.
+ */
+ end_off = lseek(fd, 0, SEEK_END);
+ if (end_off == -1) {
+ printf("can't get end of '%s': %s\n", fname, strerror(errno));
+ close(fd);
+ res = -1;
+ return (res);
+ }
+
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ printf("can't set offset to '%s': %s\n", fname,
+ strerror(errno));
+ close(fd);
+ res = -1;
+ return (res);
+ }
+
+ /*
+ * Calculate checksum.
+ */
+ crc = crc32(crc, 0, 0);
+ for (;;) {
+ bytes = read(fd, buf, sizeof(buf));
+ if (bytes < 0) {
+ res = -1;
+ break;
+ }
+
+ if (!bytes)
+ break;
+
+ crc = crc32(crc, buf, bytes);
+ }
+
+ if (!res) {
+ printf("file: %s\n", fname);
+ printf("\t size: %llu\n", end_off);
+ printf("\tcrc32: 0x%08lx\n", crc);
+ } else
+ printf("can't calculate crc32 of '%s'\n", fname);
+
+ close(fd);
+
+ return (res);
+}
+
diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h
index 20b717e..119c696 100644
--- a/lib/libstand/stand.h
+++ b/lib/libstand/stand.h
@@ -267,6 +267,9 @@ extern char *optarg; /* getopt(3) external variables */
extern int optind, opterr, optopt, optreset;
extern int getopt(int, char * const [], const char *);
+/* crc.c */
+extern int crc32_file(const char *fname);
+
/* pager.c */
extern void pager_open(void);
extern void pager_close(void);
diff --git a/sys/boot/common/commands.c b/sys/boot/common/commands.c
index b4fe118..fbbec66 100644
--- a/sys/boot/common/commands.c
+++ b/sys/boot/common/commands.c
@@ -496,3 +496,20 @@ command_lsdev(int argc, char *argv[])
return(CMD_OK);
}
+/*
+ * Calculate CRC32 of a file.
+ */
+COMMAND_SET(crc32, "crc32", "calculate crc32 of a file", command_crc32);
+
+static int
+command_crc32(int argc, char *argv[])
+{
+ int i, res;
+
+ res = 0;
+ for (i = 1; (i < argc) && !res; i++)
+ res |= crc32_file(argv[i]);
+
+ return (!res ? (CMD_OK) : (CMD_ERROR));
+}
+
diff --git a/sys/boot/common/loader.8 b/sys/boot/common/loader.8
index 25d2270..95cc47b 100644
--- a/sys/boot/common/loader.8
+++ b/sys/boot/common/loader.8
@@ -174,6 +174,8 @@ The behavior of this builtin is changed if
.Xr loader.4th 8
is loaded.
.Pp
+.It Ic crc32
+Calculate CRC32 of a specified file.
.It Ic echo Xo
.Op Fl n
.Op Aq message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAP=KkTx9x0WbTMUbxHKaGhnCj0vLWOSw15tD27KFbVdc6shefA>
