From 975c6d8949c7f35f32f077941229d8e2bd0bbc45 Mon Sep 17 00:00:00 2001 From: Greg Haerr Date: Thu, 9 Jun 2022 20:18:01 -0600 Subject: [PATCH 1/2] [kernel] Add fmemalloc sys call, fix fsck on 65M disks --- elks/arch/i86/drivers/char/console-bios.c | 3 ++ .../i86/drivers/char/console-direct-pc98.c | 3 ++ elks/arch/i86/drivers/char/console-direct.c | 3 ++ elks/arch/i86/drivers/char/mem.c | 1 + elks/arch/i86/drivers/char/ntty.c | 1 + elks/arch/i86/drivers/net/ne2k.c | 1 + elks/arch/i86/kernel/process.c | 1 + elks/arch/i86/kernel/strace.h | 1 + elks/arch/i86/kernel/syscall.dat | 1 + elks/arch/i86/kernel/timer.c | 1 + elks/arch/i86/mm/malloc.c | 39 +++++++++++++++++- elks/fs/file_table.c | 1 + elks/fs/minix/symlink.c | 1 + elks/fs/msdos/dir.c | 1 + elks/include/linuxmt/mm.h | 40 +++++++++---------- elks/kernel/exit.c | 4 +- elks/kernel/printk.c | 2 + elks/kernel/time.c | 1 + elkscmd/disk_utils/fsck.c | 23 ++++------- elkscmd/rootfs_template/bootopts | 2 +- elkscmd/sys_utils/meminfo.c | 2 +- libc/include/malloc.h | 3 ++ libc/include/string.h | 3 +- libc/malloc/Makefile | 1 + libc/malloc/fmemalloc.c | 17 ++++++++ libc/string/Makefile | 1 + libc/string/fmemset-c.c | 15 +++++++ 27 files changed, 130 insertions(+), 42 deletions(-) create mode 100644 libc/malloc/fmemalloc.c create mode 100644 libc/string/fmemset-c.c diff --git a/elks/arch/i86/drivers/char/console-bios.c b/elks/arch/i86/drivers/char/console-bios.c index 4e26b37b8..f2f0ef880 100644 --- a/elks/arch/i86/drivers/char/console-bios.c +++ b/elks/arch/i86/drivers/char/console-bios.c @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include #include #include "console.h" diff --git a/elks/arch/i86/drivers/char/console-direct-pc98.c b/elks/arch/i86/drivers/char/console-direct-pc98.c index fa533f1b4..084e83267 100644 --- a/elks/arch/i86/drivers/char/console-direct-pc98.c +++ b/elks/arch/i86/drivers/char/console-direct-pc98.c @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/elks/arch/i86/drivers/char/console-direct.c b/elks/arch/i86/drivers/char/console-direct.c index 9525837c2..8146cbce4 100644 --- a/elks/arch/i86/drivers/char/console-direct.c +++ b/elks/arch/i86/drivers/char/console-direct.c @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/elks/arch/i86/drivers/char/mem.c b/elks/arch/i86/drivers/char/mem.c index b9235470c..dbe2ba24f 100644 --- a/elks/arch/i86/drivers/char/mem.c +++ b/elks/arch/i86/drivers/char/mem.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/elks/arch/i86/drivers/char/ntty.c b/elks/arch/i86/drivers/char/ntty.c index 1e63412d3..9cc52151c 100644 --- a/elks/arch/i86/drivers/char/ntty.c +++ b/elks/arch/i86/drivers/char/ntty.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/elks/arch/i86/drivers/net/ne2k.c b/elks/arch/i86/drivers/net/ne2k.c index 3ef0a6974..c5c5b643a 100644 --- a/elks/arch/i86/drivers/net/ne2k.c +++ b/elks/arch/i86/drivers/net/ne2k.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/elks/arch/i86/kernel/process.c b/elks/arch/i86/kernel/process.c index 53c326284..1c7e9c695 100644 --- a/elks/arch/i86/kernel/process.c +++ b/elks/arch/i86/kernel/process.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/elks/arch/i86/kernel/strace.h b/elks/arch/i86/kernel/strace.h index e4e546d95..32bfd4ec3 100644 --- a/elks/arch/i86/kernel/strace.h +++ b/elks/arch/i86/kernel/strace.h @@ -250,6 +250,7 @@ struct syscall_info elks_table[] = { { "connect", packinfo(3, P_SSHORT, P_PDATA, P_SSHORT ) }, { "setsockopt", packinfo(5, P_SSHORT, P_SSHORT, P_SSHORT ) }, /* +2 args*/ { "getsocknam", packinfo(4, P_SSHORT, P_DATA, P_PUSHORT) }, /* +1 arg*/ + { "fmemalloc", packinfo(2, P_USHORT, P_PUSHORT, P_NONE) }, }; #endif diff --git a/elks/arch/i86/kernel/syscall.dat b/elks/arch/i86/kernel/syscall.dat index 06ab0a15f..57b7fc733 100644 --- a/elks/arch/i86/kernel/syscall.dat +++ b/elks/arch/i86/kernel/syscall.dat @@ -102,6 +102,7 @@ accept +202 3 = CONFIG_SOCKET connect +203 3 = CONFIG_SOCKET setsockopt +204 5 = CONFIG_SOCKET getsocknam +205 4 = CONFIG_SOCKET +fmemalloc +206 2 * # # Name No Args Flag&comment # diff --git a/elks/arch/i86/kernel/timer.c b/elks/arch/i86/kernel/timer.c index a3b4a76f3..3bee65205 100644 --- a/elks/arch/i86/kernel/timer.c +++ b/elks/arch/i86/kernel/timer.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/elks/arch/i86/mm/malloc.c b/elks/arch/i86/mm/malloc.c index 57ae091fb..457035bec 100644 --- a/elks/arch/i86/mm/malloc.c +++ b/elks/arch/i86/mm/malloc.c @@ -5,7 +5,7 @@ #include #include #include -//#include +#include #include #include @@ -45,6 +45,7 @@ static segment_s * seg_split (segment_s * s1, segext_t size0) s2->size = size2; s2->flags = SEG_FLAG_FREE; s2->ref_count = 0; + s2->pid = 0; list_insert_after (&s1->all, &s2->all); list_insert_after (&s1->free, &s2->free); @@ -107,6 +108,7 @@ static void seg_merge (segment_s * s1, segment_s * s2) { list_remove (&s2->all); s1->size += s2->size; + s1->pid = 0; heap_free (s2); } @@ -150,6 +152,7 @@ void seg_free (segment_s * seg) seg = prev; } else { seg->flags = SEG_FLAG_FREE; + seg->pid = 0; } } @@ -280,6 +283,38 @@ int sys_sbrk (int increment, __u16 * pbrk) return 0; } +// allocate memory for process, return segment +int sys_fmemalloc(int paras, unsigned short *pseg) +{ + segment_s *seg; + int err; + + err = verify_area(VERIFY_WRITE, pseg, sizeof(*pseg)); + if (err) return err; + seg = seg_alloc((segext_t)paras, SEG_FLAG_PROG); + if (!seg) return -ENOMEM; + seg->pid = current->pid; + put_user(seg->base, pseg); + return 0; +} + +// free all program allocated segments for PID pid +void seg_free_pid(pid_t pid) +{ + list_s *n; + +again: + for (n = _seg_all.next; n != &_seg_all; ) { + segment_s * seg = structof (n, segment_s, all); + + if (seg->pid == pid) { + seg_free(seg); + goto again; /* free may have changed linked list */ + } + n = seg->all.next; + } +} + // Initialize the memory manager. @@ -294,9 +329,9 @@ void INITPROC mm_init(seg_t start, seg_t end) seg->size = end - start; seg->flags = SEG_FLAG_FREE; seg->ref_count = 0; + seg->pid = 0; list_insert_before (&_seg_all, &(seg->all)); // add tail list_insert_before (&_seg_free, &(seg->free)); // add tail } } - diff --git a/elks/fs/file_table.c b/elks/fs/file_table.c index e378602ca..c1f1bccb7 100644 --- a/elks/fs/file_table.c +++ b/elks/fs/file_table.c @@ -11,6 +11,7 @@ #include #include #include +#include /* * first_file points to a doubly linked list of all file structures in diff --git a/elks/fs/minix/symlink.c b/elks/fs/minix/symlink.c index e216977d7..c1a8c3f66 100644 --- a/elks/fs/minix/symlink.c +++ b/elks/fs/minix/symlink.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/elks/fs/msdos/dir.c b/elks/fs/msdos/dir.c index 0ae4bb530..30e999d5b 100644 --- a/elks/fs/msdos/dir.c +++ b/elks/fs/msdos/dir.c @@ -16,6 +16,7 @@ #include #include #include +#include #include static size_t msdos_dir_read(struct inode *dir, struct file *filp, char *buf, size_t count) diff --git a/elks/include/linuxmt/mm.h b/elks/include/linuxmt/mm.h index 05b76009c..d82383f84 100644 --- a/elks/include/linuxmt/mm.h +++ b/elks/include/linuxmt/mm.h @@ -9,35 +9,27 @@ struct segment { list_s free; seg_t base; segext_t size; - word_t flags; - word_t ref_count; + byte_t flags; + byte_t ref_count; + word_t pid; }; typedef struct segment segment_s; // TODO: convert to tag -#define SEG_FLAG_FREE 0x0000 -#define SEG_FLAG_USED 0x0080 -#define SEG_FLAG_ALIGN1K 0x0040 -#define SEG_FLAG_TYPE 0x000F -#define SEG_FLAG_CSEG 0x0001 -#define SEG_FLAG_DSEG 0x0002 -#define SEG_FLAG_EXTBUF 0x0003 -#define SEG_FLAG_RAMDSK 0x0004 +#define SEG_FLAG_FREE 0x00 +#define SEG_FLAG_USED 0x80 +#define SEG_FLAG_ALIGN1K 0x40 +#define SEG_FLAG_TYPE 0x0F +#define SEG_FLAG_CSEG 0x01 +#define SEG_FLAG_DSEG 0x02 +#define SEG_FLAG_EXTBUF 0x03 +#define SEG_FLAG_RAMDSK 0x04 +#define SEG_FLAG_PROG 0x05 #ifdef __KERNEL__ -#include -#include #include -#include - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -#include - -#define verify_area(mode,point,size) verfy_area(point,size) /*@-namechecks@*/ @@ -47,6 +39,11 @@ int strlen_fromfs(void *,size_t); /*@+namechecks@*/ +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define verify_area(mode,point,size) verfy_area(point,size) + int verfy_area(void *,size_t); void put_user_char(unsigned char,void *); void put_user(unsigned short,void *); @@ -65,9 +62,10 @@ 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); + void mm_get_usage (unsigned int * free, unsigned int * used); #endif // __KERNEL__ diff --git a/elks/kernel/exit.c b/elks/kernel/exit.c index 465ff331d..46369a103 100644 --- a/elks/kernel/exit.c +++ b/elks/kernel/exit.c @@ -110,9 +110,11 @@ void do_exit(int status) seg_put(current->mm.seg_code); if (current->mm.seg_data) seg_put(current->mm.seg_data); - current->mm.seg_code = current->mm.seg_data = 0; + /* free program allocated memory */ + seg_free_pid(current->pid); + #if BLOAT /* Keep all of the family stuff straight */ struct task_struct *task; diff --git a/elks/kernel/printk.c b/elks/kernel/printk.c index 66001af4f..7ed3ec5f4 100644 --- a/elks/kernel/printk.c +++ b/elks/kernel/printk.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/elks/kernel/time.c b/elks/kernel/time.c index 1ccd1b789..3d5b12e3a 100644 --- a/elks/kernel/time.c +++ b/elks/kernel/time.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/elkscmd/disk_utils/fsck.c b/elkscmd/disk_utils/fsck.c index 4c4470b1c..0871fb9e4 100644 --- a/elkscmd/disk_utils/fsck.c +++ b/elkscmd/disk_utils/fsck.c @@ -76,7 +76,6 @@ /* FIXME remove all commented out code with RUBOUT in it */ - #define ROOT_INO 1 #define UPPER(size,n) ((size+((n)-1))/(n)) @@ -130,7 +129,7 @@ static char inode_map[BLOCK_SIZE * MINIX_I_MAP_SLOTS]; static char zone_map[BLOCK_SIZE * MINIX_Z_MAP_SLOTS]; static unsigned char * inode_count = NULL; -static unsigned char * zone_count = NULL; +static unsigned char __far * zone_count = NULL; void recursive_check(unsigned int ino); @@ -543,20 +542,14 @@ void read_tables(void) if (!inode_buffer) die("Unable to allocate buffer for inodes"); RUBOUT */ - /* check for filesystem too large since libc malloc fails improperly FIXME */ - if (ZONES > 32767) { - fprintf(stderr, "Filesystem too large to check (%u zones, max 32767)\n", ZONES); - exit(8); - } - + printd("inodes %d zones %d\n", INODES, ZONES); + printd("imaps %d zmaps %d\n", IMAPS, ZMAPS); inode_count = malloc(INODES); if (!inode_count) die("Unable to allocate buffer for inode count"); - zone_count = malloc(ZONES); + zone_count = fmemalloc(ZONES); /* ZONES <= 64K */ if (!zone_count) - die("Unable to allocate buffer for zone count"); - printd("inodes %d zones %d\n", INODES, ZONES); - printd("imaps %d zmaps %d\n", IMAPS, ZMAPS); + die("Unable to allocate main memory for zone count"); if ((IMAPS * BLOCK_SIZE) != read(IN, inode_map, (IMAPS * BLOCK_SIZE))) die("Unable to read inode map"); if ((ZMAPS * BLOCK_SIZE) != read(IN, zone_map, (ZMAPS * BLOCK_SIZE))) @@ -569,8 +562,8 @@ void read_tables(void) errors_uncorrected = 1; } if (show) { - printf("%d inodes\n",INODES); - printf("%d blocks\n",ZONES); + printf("%u inodes\n",INODES); + printf("%u blocks\n",ZONES); printf("Pre-zone blocks 2+%d+%d+%d %d\n", IMAPS, ZMAPS, INODE_BLOCKS, NORM_FIRSTZONE); printf("Firstdatazone=%d (%d)\n",FIRSTZONE,NORM_FIRSTZONE); printf("Zonesize=%d\n",BLOCK_SIZE< 1) { printf("/"); diff --git a/elkscmd/rootfs_template/bootopts b/elkscmd/rootfs_template/bootopts index 9fa55317b..40c72084e 100644 --- a/elkscmd/rootfs_template/bootopts +++ b/elkscmd/rootfs_template/bootopts @@ -11,4 +11,4 @@ #init=/bin/init 3 n # multiuser serial no /etc/rc.sys #init=/bin/sh # singleuser shell #root=hda1 ro # root hd partition 1, read-only -#console=ttyS0,19200 3 # serial console +console=ttyS0,19200 3 # serial console diff --git a/elkscmd/sys_utils/meminfo.c b/elkscmd/sys_utils/meminfo.c index 8f4b47614..c5608f33b 100644 --- a/elkscmd/sys_utils/meminfo.c +++ b/elkscmd/sys_utils/meminfo.c @@ -55,7 +55,7 @@ void dump_heap(int fd) word_t total_free = 0; long total_segsize = 0; static char *heaptype[] = { "free", "SEG ", "STR ", "TTY ", "INT ", "BUFH", "PIPE" }; - static char *segtype[] = { "free", "CSEG", "DSEG", "BUF ", "RDSK" }; + static char *segtype[] = { "free", "CSEG", "DSEG", "BUF ", "RDSK", "PROG" }; printf(" HEAP TYPE SIZE SEG TYPE SIZE CNT\n"); diff --git a/libc/include/malloc.h b/libc/include/malloc.h index bd6cc0a20..071d65e67 100644 --- a/libc/include/malloc.h +++ b/libc/include/malloc.h @@ -29,4 +29,7 @@ extern void *(*__alloca_alloc) __P((size_t)); #define malloc(x) ((*__alloca_alloc)(x)) #endif +/* alloc from main memory */ +void __far *fmemalloc(unsigned long size); + #endif diff --git a/libc/include/string.h b/libc/include/string.h index b02c1176c..e4ac033c1 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -25,9 +25,10 @@ extern void * memccpy __P ((void*, void*, int, size_t)); extern void * memchr __P ((__const void*, __const int, size_t)); extern void * memset __P ((void*, int, size_t)); extern int memcmp __P ((__const void*, __const void*, size_t)); - extern void * memmove __P ((void*, void*, size_t)); +void __far *fmemset(void __far *buf, int c, size_t l); + /* Error messages */ extern char * strerror __P ((int)); diff --git a/libc/malloc/Makefile b/libc/malloc/Makefile index 7dfe620db..355c45974 100644 --- a/libc/malloc/Makefile +++ b/libc/malloc/Makefile @@ -24,6 +24,7 @@ OBJS = \ noise.o \ realloc.o \ sbrk.o \ + fmemalloc.o \ .PHONY: all diff --git a/libc/malloc/fmemalloc.c b/libc/malloc/fmemalloc.c new file mode 100644 index 000000000..6100f840b --- /dev/null +++ b/libc/malloc/fmemalloc.c @@ -0,0 +1,17 @@ +#include + +#define _MK_FP(seg,off) ((void __far *)((((unsigned long)(seg)) << 16) | (off))) + +/* request paras from main memory, returns segment */ +int _fmemalloc(int paras, unsigned short *pseg); + +/* alloc from main memory */ +void __far *fmemalloc(unsigned long size) +{ + unsigned short seg; + unsigned int paras = (unsigned int)((size + 15) >> 4); + + if (_fmemalloc(paras, &seg)) + return 0; + return _MK_FP(seg, 0); +} diff --git a/libc/string/Makefile b/libc/string/Makefile index bd36f2cd3..8bd029206 100644 --- a/libc/string/Makefile +++ b/libc/string/Makefile @@ -10,6 +10,7 @@ OBJS = \ memcpy-c.o \ memmove.o \ memset-c.o \ + fmemset-c.o \ movedata.o \ strcasecmp.o \ strcat.o \ diff --git a/libc/string/fmemset-c.c b/libc/string/fmemset-c.c new file mode 100644 index 000000000..4ddc3a30e --- /dev/null +++ b/libc/string/fmemset-c.c @@ -0,0 +1,15 @@ +#include +#include + +#ifndef LIBC_ASM_FMEMSET + +void __far *fmemset(void __far *str, int c, size_t l) +{ + char __far *s1 = str; + + while (l-- > 0) + *s1++ = c; + return str; +} + +#endif From e215754455d2ea34668a7422493525d6524542ab Mon Sep 17 00:00:00 2001 From: Greg Haerr Date: Thu, 9 Jun 2022 20:25:01 -0600 Subject: [PATCH 2/2] cleanup --- elkscmd/rootfs_template/bootopts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elkscmd/rootfs_template/bootopts b/elkscmd/rootfs_template/bootopts index 40c72084e..9fa55317b 100644 --- a/elkscmd/rootfs_template/bootopts +++ b/elkscmd/rootfs_template/bootopts @@ -11,4 +11,4 @@ #init=/bin/init 3 n # multiuser serial no /etc/rc.sys #init=/bin/sh # singleuser shell #root=hda1 ro # root hd partition 1, read-only -console=ttyS0,19200 3 # serial console +#console=ttyS0,19200 3 # serial console