"Das U-Boot" Source Tree
at master 201 lines 4.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (c) Copyright 2016 by VRT Technology 4 * 5 * Author: 6 * Stuart Longland <stuartl@vrt.com.au> 7 * 8 * Based on FAT environment driver 9 * (c) Copyright 2011 by Tigris Elektronik GmbH 10 * 11 * Author: 12 * Maximilian Schwerin <mvs@tigris.de> 13 * 14 * and EXT4 filesystem implementation 15 * (C) Copyright 2011 - 2012 Samsung Electronics 16 * EXT4 filesystem implementation in Uboot by 17 * Uma Shankar <uma.shankar@samsung.com> 18 * Manjunatha C Achar <a.manjunatha@samsung.com> 19 */ 20 21#include <part.h> 22 23#include <command.h> 24#include <env.h> 25#include <env_internal.h> 26#include <linux/stddef.h> 27#include <malloc.h> 28#include <memalign.h> 29#include <search.h> 30#include <errno.h> 31#include <ext4fs.h> 32#include <mmc.h> 33#include <scsi.h> 34#include <virtio.h> 35#include <asm/global_data.h> 36 37DECLARE_GLOBAL_DATA_PTR; 38 39__weak const char *env_ext4_get_intf(void) 40{ 41 return (const char *)CONFIG_ENV_EXT4_INTERFACE; 42} 43 44__weak const char *env_ext4_get_dev_part(void) 45{ 46#ifdef CONFIG_MMC 47 static char *part_str; 48 49 if (!part_str) { 50 part_str = CONFIG_ENV_EXT4_DEVICE_AND_PART; 51 if (!strcmp(CONFIG_ENV_EXT4_INTERFACE, "mmc") && part_str[0] == ':') { 52 part_str = "0" CONFIG_ENV_EXT4_DEVICE_AND_PART; 53 part_str[0] += mmc_get_env_dev(); 54 } 55 } 56 57 return part_str; 58#else 59 return (const char *)CONFIG_ENV_EXT4_DEVICE_AND_PART; 60#endif 61} 62 63static int env_ext4_save_buffer(env_t *env_new) 64{ 65 struct blk_desc *dev_desc = NULL; 66 struct disk_partition info; 67 int dev, part; 68 int err; 69 const char *ifname = env_ext4_get_intf(); 70 const char *dev_and_part = env_ext4_get_dev_part(); 71 72 part = blk_get_device_part_str(ifname, dev_and_part, 73 &dev_desc, &info, 1); 74 if (part < 0) 75 return 1; 76 77 dev = dev_desc->devnum; 78 ext4fs_set_blk_dev(dev_desc, &info); 79 80 if (!ext4fs_mount()) { 81 printf("\n** Unable to use %s %s for saveenv **\n", 82 ifname, dev_and_part); 83 return 1; 84 } 85 86 err = ext4fs_write(CONFIG_ENV_EXT4_FILE, (void *)env_new, 87 sizeof(env_t), FILETYPE_REG); 88 ext4fs_close(); 89 90 if (err == -1) { 91 printf("\n** Unable to write \"%s\" from %s%d:%d **\n", 92 CONFIG_ENV_EXT4_FILE, ifname, dev, part); 93 return 1; 94 } 95 96 return 0; 97} 98 99static int env_ext4_save(void) 100{ 101 env_t env_new; 102 int err; 103 104 err = env_export(&env_new); 105 if (err) 106 return err; 107 108 err = env_ext4_save_buffer(&env_new); 109 if (err) 110 return err; 111 112 gd->env_valid = ENV_VALID; 113 puts("done\n"); 114 115 return 0; 116} 117 118static int env_ext4_erase(void) 119{ 120 env_t env_new; 121 int err; 122 123 memset(&env_new, 0, sizeof(env_t)); 124 125 err = env_ext4_save_buffer(&env_new); 126 if (err) 127 return err; 128 129 gd->env_valid = ENV_INVALID; 130 puts("done\n"); 131 132 return 0; 133} 134 135static int env_ext4_load(void) 136{ 137 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); 138 struct blk_desc *dev_desc = NULL; 139 struct disk_partition info; 140 int dev, part; 141 int err; 142 loff_t off; 143 const char *ifname = env_ext4_get_intf(); 144 const char *dev_and_part = env_ext4_get_dev_part(); 145 146#ifdef CONFIG_MMC 147 if (!strcmp(ifname, "mmc")) 148 mmc_initialize(NULL); 149#endif 150#if defined(CONFIG_AHCI) || defined(CONFIG_SCSI) 151 if (!strcmp(ifname, "scsi")) 152 scsi_scan(true); 153#endif 154#if defined(CONFIG_VIRTIO) 155 if (!strcmp(ifname, "virtio")) 156 virtio_init(); 157#endif 158 159 part = blk_get_device_part_str(ifname, dev_and_part, 160 &dev_desc, &info, 1); 161 if (part < 0) 162 goto err_env_relocate; 163 164 dev = dev_desc->devnum; 165 ext4fs_set_blk_dev(dev_desc, &info); 166 167 if (!ext4fs_mount()) { 168 printf("\n** Unable to use %s %s for loading the env **\n", 169 ifname, dev_and_part); 170 goto err_env_relocate; 171 } 172 173 err = ext4_read_file(CONFIG_ENV_EXT4_FILE, buf, 0, CONFIG_ENV_SIZE, 174 &off); 175 ext4fs_close(); 176 177 if (err == -1) { 178 printf("\n** Unable to read \"%s\" from %s%d:%d **\n", 179 CONFIG_ENV_EXT4_FILE, ifname, dev, part); 180 goto err_env_relocate; 181 } 182 183 err = env_import(buf, 1, H_EXTERNAL); 184 if (!err) 185 gd->env_valid = ENV_VALID; 186 187 return err; 188 189err_env_relocate: 190 env_set_default(NULL, 0); 191 192 return -EIO; 193} 194 195U_BOOT_ENV_LOCATION(ext4) = { 196 .location = ENVL_EXT4, 197 ENV_NAME("EXT4") 198 .load = env_ext4_load, 199 .save = ENV_SAVE_PTR(env_ext4_save), 200 .erase = ENV_ERASE_PTR(env_ext4_erase), 201};