Browse Source

Improve the bootm command for CONFIG_OF_LIBFDT

In bootm, create the "/chosen" node only if it doesn't already exist
  (better matches the previous behavior).
Update for proper reserved memory map handling for initrd.
Gerald Van Baren 18 năm trước cách đây
mục cha
commit
c28abb9c61
2 tập tin đã thay đổi với 77 bổ sung13 xóa
  1. 48 8
      common/cmd_bootm.c
  2. 29 5
      common/fdt_support.c

+ 48 - 8
common/cmd_bootm.c

@@ -37,6 +37,7 @@
 #if defined(CONFIG_OF_LIBFDT)
 #include <fdt.h>
 #include <libfdt.h>
+#include <fdt_support.h>
 #endif
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
@@ -748,7 +749,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 		of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);
 		hdr = (image_header_t *)of_flat_tree;
 #if defined(CONFIG_OF_LIBFDT)
-		if (be32_to_cpu(fdt_magic(of_flat_tree)) == FDT_MAGIC) {
+		if (fdt_check_header(of_flat_tree) == 0) {
 #else
 		if (*(ulong *)of_flat_tree == OF_DT_HEADER) {
 #endif
@@ -795,7 +796,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 				return;
 			}
 #if defined(CONFIG_OF_LIBFDT)
-			if (be32_to_cpu(fdt_magic(of_flat_tree + sizeof(image_header_t))) != FDT_MAGIC) {
+			if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) == 0) {
 #else
 			if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) {
 #endif
@@ -836,7 +837,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 		}
 
 #if defined(CONFIG_OF_LIBFDT)
-		if (be32_to_cpu(fdt_magic(of_data)) != FDT_MAGIC) {
+		if (fdt_check_header((void *)of_data) != 0) {
 #else
 		if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) {
 #endif
@@ -937,23 +938,44 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	if (of_data) {
 		int err;
 		ulong of_start, of_len;
+
 		of_len = be32_to_cpu(fdt_totalsize(of_data));
-		/* provide extra 8k pad */
+		/* position on a 4K boundary before the initrd/kbd */
 		if (initrd_start)
-			of_start = initrd_start - of_len - 8192;
+			of_start = initrd_start - of_len;
 		else
-			of_start  = (ulong)kbd - of_len - 8192;
+			of_start  = (ulong)kbd - of_len;
 		of_start &= ~(4096 - 1);	/* align on page */
 		debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
 			of_data, of_data + of_len - 1, of_len, of_len);
 
-
+		of_flat_tree = (char *)of_start;
 		printf ("   Loading Device Tree to %08lx, end %08lx ... ",
 			of_start, of_start + of_len - 1);
 		err = fdt_open_into((void *)of_start, (void *)of_data, of_len);
 		if (err != 0) {
-			printf ("libfdt: %s\n", fdt_strerror(err));
+			printf ("libfdt: %s " __FILE__ " %d\n", fdt_strerror(err), __LINE__);
 		}
+		/*
+		 * Add the chosen node if it doesn't exist, add the env and bd_t
+		 * if the user wants it (the logic is in the subroutines).
+		 */
+		if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) {
+				printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree);
+				return;
+		}
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+		if (fdt_env(of_flat_tree) < 0) {
+				printf("Failed creating the /u-boot-env node, aborting.\n");
+				return;
+		}
+#endif
+#ifdef CONFIG_OF_HAS_BD_T
+		if (fdt_bd_t(of_flat_tree) < 0) {
+				printf("Failed creating the /bd_t node, aborting.\n");
+				return;
+		}
+#endif
 	}
 #endif
 #if defined(CONFIG_OF_FLAT_TREE)
@@ -1004,6 +1026,24 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
 	/* ft_dump_blob(of_flat_tree); */
 #endif
+#if defined(CONFIG_OF_LIBFDT)
+	if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) {
+		printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree);
+		return;
+	}
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+	if (fdt_env(of_flat_tree) < 0) {
+		printf("Failed creating the /u-boot-env node, aborting.\n");
+		return;
+	}
+#endif
+#ifdef CONFIG_OF_HAS_BD_T
+	if (fdt_bd_t(of_flat_tree) < 0) {
+		printf("Failed creating the /bd_t node, aborting.\n");
+		return;
+	}
+#endif
+#endif /* if defined(CONFIG_OF_LIBFDT) */
 
 	(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
 #endif

+ 29 - 5
common/fdt_support.c

@@ -55,9 +55,33 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 		return err;
 	}
 
-#warning "Don't double-add the reserved map"
 	if (initrd_start && initrd_end) {
-		err = fdt_add_reservemap_entry(fdt,
+		struct fdt_reserve_entry *re;
+		int  used;
+		int  total;
+		int  j;
+
+		err = fdt_num_reservemap(fdt, &used, &total);
+		if (err < 0) {
+			printf("libfdt: %s\n", fdt_strerror(err));
+			return err;
+		}
+		if (used >= total) {
+			printf("fdt_chosen: no room in the reserved map (%d of %d)\n",
+				used, total);
+			return -1;
+		}
+		/*
+		 * Look for an existing entry and update it.  If we don't find
+		 * the entry, we will j be the next available slot.
+		 */
+		for (j = 0; j < used; j++) {
+			err = fdt_get_reservemap(fdt, j, &re);
+			if (re->address == initrd_start) {
+				break;
+			}
+		}
+		err = fdt_replace_reservemap_entry(fdt, j,
 			initrd_start, initrd_end - initrd_start + 1);
 		if (err < 0) {
 			printf("libfdt: %s\n", fdt_strerror(err));
@@ -202,13 +226,13 @@ int fdt_env(void *fdt)
 			continue;
 		err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1);
 		if (err < 0) {
-			printf("libfdt: %s\n", lval, fdt_strerror(err));
+			printf("libfdt: %s\n", fdt_strerror(err));
 			return err;
 		}
 	}
 	return 0;
 }
-#endif /* CONFIG_OF_HAS_UBOOT_ENV */
+#endif /* ifdef CONFIG_OF_HAS_UBOOT_ENV */
 
 /********************************************************************/
 
@@ -318,6 +342,6 @@ int fdt_bd_t(void *fdt)
 
 	return 0;
 }
-#endif /* CONFIG_OF_HAS_BD_T */
+#endif /* ifdef CONFIG_OF_HAS_BD_T */
 
 #endif /* CONFIG_OF_LIBFDT */