@@ -23,6 +23,7 @@ config OF_FLATTREE
bool
select DTC
select LIBFDT
+ select CRC32
config OF_EARLY_FLATTREE
bool
@@ -9,6 +9,7 @@
* version 2 as published by the Free Software Foundation.
*/
+#include <linux/crc32.h>
#include <linux/kernel.h>
#include <linux/initrd.h>
#include <linux/memblock.h>
@@ -22,10 +23,20 @@
#include <linux/libfdt.h>
#include <linux/debugfs.h>
#include <linux/serial_core.h>
+#include <linux/sysfs.h>
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include <asm/page.h>
+static u32 of_fdt_crc32;
+
+static u32 of_fdt_get_crc32(void *fdt)
+{
+ static u32 const OF_FDT_CRC32_SEED = 0x04c11db7;
+
+ return crc32_be(OF_FDT_CRC32_SEED, fdt, fdt_totalsize(fdt));
+}
+
/*
* of_fdt_limit_memory - limit the number of regions in the /memory node
* @limit: maximum entries
@@ -1003,6 +1014,7 @@ bool __init early_init_dt_verify(void *params)
/* Setup flat device-tree pointer */
initial_boot_params = params;
+ of_fdt_crc32 = of_fdt_get_crc32(initial_boot_params);
return true;
}
@@ -1080,27 +1092,31 @@ void __init unflatten_and_copy_device_tree(void)
unflatten_device_tree();
}
-#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
-static struct debugfs_blob_wrapper flat_dt_blob;
-
-static int __init of_flat_dt_debugfs_export_fdt(void)
+#ifdef CONFIG_SYSFS
+static ssize_t of_fdt_raw_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
{
- struct dentry *d = debugfs_create_dir("device-tree", NULL);
-
- if (!d)
- return -ENOENT;
+ memcpy(buf, initial_boot_params + off, count);
+ return count;
+}
- flat_dt_blob.data = initial_boot_params;
- flat_dt_blob.size = fdt_totalsize(initial_boot_params);
+static int __init of_fdt_raw_init(void)
+{
+ static struct bin_attribute of_fdt_raw_attr =
+ __BIN_ATTR(fdt, S_IRUSR, of_fdt_raw_read, NULL, 0);
- d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
- d, &flat_dt_blob);
- if (!d)
- return -ENOENT;
+ if (!initial_boot_params || fdt_check_header(initial_boot_params))
+ return 0;
- return 0;
+ if (of_fdt_crc32 != of_fdt_get_crc32(initial_boot_params)) {
+ pr_warn("fdt: not creating '/sys/firmware/fdt': CRC check failed");
+ return 0;
+ }
+ of_fdt_raw_attr.size = fdt_totalsize(initial_boot_params);
+ return sysfs_create_bin_file(firmware_kobj, &of_fdt_raw_attr);
}
-module_init(of_flat_dt_debugfs_export_fdt);
+late_initcall(of_fdt_raw_init);
#endif
#endif /* CONFIG_OF_EARLY_FLATTREE */