Changeset View
Changeset View
Standalone View
Standalone View
sys/geom/geom_flashmap.c
Show All 22 Lines | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * 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 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_geom.h" | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/slicer.h> | #include <sys/slicer.h> | ||||
#include <geom/geom.h> | #include <geom/geom.h> | ||||
#include <geom/geom_slice.h> | #include <geom/geom_slice.h> | ||||
#include <geom/geom_disk.h> | #include <geom/geom_disk.h> | ||||
#include <dev/nand/nand_dev.h> | #include <dev/nand/nand_dev.h> | ||||
#define FLASHMAP_CLASS_NAME "Flashmap" | #define FLASHMAP_CLASS_NAME "Flashmap" | ||||
#ifdef GEOM_FLASHMAP_ADJUST_BORDER | |||||
#define FLASHMAP_MARKER_STR ".!/bin/sh" | |||||
#define FLASHMAP_MAX_MARKER_LEN 64 | |||||
#define FLASHMAP_SEARCH_STEP (64 * 1024) | |||||
#endif | |||||
struct g_flashmap_slice { | struct g_flashmap_slice { | ||||
off_t sl_start; | off_t sl_start; | ||||
off_t sl_end; | off_t sl_end; | ||||
const char *sl_name; | const char *sl_name; | ||||
STAILQ_ENTRY(g_flashmap_slice) sl_link; | STAILQ_ENTRY(g_flashmap_slice) sl_link; | ||||
}; | }; | ||||
STAILQ_HEAD(g_flashmap_head, g_flashmap_slice); | STAILQ_HEAD(g_flashmap_head, g_flashmap_slice); | ||||
static struct { | static struct { | ||||
const char *type; | const char *type; | ||||
flash_slicer_t slicer; | flash_slicer_t slicer; | ||||
} g_flashmap_slicers[] = { | } g_flashmap_slicers[] = { | ||||
{ "NAND::device", NULL }, | { "NAND::device", NULL }, | ||||
{ "CFI::device", NULL }, | { "CFI::device", NULL }, | ||||
{ "SPI::device", NULL }, | { "SPI::device", NULL }, | ||||
{ "MMC::device", NULL } | { "MMC::device", NULL } | ||||
}; | }; | ||||
static g_ioctl_t g_flashmap_ioctl; | static g_ioctl_t g_flashmap_ioctl; | ||||
static g_taste_t g_flashmap_taste; | static g_taste_t g_flashmap_taste; | ||||
static int g_flashmap_load(device_t dev, struct g_provider *pp, | static int g_flashmap_load(device_t dev, struct g_provider *pp, | ||||
flash_slicer_t slicer, struct g_flashmap_head *head); | struct g_consumer *cp, flash_slicer_t slicer, struct g_flashmap_head *head); | ||||
static int g_flashmap_modify(struct g_geom *gp, const char *devname, | static int g_flashmap_modify(struct g_geom *gp, const char *devname, | ||||
int secsize, struct g_flashmap_head *slices); | int secsize, struct g_flashmap_head *slices); | ||||
static void g_flashmap_print(struct g_flashmap_slice *slice); | static void g_flashmap_print(struct g_flashmap_slice *slice); | ||||
MALLOC_DECLARE(M_FLASHMAP); | MALLOC_DECLARE(M_FLASHMAP); | ||||
MALLOC_DEFINE(M_FLASHMAP, "geom_flashmap", "GEOM flash memory slicer class"); | MALLOC_DEFINE(M_FLASHMAP, "geom_flashmap", "GEOM flash memory slicer class"); | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | for (i = 0; i < nitems(g_flashmap_slicers); i++) { | ||||
&size, &dev) == 0) { | &size, &dev) == 0) { | ||||
slicer = g_flashmap_slicers[i].slicer; | slicer = g_flashmap_slicers[i].slicer; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (slicer == NULL) | if (slicer == NULL) | ||||
break; | break; | ||||
if (g_flashmap_load(dev, pp, slicer, &head) == 0) | if (g_flashmap_load(dev, pp, cp, slicer, &head) == 0) | ||||
break; | break; | ||||
g_flashmap_modify(gp, cp->provider->name, | g_flashmap_modify(gp, cp->provider->name, | ||||
cp->provider->sectorsize, &head); | cp->provider->sectorsize, &head); | ||||
} while (0); | } while (0); | ||||
g_access(cp, -1, 0, 0); | g_access(cp, -1, 0, 0); | ||||
STAILQ_FOREACH_SAFE(slice, &head, sl_link, slice_temp) | STAILQ_FOREACH_SAFE(slice, &head, sl_link, slice_temp) | ||||
free(slice, M_FLASHMAP); | free(slice, M_FLASHMAP); | ||||
if (LIST_EMPTY(&gp->provider)) { | if (LIST_EMPTY(&gp->provider)) { | ||||
g_slice_spoiled(cp); | g_slice_spoiled(cp); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
return (gp); | return (gp); | ||||
} | } | ||||
#ifdef GEOM_FLASHMAP_ADJUST_BORDER | |||||
static int | static int | ||||
g_flashmap_load(device_t dev, struct g_provider *pp, flash_slicer_t slicer, | find_marker(struct g_consumer *cp, off_t *offset) | ||||
struct g_flashmap_head *head) | |||||
{ | { | ||||
mizhka: add declaration at top of file? | |||||
off_t search_start, search_offset, search_step; | |||||
uint8_t *buf; | |||||
size_t sectorsize; | |||||
char key[FLASHMAP_MAX_MARKER_LEN], search_key[FLASHMAP_MAX_MARKER_LEN]; | |||||
mizhkaUnsubmitted Not Done Inline Actions128 bytes on stack is not good, please malloc/free it. mizhka: 128 bytes on stack is not good, please malloc/free it. | |||||
int c; | |||||
search_start = *offset; | |||||
sectorsize = cp->provider->sectorsize; | |||||
search_step = FLASHMAP_SEARCH_STEP; | |||||
strcpy(search_key, FLASHMAP_MARKER_STR); | |||||
for (search_offset = search_start; | |||||
search_offset < cp->provider->mediasize; | |||||
search_offset += search_step) { | |||||
g_topology_unlock(); | |||||
buf = g_read_data(cp, search_offset, sectorsize, NULL); | |||||
g_topology_lock(); | |||||
strncpy(key, search_key, FLASHMAP_MAX_MARKER_LEN); | |||||
for (c = 0; c < FLASHMAP_MAX_MARKER_LEN && key[c]; c++) { | |||||
if (key[c] == '.') { | |||||
key[c] = buf[c]; | |||||
} | |||||
} | |||||
/* Assume buf != NULL here */ | |||||
if (memcmp(buf, key, strlen(search_key)) == 0) { | |||||
g_free(buf); | |||||
/* Marker found, so return their offset */ | |||||
if (*offset == search_offset) | |||||
return (0); | |||||
*offset = search_offset; | |||||
return (1); | |||||
} | |||||
g_free(buf); | |||||
} | |||||
printf("geom_flash map not found marker\n"); | |||||
mizhkaUnsubmitted Not Done Inline Actionsbootverbose? mizhka: bootverbose? | |||||
return (0); | |||||
} | |||||
static void | |||||
adjust_print(char *str, off_t from, off_t to) | |||||
mizhkaUnsubmitted Not Done Inline Actionsplease prefix g_flashmap_% mizhka: please prefix g_flashmap_% | |||||
{ | |||||
printf("adjust %s %08jx to %08jx\n", str, (uintmax_t)from, | |||||
(uintmax_t)to); | |||||
} | |||||
#endif | |||||
static int | |||||
g_flashmap_load(device_t dev, struct g_provider *pp, struct g_consumer *cp, | |||||
flash_slicer_t slicer, struct g_flashmap_head *head) | |||||
{ | |||||
struct flash_slice *slices; | struct flash_slice *slices; | ||||
struct g_flashmap_slice *slice; | struct g_flashmap_slice *slice; | ||||
int i, nslices = 0; | int i, nslices = 0; | ||||
slices = malloc(sizeof(struct flash_slice) * FLASH_SLICES_MAX_NUM, | slices = malloc(sizeof(struct flash_slice) * FLASH_SLICES_MAX_NUM, | ||||
M_FLASHMAP, M_WAITOK | M_ZERO); | M_FLASHMAP, M_WAITOK | M_ZERO); | ||||
if (slicer(dev, pp->name, slices, &nslices) == 0) { | if (slicer(dev, pp->name, slices, &nslices) == 0) { | ||||
for (i = 0; i < nslices; i++) { | for (i = 0; i < nslices; i++) { | ||||
slice = malloc(sizeof(struct g_flashmap_slice), | slice = malloc(sizeof(struct g_flashmap_slice), | ||||
M_FLASHMAP, M_WAITOK); | M_FLASHMAP, M_WAITOK); | ||||
slice->sl_name = slices[i].label; | slice->sl_name = slices[i].label; | ||||
slice->sl_start = slices[i].base; | slice->sl_start = slices[i].base; | ||||
slice->sl_end = slices[i].base + slices[i].size - 1; | slice->sl_end = slices[i].base + slices[i].size - 1; | ||||
#ifdef GEOM_FLASHMAP_ADJUST_BORDER | |||||
if(strcmp("kernel", slice->sl_name) == 0) { | |||||
++slice->sl_end; | |||||
if (find_marker(cp, &slice->sl_end) ) { | |||||
adjust_print("kernel end", | |||||
slices[i].base + slices[i].size - 1, | |||||
slice->sl_end - 1); | |||||
} | |||||
--slice->sl_end; | |||||
} | |||||
if(strcmp("rootfs", slice->sl_name) == 0) { | |||||
if( find_marker(cp, &slice->sl_start) ) { | |||||
adjust_print("rootfs start", | |||||
slices[i].base, | |||||
slice->sl_start); | |||||
slice->sl_end -= slice->sl_start - | |||||
slices[i].base; | |||||
} | |||||
} | |||||
#endif | |||||
STAILQ_INSERT_TAIL(head, slice, sl_link); | STAILQ_INSERT_TAIL(head, slice, sl_link); | ||||
} | } | ||||
} | } | ||||
free(slices, M_FLASHMAP); | free(slices, M_FLASHMAP); | ||||
return (nslices); | return (nslices); | ||||
} | } | ||||
Show All 19 Lines |
add declaration at top of file?