From d460c8cafdbbae6a7aea6b09f30f38d209defe62 Mon Sep 17 00:00:00 2001 From: Greg Haerr Date: Tue, 17 Sep 2024 13:37:01 -0600 Subject: [PATCH 1/3] Reformat mem.c --- elks/arch/i86/drivers/char/mem.c | 172 +++++++++++++++---------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/elks/arch/i86/drivers/char/mem.c b/elks/arch/i86/drivers/char/mem.c index 9c28b8c27..320b33413 100644 --- a/elks/arch/i86/drivers/char/mem.c +++ b/elks/arch/i86/drivers/char/mem.c @@ -29,12 +29,12 @@ #include #include -#define DEV_MEM_MINOR 1 /* unused */ -#define DEV_KMEM_MINOR 2 -#define DEV_NULL_MINOR 3 -#define DEV_PORT_MINOR 4 -#define DEV_ZERO_MINOR 5 -#define DEV_FULL_MINOR 6 /* unused */ +#define DEV_MEM_MINOR 1 /* unused */ +#define DEV_KMEM_MINOR 2 +#define DEV_NULL_MINOR 3 +#define DEV_PORT_MINOR 4 +#define DEV_ZERO_MINOR 5 +#define DEV_FULL_MINOR 6 /* unused */ /* * generally useful code... @@ -45,15 +45,15 @@ static int memory_lseek(struct inode *inode, struct file *filp, loff_t offset, debugmem("mem_lseek()\n"); switch (origin) { case 1: - offset += filp->f_pos; + offset += filp->f_pos; case 0: - if (offset >= 0) - break; + if (offset >= 0) + break; default: - return -EINVAL; + return -EINVAL; } if (offset != filp->f_pos) { - filp->f_pos = offset; + filp->f_pos = offset; } return 0; } @@ -135,7 +135,7 @@ size_t port_read(struct inode *inode, struct file *filp, char *data, size_t len) return i; } #else -# define port_read NULL +# define port_read NULL #endif #if defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) @@ -156,7 +156,7 @@ size_t port_write(struct inode *inode, struct file *filp, char *data, size_t len return i; } #else -# define port_write NULL +# define port_write NULL #endif #if UNUSED @@ -228,98 +228,98 @@ int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg) switch (cmd) { case MEM_GETTASK: - retword = (unsigned short)task; - break; + retword = (unsigned short)task; + break; case MEM_GETMAXTASKS: - retword = max_tasks; - break; + retword = max_tasks; + break; case MEM_GETCS: - retword = kernel_cs; - break; + retword = kernel_cs; + break; case MEM_GETDS: - retword = kernel_ds; - break; + retword = kernel_ds; + break; case MEM_GETFARTEXT: retword = (unsigned)((long)buffer_init >> 16); break; case MEM_GETUSAGE: - mm_get_usage (&(mu.free_memory), &(mu.used_memory)); - memcpy_tofs(arg, &mu, sizeof(struct mem_usage)); - return 0; + mm_get_usage (&(mu.free_memory), &(mu.used_memory)); + memcpy_tofs(arg, &mu, sizeof(struct mem_usage)); + return 0; case MEM_GETHEAP: - retword = (unsigned short) &_heap_all; - break; + retword = (unsigned short) &_heap_all; + break; case MEM_GETJIFFADDR: - retword = (unsigned short) &jiffies; + retword = (unsigned short) &jiffies; break; case MEM_GETUPTIME: #ifdef CONFIG_CPU_USAGE - retword = (unsigned short) &uptime; - break; + retword = (unsigned short) &uptime; + break; #endif default: - return -EINVAL; + return -EINVAL; } put_user(retword, arg); return 0; } static struct file_operations null_fops = { - null_lseek, /* lseek */ - null_read, /* read */ - null_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ + null_lseek, /* lseek */ + null_read, /* read */ + null_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; #if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) static struct file_operations port_fops = { - port_lseek, /* lseek */ - port_read, /* read */ - port_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ + port_lseek, /* lseek */ + port_read, /* read */ + port_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; #endif static struct file_operations zero_fops = { - memory_lseek, /* lseek */ - zero_read, /* read */ - null_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ + memory_lseek, /* lseek */ + zero_read, /* read */ + null_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; static struct file_operations kmem_fops = { - memory_lseek, /* lseek */ - kmem_read, /* read */ - kmem_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - kmem_ioctl, /* ioctl */ - NULL, /* open */ - NULL /* release */ + memory_lseek, /* lseek */ + kmem_read, /* read */ + kmem_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + kmem_ioctl, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; #if UNUSED static struct file_operations full_fops = { - memory_lseek, /* lseek */ - full_read, /* read */ - full_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ + memory_lseek, /* lseek */ + full_read, /* read */ + full_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; #endif @@ -329,38 +329,38 @@ static struct file_operations full_fops = { int memory_open(register struct inode *inode, struct file *filp) { static struct file_operations *mdev_fops[] = { - NULL, - &kmem_fops, /* DEV_MEM_MINOR */ - &kmem_fops, /* DEV_KMEM_MINOR */ - &null_fops, /* DEV_NULL_MINOR */ + NULL, + &kmem_fops, /* DEV_MEM_MINOR */ + &kmem_fops, /* DEV_KMEM_MINOR */ + &null_fops, /* DEV_NULL_MINOR */ #if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) - &port_fops, /* DEV_PORT_MINOR */ + &port_fops, /* DEV_PORT_MINOR */ #else NULL, #endif - &zero_fops, /* DEV_ZERO_MINOR */ + &zero_fops, /* DEV_ZERO_MINOR */ #if UNUSED - &full_fops /* DEV_FULL_MINOR */ + &full_fops /* DEV_FULL_MINOR */ #endif }; unsigned int minor; minor = MINOR(inode->i_rdev); if (minor > 5 || !mdev_fops[minor]) - return -ENXIO; + return -ENXIO; filp->f_op = mdev_fops[minor]; return 0; } static struct file_operations memory_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - memory_open, /* open */ - NULL /* release */ + NULL, /* lseek */ + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + memory_open, /* open */ + NULL /* release */ }; void INITPROC mem_dev_init(void) From 1d05b2fcdcc0685a29451fa176b5f8c720fdfd38 Mon Sep 17 00:00:00 2001 From: Greg Haerr Date: Tue, 17 Sep 2024 16:07:33 -0600 Subject: [PATCH 2/3] Add meminfo -m option to display sorted main memory segments --- elks/arch/i86/drivers/char/mem.c | 320 +++++++++++++------------------ elks/arch/i86/mm/malloc.c | 2 +- elks/include/linuxmt/mem.h | 19 +- elks/include/linuxmt/mm.h | 4 +- elkscmd/sys_utils/meminfo.c | 88 ++++++--- 5 files changed, 208 insertions(+), 225 deletions(-) diff --git a/elks/arch/i86/drivers/char/mem.c b/elks/arch/i86/drivers/char/mem.c index 320b33413..0717d3e9e 100644 --- a/elks/arch/i86/drivers/char/mem.c +++ b/elks/arch/i86/drivers/char/mem.c @@ -34,194 +34,62 @@ #define DEV_NULL_MINOR 3 #define DEV_PORT_MINOR 4 #define DEV_ZERO_MINOR 5 -#define DEV_FULL_MINOR 6 /* unused */ - -/* - * generally useful code... - */ -static int memory_lseek(struct inode *inode, struct file *filp, loff_t offset, - unsigned int origin) -{ - debugmem("mem_lseek()\n"); - switch (origin) { - case 1: - offset += filp->f_pos; - case 0: - if (offset >= 0) - break; - default: - return -EINVAL; - } - if (offset != filp->f_pos) { - filp->f_pos = offset; - } - return 0; -} +#define DEV_MAX_MINOR 5 /* * /dev/null code */ -int null_lseek(struct inode *inode, struct file *filp, off_t offset, int origin) +static int null_lseek(struct inode *inode, struct file *filp, loff_t offset, int origin) { - debugmem("null_lseek()\n"); filp->f_pos = 0; return 0; } -size_t null_read(struct inode *inode, struct file *filp, char *data, size_t len) -{ - debugmem("null_read()\n"); - return 0; -} - -size_t null_write(struct inode *inode, struct file *filp, char *data, size_t len) -{ - debugmem("null write: ignoring %d bytes!\n", len); - return len; -} - -/* - * /dev/port code - */ -#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) -int port_lseek(struct inode *inode, struct file *filp, off_t offset, int origin) +static size_t null_read(struct inode *inode, struct file *filp, char *data, size_t len) { - debugmem("port_lseek()\n"); - - switch (origin) - { - case 0: /* SEEK_SET */ - break; - - case 1: /* SEEK_CUR */ - offset += filp->f_pos; - break; - - case 2: /* SEEK_END */ - offset = port_MAX + offset; - break; - - default: - return -EINVAL; - } - - if(offset < 0) - offset = 0; - else if(offset > port_MAX) - offset = port_MAX; - - filp->f_pos = offset; - debugmem("port_lseek: 0x%02X\n", (unsigned)filp->f_pos); - return 0; } -#endif - -#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) -size_t port_read(struct inode *inode, struct file *filp, char *data, size_t len) -{ - size_t i; - - debugmem("port_read()\n"); - - for (i = 0; i < len && filp->f_pos < port_MAX; i++) - { - put_user_char(inb((unsigned)filp->f_pos++), (void *)(data++)); - debugmem("port_read(0x%02X) = %02X\n", - (unsigned)filp->f_pos - 1, - (unsigned)(((unsigned char *)data)[-1])); - } - - return i; -} -#else -# define port_read NULL -#endif - -#if defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) -size_t port_write(struct inode *inode, struct file *filp, char *data, size_t len) -{ - size_t i; - - debugmem("port_write\n"); - - for (i = 0; i < len && filp->f_pos < port_MAX; i++) - { - debugmem("port: write(0x%02X) = %02X\n", - (unsigned)filp->f_pos, - (unsigned)get_user_char((void *)data)); - outb(get_user_char((void *)data++), (unsigned)filp->f_pos++); - } - - return i; -} -#else -# define port_write NULL -#endif -#if UNUSED -/* - * /dev/full code - */ -size_t full_read(struct inode *inode, struct file *filp, char *data, size_t len) +static size_t null_write(struct inode *inode, struct file *filp, char *data, size_t len) { - debugmem("full_read()\n"); - filp->f_pos += len; return len; } -size_t full_write(struct inode *inode, struct file *filp, char *data, size_t len) -{ - debugmem("full_write: objecting to %d bytes!\n", len); - return -ENOSPC; -} -#endif - /* * /dev/zero code */ -size_t zero_read(struct inode *inode, struct file *filp, char *data, size_t len) +static size_t zero_read(struct inode *inode, struct file *filp, char *data, size_t len) { - debugmem("zero_read()\n"); fmemsetb(data, current->t_regs.ds, 0, len); filp->f_pos += len; - return (size_t)len; -} - -static unsigned short int split_seg_off(unsigned short int *offset, long int posn) -{ - *offset = (unsigned short int) (((unsigned long int) posn) & 0xF); - return (unsigned short int) (((unsigned long int) posn) >> 4); + return len; } /* * /dev/kmem code */ -size_t kmem_read(struct inode *inode, register struct file *filp, char *data, size_t len) +static size_t kmem_read(struct inode *inode, struct file *filp, char *data, size_t len) { - unsigned short int sseg, soff; + seg_t sseg = (unsigned long)filp->f_pos >> 4; + segext_t soff = filp->f_pos & 0x0F; - debugmem("kmem_read()\n"); - sseg = split_seg_off(&soff, filp->f_pos); - debugmem("Reading %u %p %p.\n", len, sseg, soff); fmemcpyb((byte_t *)data, current->t_regs.ds, (byte_t *)soff, sseg, (word_t) len); filp->f_pos += len; - return (size_t) len; + return len; } -size_t kmem_write(struct inode *inode, register struct file *filp, char *data, size_t len) +static size_t kmem_write(struct inode *inode, struct file *filp, char *data, size_t len) { - unsigned short int dseg, doff; + seg_t dseg = (unsigned long)filp->f_pos >> 4; + segext_t doff = filp->f_pos & 0x0F; - debugmem("kmem_write()\n"); - dseg = split_seg_off(&doff, filp->f_pos); - debugmem("Writing to %d:%d\n", dseg, doff); + /* FIXME: very dangerous! */ fmemcpyb((byte_t *)doff, dseg, (byte_t *)data, current->t_regs.ds, (word_t) len); filp->f_pos += len; return len; } -int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg) +static int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg) { unsigned short retword; struct mem_usage mu; @@ -252,11 +120,15 @@ int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg) case MEM_GETJIFFADDR: retword = (unsigned short) &jiffies; break; + case MEM_GETSEGALL: + retword = (unsigned short) &_seg_all; + break; case MEM_GETUPTIME: #ifdef CONFIG_CPU_USAGE retword = (unsigned short) &uptime; break; #endif + /* fall thru */ default: return -EINVAL; } @@ -264,18 +136,100 @@ int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg) return 0; } -static struct file_operations null_fops = { - null_lseek, /* lseek */ - null_read, /* read */ - null_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ -}; +static int memory_lseek(struct inode *inode, struct file *filp, loff_t offset, int origin) +{ + switch (origin) { + case 1: + offset += filp->f_pos; + /* fall thru */ + case 0: + if (offset >= 0) + break; + default: + return -EINVAL; + } + filp->f_pos = offset; + return 0; +} + +/* + * /dev/port code + */ +#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) +static size_t port_read(struct inode *inode, struct file *filp, char *data, size_t len) +{ + size_t i; + + debugmem("port_read()\n"); + + for (i = 0; i < len && filp->f_pos < port_MAX; i++) + { + put_user_char(inb((unsigned)filp->f_pos++), (void *)(data++)); + debugmem("port_read(0x%02X) = %02X\n", + (unsigned)filp->f_pos - 1, + (unsigned)(((unsigned char *)data)[-1])); + } + + return i; +} +#else +# define port_read NULL +#endif + +#if defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) +static size_t port_write(struct inode *inode, struct file *filp, char *data, size_t len) +{ + size_t i; + + debugmem("port_write\n"); + + for (i = 0; i < len && filp->f_pos < port_MAX; i++) + { + debugmem("port: write(0x%02X) = %02X\n", + (unsigned)filp->f_pos, + (unsigned)get_user_char((void *)data)); + outb(get_user_char((void *)data++), (unsigned)filp->f_pos++); + } + + return i; +} +#else +# define port_write NULL +#endif #if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) +static int port_lseek(struct inode *inode, struct file *filp, loff_t offset, int origin) +{ + debugmem("port_lseek()\n"); + + switch (origin) + { + case 0: /* SEEK_SET */ + break; + + case 1: /* SEEK_CUR */ + offset += filp->f_pos; + break; + + case 2: /* SEEK_END */ + offset = port_MAX + offset; + break; + + default: + return -EINVAL; + } + + if(offset < 0) + offset = 0; + else if(offset > port_MAX) + offset = port_MAX; + + filp->f_pos = offset; + debugmem("port_lseek: 0x%02X\n", (unsigned)filp->f_pos); + + return 0; +} + static struct file_operations port_fops = { port_lseek, /* lseek */ port_read, /* read */ @@ -288,6 +242,17 @@ static struct file_operations port_fops = { }; #endif +static struct file_operations null_fops = { + null_lseek, /* lseek */ + null_read, /* read */ + null_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ +}; + static struct file_operations zero_fops = { memory_lseek, /* lseek */ zero_read, /* read */ @@ -310,43 +275,28 @@ static struct file_operations kmem_fops = { NULL /* release */ }; -#if UNUSED -static struct file_operations full_fops = { - memory_lseek, /* lseek */ - full_read, /* read */ - full_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ -}; +static struct file_operations *mdev_fops[] = { + NULL, + &kmem_fops, /* DEV_MEM_MINOR */ + &kmem_fops, /* DEV_KMEM_MINOR */ + &null_fops, /* DEV_NULL_MINOR */ +#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) + &port_fops, /* DEV_PORT_MINOR */ +#else + NULL, #endif + &zero_fops, /* DEV_ZERO_MINOR */ +}; /* * memory device open multiplexor */ -int memory_open(register struct inode *inode, struct file *filp) +static int memory_open(struct inode *inode, struct file *filp) { - static struct file_operations *mdev_fops[] = { - NULL, - &kmem_fops, /* DEV_MEM_MINOR */ - &kmem_fops, /* DEV_KMEM_MINOR */ - &null_fops, /* DEV_NULL_MINOR */ -#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) - &port_fops, /* DEV_PORT_MINOR */ -#else - NULL, -#endif - &zero_fops, /* DEV_ZERO_MINOR */ -#if UNUSED - &full_fops /* DEV_FULL_MINOR */ -#endif - }; unsigned int minor; minor = MINOR(inode->i_rdev); - if (minor > 5 || !mdev_fops[minor]) + if (minor > DEV_MAX_MINOR || !mdev_fops[minor]) return -ENXIO; filp->f_op = mdev_fops[minor]; return 0; diff --git a/elks/arch/i86/mm/malloc.c b/elks/arch/i86/mm/malloc.c index 2c69576a8..cd130bbbf 100644 --- a/elks/arch/i86/mm/malloc.c +++ b/elks/arch/i86/mm/malloc.c @@ -22,7 +22,7 @@ // and to ease the 286 protected mode // whenever that mode comes back one day -static list_s _seg_all; +list_s _seg_all; static list_s _seg_free; diff --git a/elks/include/linuxmt/mem.h b/elks/include/linuxmt/mem.h index 1051cc623..93d219175 100644 --- a/elks/include/linuxmt/mem.h +++ b/elks/include/linuxmt/mem.h @@ -1,20 +1,21 @@ #ifndef __LINUXMT_MEM_H #define __LINUXMT_MEM_H -#define MEM_GETTEXTSIZ 2 -#define MEM_GETUSAGE 3 -#define MEM_GETTASK 4 -#define MEM_GETDS 5 -#define MEM_GETCS 6 -#define MEM_GETHEAP 7 -#define MEM_GETUPTIME 8 +#define MEM_GETTEXTSIZ 2 +#define MEM_GETUSAGE 3 +#define MEM_GETTASK 4 +#define MEM_GETDS 5 +#define MEM_GETCS 6 +#define MEM_GETHEAP 7 +#define MEM_GETUPTIME 8 #define MEM_GETFARTEXT 9 #define MEM_GETMAXTASKS 10 #define MEM_GETJIFFADDR 11 +#define MEM_GETSEGALL 12 struct mem_usage { - unsigned int free_memory; - unsigned int used_memory; + unsigned int free_memory; + unsigned int used_memory; }; #endif diff --git a/elks/include/linuxmt/mm.h b/elks/include/linuxmt/mm.h index 3fdd61701..0d83aaaec 100644 --- a/elks/include/linuxmt/mm.h +++ b/elks/include/linuxmt/mm.h @@ -56,13 +56,13 @@ int fs_memcmp(const void *,const void *,size_t); segment_s * seg_alloc (segext_t, word_t); void seg_free (segment_s *); - segment_s * seg_get (segment_s *); void seg_put (segment_s *); segment_s * seg_dup (segment_s *); - void seg_free_pid(pid_t pid); +extern list_s _seg_all; + void mm_get_usage (unsigned int * free, unsigned int * used); #endif /* __KERNEL__ */ diff --git a/elkscmd/sys_utils/meminfo.c b/elkscmd/sys_utils/meminfo.c index 225ab55c0..19dfd42bb 100644 --- a/elkscmd/sys_utils/meminfo.c +++ b/elkscmd/sys_utils/meminfo.c @@ -28,10 +28,12 @@ int fflag; /* show free memory*/ int tflag; /* show tty and driver memory*/ int bflag; /* show buffer memory*/ int sflag; /* show system memory*/ +int mflag; /* show main memory*/ int allflag; /* show all memory*/ unsigned int ds; unsigned int heap_all; +unsigned int seg_all; unsigned int taskoff; int maxtasks; struct task_struct task_table; @@ -92,15 +94,55 @@ struct task_struct *find_process(int fd, unsigned int seg) return NULL; } +static long total_segsize = 0; +static char *segtype[] = + { "free", "CSEG", "DSEG", "DDAT", "FDAT", "BUF ", "RDSK" }; + +void display_seg(int fd, word_t mem) +{ + seg_t segbase = getword(fd, mem + offsetof(segment_s, base), ds); + segext_t segsize = getword(fd, mem + offsetof(segment_s, size), ds); + word_t segflags = getword(fd, mem + offsetof(segment_s, flags), ds) & SEG_FLAG_TYPE; + byte_t ref_count = getword(fd, mem + offsetof(segment_s, ref_count), ds); + struct task_struct *t; + + printf(" %4x %s %7ld %4d ", + segbase, segtype[segflags], (long)segsize << 4, ref_count); + if (segflags == SEG_FLAG_CSEG || segflags == SEG_FLAG_DSEG) { + if ((t = find_process(fd, mem)) != NULL) { + process_name(fd, t->t_begstack, t->t_regs.ss); + } + } + + total_segsize += (long)segsize << 4; +} + +void dump_segs(int fd) +{ + word_t n, mem; + seg_t segbase, oldbase = 0; + + printf(" SEG TYPE SIZE CNT NAME\n"); + n = getword (fd, seg_all + offsetof(list_s, next), ds); + while (n != seg_all) { + mem = n - offsetof(segment_s, all); + segbase = getword(fd, mem + offsetof(segment_s, base), ds); + if (segbase < oldbase) printf("\n"); + oldbase = segbase; + display_seg(fd, mem); + printf("\n"); + + /* next in list */ + n = getword(fd, n + offsetof(list_s, next), ds); + } +} + void dump_heap(int fd) { word_t total_size = 0; word_t total_free = 0; - long total_segsize = 0; static char *heaptype[] = { "free", "MEM ", "DRVR", "TTY ", "TASK", "BUFH", "PIPE", "INOD", "FILE", "CACH"}; - static char *segtype[] = - { "free", "CSEG", "DSEG", "DDAT", "FDAT", "BUF ", "RDSK" }; printf(" HEAP TYPE SIZE SEG TYPE SIZE CNT NAME\n"); @@ -110,18 +152,14 @@ void dump_heap(int fd) word_t size = getword(fd, h + offsetof(heap_s, size), ds); byte_t tag = getword(fd, h + offsetof(heap_s, tag), ds) & HEAP_TAG_TYPE; word_t mem = h + sizeof(heap_s); - seg_t segbase; - segext_t segsize; word_t segflags; - byte_t ref_count; - int free, used, tty, buffer, system; - struct task_struct *t; + int free, app, tty, buffer, system; if (tag == HEAP_TAG_SEG) segflags = getword(fd, mem + offsetof(segment_s, flags), ds) & SEG_FLAG_TYPE; else segflags = -1; free = (tag == HEAP_TAG_FREE || segflags == SEG_FLAG_FREE); - used = ((tag == HEAP_TAG_SEG) + app = ((tag == HEAP_TAG_SEG) && (segflags == SEG_FLAG_CSEG || segflags == SEG_FLAG_DSEG || segflags == SEG_FLAG_DDAT || segflags == SEG_FLAG_FDAT)); tty = (tag == HEAP_TAG_TTY || tag == HEAP_TAG_DRVR); @@ -129,9 +167,8 @@ void dump_heap(int fd) || tag == HEAP_TAG_BUFHEAD || tag == HEAP_TAG_CACHE || tag == HEAP_TAG_PIPE; system = (tag == HEAP_TAG_TASK || tag == HEAP_TAG_INODE || tag == HEAP_TAG_FILE); - if (allflag || - (fflag && free) || (aflag && used) || (tflag && tty) || (bflag && buffer) - || (sflag && system)) { + if (allflag || (fflag && free) || (aflag && app) || (tflag && tty) + || (bflag && buffer) || (sflag && system)) { printf(" %4x %s %5d", mem, heaptype[tag], size); total_size += size + sizeof(heap_s); if (tag == HEAP_TAG_FREE) @@ -139,18 +176,7 @@ void dump_heap(int fd) switch (tag) { case HEAP_TAG_SEG: - segbase = getword(fd, mem + offsetof(segment_s, base), ds); - segsize = getword(fd, mem + offsetof(segment_s, size), ds); - ref_count = getword(fd, mem + offsetof(segment_s, ref_count), ds); - printf(" %4x %s %7ld %4d ", - segbase, segtype[segflags], (long)segsize << 4, ref_count); - if (segflags == SEG_FLAG_CSEG || segflags == SEG_FLAG_DSEG) { - if ((t = find_process(fd, mem)) != NULL) { - process_name(fd, t->t_begstack, t->t_regs.ss); - } - } - - total_segsize += (long)segsize << 4; + display_seg(fd, mem); break; } printf("\n"); @@ -165,7 +191,7 @@ void dump_heap(int fd) void usage(void) { - printf("usage: meminfo [-a][-f][-t][-b]\n"); + printf("usage: meminfo [-maftbsh]\n"); } int main(int argc, char **argv) @@ -175,7 +201,7 @@ int main(int argc, char **argv) if (argc < 2) allflag = 1; - else while ((c = getopt(argc, argv, "aftbsh")) != -1) { + else while ((c = getopt(argc, argv, "aftbsmh")) != -1) { switch (c) { case 'a': aflag = 1; @@ -192,6 +218,9 @@ int main(int argc, char **argv) case 's': sflag = 1; break; + case 'm': + mflag = 1; + break; case 'h': usage(); return 0; @@ -207,15 +236,18 @@ int main(int argc, char **argv) } if (ioctl(fd, MEM_GETDS, &ds) || ioctl(fd, MEM_GETHEAP, &heap_all) || + ioctl(fd, MEM_GETSEGALL, &seg_all) || ioctl(fd, MEM_GETTASK, &taskoff) || ioctl(fd, MEM_GETMAXTASKS, &maxtasks)) { perror("meminfo"); - return 1; + return 1; } if (!memread(fd, taskoff, ds, &task_table, sizeof(task_table))) { perror("taskinfo"); } - dump_heap(fd); + if (mflag) + dump_segs(fd); + else dump_heap(fd); if (!ioctl(fd, MEM_GETUSAGE, &mu)) { /* note MEM_GETUSAGE amounts are floors, so total may display less by 1k than actual*/ From e1e7acd118fa7e75836f0c4cb791b5a9c52ebd39 Mon Sep 17 00:00:00 2001 From: Greg Haerr Date: Tue, 17 Sep 2024 16:31:45 -0600 Subject: [PATCH 3/3] Update man page, remove unnecessary kernel message --- elks/arch/i86/mm/malloc.c | 8 +++----- elkscmd/man/man1/meminfo.1 | 15 ++++++++++++--- elkscmd/sys_utils/meminfo.c | 10 +++++----- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/elks/arch/i86/mm/malloc.c b/elks/arch/i86/mm/malloc.c index cd130bbbf..c8f40d59b 100644 --- a/elks/arch/i86/mm/malloc.c +++ b/elks/arch/i86/mm/malloc.c @@ -36,10 +36,8 @@ static segment_s * seg_split (segment_s * s1, segext_t size0) // TODO: use pool_alloc segment_s * s2 = (segment_s *) heap_alloc (sizeof (segment_s), HEAP_TAG_SEG); - if (!s2) { - printk ("seg:cannot split:heap full\n"); - return 0; - } + if (!s2) + return 0; // heap_alloc gives heap full message s2->base = s1->base + size0; s2->size = size2; @@ -323,7 +321,7 @@ void INITPROC seg_add(seg_t start, seg_t end) seg->ref_count = 0; seg->pid = 0; - list_insert_before (&_seg_all, &(seg->all)); // add tail + list_insert_before (&_seg_all, &(seg->all)); // add tail list_insert_before (&_seg_free, &(seg->free)); // add tail } } diff --git a/elkscmd/man/man1/meminfo.1 b/elkscmd/man/man1/meminfo.1 index 05218f402..fd8243530 100644 --- a/elkscmd/man/man1/meminfo.1 +++ b/elkscmd/man/man1/meminfo.1 @@ -4,15 +4,21 @@ meminfo \- list system memory usage .SH SYNOPSIS .B meminfo .RB [ \-a ] +.RB [ \-m ] .RB [ \-f ] .RB [ \-t ] .RB [ \-b ] +.RB [ \-s ] +.RB [ \-h ] .br .SS OPTIONS -Defaults to showing all memory. +Defaults to showing all memory (equivalent to -aftbs). .TP 5 .B -a -Show application memory +Show memory in use by applications +.TP 5 +.B -m +Show main memory sorted by segment .TP 5 .B -f Show free memory @@ -24,7 +30,10 @@ Show tty and driver memory Show system buffer and pipe memory .TP 5 .B -s -Show system task, inode and file memory. +Show system task, inode and file memory +.TP 5 +.B -h +Show help .SH DESCRIPTION .B meminfo traverses the kernel local heap and displays a line for each in-use or free entry. diff --git a/elkscmd/sys_utils/meminfo.c b/elkscmd/sys_utils/meminfo.c index 19dfd42bb..6f3c80cca 100644 --- a/elkscmd/sys_utils/meminfo.c +++ b/elkscmd/sys_utils/meminfo.c @@ -191,7 +191,7 @@ void dump_heap(int fd) void usage(void) { - printf("usage: meminfo [-maftbsh]\n"); + printf("usage: meminfo [-amftbsh]\n"); } int main(int argc, char **argv) @@ -201,11 +201,14 @@ int main(int argc, char **argv) if (argc < 2) allflag = 1; - else while ((c = getopt(argc, argv, "aftbsmh")) != -1) { + else while ((c = getopt(argc, argv, "amftbsh")) != -1) { switch (c) { case 'a': aflag = 1; break; + case 'm': + mflag = 1; + break; case 'f': fflag = 1; break; @@ -218,9 +221,6 @@ int main(int argc, char **argv) case 's': sflag = 1; break; - case 'm': - mflag = 1; - break; case 'h': usage(); return 0;