[PATCH] debug nvram

From: Pan Xinhui
Date: Thu Dec 10 2015 - 23:36:57 EST


Signed-off-by: Pan Xinhui <xinhui.pan@xxxxxxxxxxxxxxxxxx>
---
arch/powerpc/kernel/nvram_64.c | 53 ++++++++++++++++++++++++++++++++----------
1 file changed, 41 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index a8939f5..4d91654 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -36,6 +36,13 @@
#include <asm/machdep.h>

#undef DEBUG_NVRAM
+#define DEBUG_NVRAM
+struct x{
+ char name[12];
+ unsigned int size;
+};
+#define IOC_NVRAM_CREATE _IOWR('p', 0x44, struct x)
+#define IOC_NVRAM_REMOVE _IOWR('p', 0x45, struct x)

#define NVRAM_HEADER_LEN sizeof(struct nvram_header)
#define NVRAM_BLOCK_LEN NVRAM_HEADER_LEN
@@ -843,9 +850,12 @@ out:

}

+static void nvram_print_partitions(char * label);
+
static long dev_nvram_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
+ int remove = 0;
switch(cmd) {
#ifdef CONFIG_PPC_PMAC
case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
@@ -867,6 +877,25 @@ static long dev_nvram_ioctl(struct file *file, unsigned int cmd,
return 0;
}
#endif /* CONFIG_PPC_PMAC */
+ case IOC_NVRAM_REMOVE:
+ remove = 1;
+ case IOC_NVRAM_CREATE: {
+ struct x h;
+ if (copy_from_user(&h, (void __user*)arg, sizeof(h)) != 0) {
+ printk("XINHUI: %s fails\n", __func__);
+ return 0;
+ }
+ printk("XINHUI: %s, [%s],[%d]\n", __func__, h.name, h.size);
+ if (remove == 0)
+ nvram_create_partition(h.name, 0xef, h.size, 0x100);
+ else
+ nvram_remove_partition(h.name, 0xef, NULL);
+ }
+
+#ifdef DEBUG_NVRAM
+ nvram_print_partitions("NVRAM Partitions");
+#endif
+ return 0;
default:
return -EINVAL;
}
@@ -878,6 +907,7 @@ const struct file_operations nvram_fops = {
.read = dev_nvram_read,
.write = dev_nvram_write,
.unlocked_ioctl = dev_nvram_ioctl,
+ .compat_ioctl = dev_nvram_ioctl,
};

static struct miscdevice nvram_dev = {
@@ -888,7 +918,7 @@ static struct miscdevice nvram_dev = {


#ifdef DEBUG_NVRAM
-static void __init nvram_print_partitions(char * label)
+static void nvram_print_partitions(char * label)
{
struct nvram_partition * tmp_part;

@@ -904,7 +934,7 @@ static void __init nvram_print_partitions(char * label)
#endif


-static int __init nvram_write_header(struct nvram_partition * part)
+static int nvram_write_header(struct nvram_partition * part)
{
loff_t tmp_index;
int rc;
@@ -920,7 +950,7 @@ static int __init nvram_write_header(struct nvram_partition * part)
}


-static unsigned char __init nvram_checksum(struct nvram_header *p)
+static unsigned char nvram_checksum(struct nvram_header *p)
{
unsigned int c_sum, c_sum2;
unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */
@@ -965,7 +995,7 @@ static int nvram_can_remove_partition(struct nvram_partition *part,
* leave these alone.
*/

-int __init nvram_remove_partition(const char *name, int sig,
+int nvram_remove_partition(const char *name, int sig,
const char *exceptions[])
{
struct nvram_partition *part, *prev, *tmp;
@@ -1023,7 +1053,7 @@ int __init nvram_remove_partition(const char *name, int sig,
* you need to query for the actual size yourself after the
* call using nvram_partition_get_size().
*/
-loff_t __init nvram_create_partition(const char *name, int sig,
+loff_t nvram_create_partition(const char *name, int sig,
int req_size, int min_size)
{
struct nvram_partition *part;
--
2.5.0


*user-space* codes:

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <linux/ioctl.h>

struct x{
char name[12];
unsigned int size;
};

#define IOC_NVRAM_CREATE _IOWR('p', 0x44, struct x)
#define IOC_NVRAM_REMOVE _IOWR('p', 0x45, struct x)

void main(int argc, char *argv[])
{
int fd;
unsigned int cmd;
struct x h;

fd = open("/dev/nvram", O_RDWR);
if (fd < 0) {
printf("fails open\n");
return;
}

cmd = atoi(argv[1]);
if (cmd == 0)
cmd = IOC_NVRAM_CREATE;
else
cmd = IOC_NVRAM_REMOVE;

strncpy(h.name, argv[2], 12);

if (cmd == IOC_NVRAM_CREATE)
h.size = atoi(argv[3]);

printf("%s, %d\n", h.name, h.size);

if (ioctl(fd, cmd, &h) < 0) {
printf("fails ioctl\n");
return;
}
close(fd);
return;
}



any comments are welcome :)

thanks
xinhui

On 2015å¹´12æ??10æ?¥ 15:30, xinhui wrote:
> From: Pan Xinhui <xinhui.pan@xxxxxxxxxxxxxxxxxx>
>
> When we merge two contiguous partitions whose signatures are marked
> NVRAM_SIG_FREE, We need update prev's length and checksum, then write it
> to nvram, not cur's. So lets fix this mistake now.
>
> Also use memset instead of strncpy to set the partition's name. It's
> more readable if we want to fill up with duplicate chars .
>
> Signed-off-by: Pan Xinhui <xinhui.pan@xxxxxxxxxxxxxxxxxx>
> ---
> arch/powerpc/kernel/nvram_64.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
> index 21a278b7..40e80ca 100644
> --- a/arch/powerpc/kernel/nvram_64.c
> +++ b/arch/powerpc/kernel/nvram_64.c
> @@ -969,7 +969,7 @@ int __init nvram_remove_partition(const char *name, int sig,
>
> /* Make partition a free partition */
> part->header.signature = NVRAM_SIG_FREE;
> - strncpy(part->header.name, "wwwwwwwwwwww", 12);
> + memset(part->header.name, 'w', 12);
> part->header.checksum = nvram_checksum(&part->header);
> rc = nvram_write_header(part);
> if (rc <= 0) {
> @@ -987,8 +987,8 @@ int __init nvram_remove_partition(const char *name, int sig,
> }
> if (prev) {
> prev->header.length += part->header.length;
> - prev->header.checksum = nvram_checksum(&part->header);
> - rc = nvram_write_header(part);
> + prev->header.checksum = nvram_checksum(&prev->header);
> + rc = nvram_write_header(prev);
> if (rc <= 0) {
> printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
> return rc;
>

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/