Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[kernel] Dynamically allocate task array from bootopts #1839

Merged
merged 2 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions elks/arch/i86/boot/crt0.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include <linuxmt/config.h>
#include <arch/asm-offsets.h>

// Assembler boot strap hooks. This is called by setup

Expand Down Expand Up @@ -42,11 +41,11 @@ _start:
mov %cs,kernel_cs
mov %ds,kernel_ds

// Set SS:SP to task[0] kernel stack area
// Set SS:SP to kernel interrupt stack for temporary use

mov %ds,%ax
mov %ax,%ss // SS=ES=DS
mov $task + TASK_USER_AX,%sp
mov $istack,%sp

call start_kernel // fall through into breakpoint if returns

Expand Down Expand Up @@ -81,7 +80,7 @@ early_putchar:
.global _endbss
.extern kernel_cs
.extern kernel_ds
.extern task
.extern istack

_endtext:
.word 0
Expand Down
3 changes: 3 additions & 0 deletions elks/arch/i86/drivers/char/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg)
case MEM_GETTASK:
retword = (unsigned short)task;
break;
case MEM_GETMAXTASKS:
retword = max_tasks;
break;
case MEM_GETCS:
retword = kernel_cs;
break;
Expand Down
12 changes: 10 additions & 2 deletions elks/arch/i86/kernel/irqtab.S
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,9 @@ restore_regs:
iret

/*
* tswitch();
* tswitch()
*
* This function can only be called with SS=DS=ES=kernel DS and
* This function can only be called with SS=DS=kernel DS and
* CS=kernel CS. SS:SP is the relevant kernel stack. Thus we don't need
* to arse about with segment registers. The kernel isn't relocating.
*
Expand All @@ -389,6 +389,13 @@ tswitch:
pop %bp // BP of schedule()
ret

// setsp(void *sp) - set stack pointer
.global setsp
setsp:
pop %bx // return address
pop %ax
mov %ax,%sp
jmp *%bx

// Halt - wait for next interrupt to save CPU power
.global idle_halt
Expand All @@ -399,6 +406,7 @@ idle_halt:
.data
.global intr_count
.global endistack
.global istack
.extern current
.extern previous

Expand Down
2 changes: 1 addition & 1 deletion elks/fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ int sys_execve(const char *filename, char *sptr, size_t slen)
seg_code = currentp->mm.seg_code;
break;
}
} while (++currentp < &task[MAX_TASKS]);
} while (++currentp < &task[max_tasks]);

/* Read the header */
currentp = current;
Expand Down
2 changes: 1 addition & 1 deletion elks/fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ int permission(register struct inode *inode, int mask)
do {
if (p->state <= TASK_STOPPED && (p->t_inode == inode))
return -EBUSY;
} while (++p < &task[MAX_TASKS]);
} while (++p < &task[max_tasks]);
}
if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
!S_ISCHR(inode->i_mode) && !S_ISBLK(inode->i_mode)) /* allow writable devices*/
Expand Down
7 changes: 4 additions & 3 deletions elks/include/linuxmt/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
#define UTS_MACHINE "ibmpc i8086"

/* The following can be set for minimal systems or for QEMU emulation testing:
* 10 buffers (@20 = 200), 2 ttyq (@80 = 160), 4k L1 cache, 512 heap free = ~4968.
* Use buf=10 cache=4 in /bootopts
* 10 buffers (@20 = 200), 2 ttyq (@80 = 160), 4k L1 cache, 512 heap free,
* 10 tasks (@876 = 8760) = ~13728.
* Use buf=10 cache=4 task=10 in /bootopts
*/
#if defined(CONFIG_HW_MK88)
#define SETUP_HEAPSIZE 4968 /* force kernel heap size */
#define SETUP_HEAPSIZE 13728 /* force kernel heap size */
#endif
//#undef SETUP_MEM_KBYTES
//#define SETUP_MEM_KBYTES 256 /* force available memory in 1K bytes */
Expand Down
2 changes: 1 addition & 1 deletion elks/include/linuxmt/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define HEAP_TAG_SEG 0x01
#define HEAP_TAG_BUF 0x02
#define HEAP_TAG_TTY 0x03
#define HEAP_TAG_INTHAND 0x04 /* unused */
#define HEAP_TAG_TASK 0x04
#define HEAP_TAG_BUFHEAD 0x05
#define HEAP_TAG_PIPE 0x06

Expand Down
1 change: 1 addition & 0 deletions elks/include/linuxmt/mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define MEM_GETHEAP 7
#define MEM_GETUPTIME 8
#define MEM_GETFARTEXT 9
#define MEM_GETMAXTASKS 10

struct mem_usage {
unsigned int free_memory;
Expand Down
8 changes: 6 additions & 2 deletions elks/include/linuxmt/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ struct task_struct {
/* We use typedefs to avoid using struct foobar (*) */
typedef struct task_struct __task, *__ptask;

extern __task task[MAX_TASKS];
extern __task *task;
extern __task *next_task_slot;
extern int max_tasks;
extern int task_slots_unused;

extern volatile jiff_t jiffies; /* ticks updated by the timer interrupt*/
extern __ptask current;
Expand All @@ -125,7 +128,7 @@ extern time_t current_time(void);
#define time_after(a,b) (((long)(b) - (long)(a) < 0))

#define for_each_task(p) \
for (p = &task[0] ; p!=&task[MAX_TASKS]; p++ )
for (p = &task[0] ; p!=&task[max_tasks]; p++ )

/* Scheduling and sleeping function prototypes */

Expand Down Expand Up @@ -168,6 +171,7 @@ extern unsigned int get_ustack(struct task_struct *,int);
extern void put_ustack(register struct task_struct *,int,int);

extern void tswitch(void);
extern void setsp(void *);
extern int run_init_process(const char *cmd);
extern int run_init_process_sptr(const char *cmd, char *sptr, int slen);
extern void ret_from_syscall(void);
Expand Down
46 changes: 29 additions & 17 deletions elks/init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <linuxmt/netstat.h>
#include <linuxmt/trace.h>
#include <linuxmt/devnum.h>
#include <linuxmt/heap.h>
#include <arch/system.h>
#include <arch/segment.h>
#include <arch/ports.h>
Expand Down Expand Up @@ -45,6 +46,7 @@ __u16 kernel_cs, kernel_ds;
int tracing;
int nr_ext_bufs, nr_xms_bufs, nr_map_bufs;
static int boot_console;
static seg_t membase, memend;
static char bininit[] = "/bin/init";
static char binshell[] = "/bin/sh";
#ifdef CONFIG_SYS_NO_BININIT
Expand All @@ -57,6 +59,7 @@ static char *init_command = bininit;
/*
* Parse /bootopts startup options
*/
static char opts;
static int args = 2; /* room for argc and av[0] */
static int envs;
static int argv_slen;
Expand All @@ -82,11 +85,17 @@ static char * INITPROC option(char *s);

static void init_task(void);
static void INITPROC kernel_banner(seg_t start, seg_t end, seg_t init, seg_t extra);
static void INITPROC early_kernel_init(void);


/* this procedure called using temp stack then switched, no temp vars allowed */
void start_kernel(void)
{
kernel_init();
early_kernel_init(); /* read bootopts using kernel interrupt stack */
task = heap_alloc(max_tasks * sizeof(struct task_struct),
HEAP_TAG_TASK|HEAP_TAG_CLEAR);
if (!task) panic("No task mem");
setsp(&task->t_regs.ax); /* change to idle task stack */
kernel_init(); /* continue init running on idle task stack */

/* fork and run procedure init_task() as task #1*/
kfork_proc(init_task);
Expand All @@ -105,25 +114,24 @@ void start_kernel(void)
}
}

void INITPROC kernel_init(void)
static void INITPROC early_kernel_init(void)
{
seg_t base, end;

/* sched_init sets us (the current stack) to be idle task #0*/
sched_init();
setup_arch(&base, &end);
mm_init(base, end);
irq_init();
tty_init();

setup_arch(&membase, &memend); /* initializes kernel heap */
mm_init(membase, memend); /* parse_options may call seg_add */
tty_init(); /* parse_options may call rs_setbaud */
#ifdef CONFIG_TIME_TZ
tz_init(CONFIG_TIME_TZ);
tz_init(CONFIG_TIME_TZ); /* parse_options may call tz_init */
#endif

#ifdef CONFIG_BOOTOPTS
/* parse options found in /bootops */
int opts = parse_options();
opts = parse_options(); /* parse options found in /bootops */
#endif
}

void INITPROC kernel_init(void)
{
/* set us (the current stack) to be idle task #0*/
sched_init();
irq_init();

/* set console from /bootopts console= or 0=default*/
set_console(boot_console);
Expand Down Expand Up @@ -163,7 +171,7 @@ void INITPROC kernel_init(void)
seg_t s = 0, e = 0;
#endif

kernel_banner(base, end, s, e - s);
kernel_banner(membase, memend, s, e - s);
}

static void INITPROC kernel_banner(seg_t start, seg_t end, seg_t init, seg_t extra)
Expand Down Expand Up @@ -481,6 +489,10 @@ static int INITPROC parse_options(void)
nr_map_bufs = (int)simple_strtol(line+6, 10);
continue;
}
if (!strncmp(line,"task=",5)) {
max_tasks = (int)simple_strtol(line+5, 10);
continue;
}
if (!strncmp(line,"comirq=",7)) {
comirq(line+7);
continue;
Expand Down
3 changes: 0 additions & 3 deletions elks/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
#include <linuxmt/mm.h>
#include <linuxmt/debug.h>

extern int task_slots_unused;
extern struct task_struct *next_task_slot;

static void reparent_children(void)
{
register struct task_struct *p;
Expand Down
8 changes: 4 additions & 4 deletions elks/kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

#include <arch/segment.h>

int task_slots_unused = MAX_TASKS;
struct task_struct *next_task_slot = task;
int task_slots_unused;
__task *next_task_slot;
pid_t last_pid = -1;

static pid_t get_pid(void)
Expand All @@ -27,7 +27,7 @@ static pid_t get_pid(void)
last_pid = 1;
p = &task[0];
}
} while (++p < &task[MAX_TASKS]);
} while (++p < &task[max_tasks]);
return last_pid;
}

Expand All @@ -46,7 +46,7 @@ struct task_struct *find_empty_process(void)
}
t = next_task_slot;
while (t->state != TASK_UNUSED) {
if (++t >= &task[MAX_TASKS])
if (++t >= &task[max_tasks])
t = &task[1];
}
next_task_slot = t;
Expand Down
12 changes: 8 additions & 4 deletions elks/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@

#define idle_task task[0]

__task task[MAX_TASKS];
__ptask current = task;
__task *task; /* dynamically allocated task array */
__ptask current;
__ptask previous;
int max_tasks = MAX_TASKS;

extern int intr_count;

Expand Down Expand Up @@ -192,15 +193,18 @@ void do_timer(void)

void INITPROC sched_init(void)
{
register struct task_struct *t = &task[MAX_TASKS];
struct task_struct *t = &task[max_tasks];

/*
* Mark tasks 0-(MAX_TASKS-1) as not in use.
* Mark tasks 0-(max_tasks-1) as not in use.
*/
do {
(--t)->state = TASK_UNUSED;
} while (t > task);

current = task;
next_task_slot = task;
task_slots_unused = max_tasks;
/*
* Now create task 0 to be ourself.
*/
Expand Down
5 changes: 3 additions & 2 deletions elkscmd/rootfs_template/bootopts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## boot opts max 511 bytes
#console=ttyS0,57600 debug net=ne0 3 # sercon+multiuser+net
#console=ttyS0,57600 debug net=ne0 3 # sercon+muser+net
#QEMU=1 # QEMU ftp/ftpd
#TZ=MDT7
#LOCALIP=10.0.2.16
Expand All @@ -12,8 +12,9 @@ wd0=10,0x300,0xCC00,0x80
#cache=4
#xmsbuf=2975
#umb=0xC000:0x800,0xD000:0x1000
#task=20
#sync=30 # autosync secs
#init=/bin/init 3 n # multiuser serial no rc.sys
#init=/bin/init 3 n # muser serial no rc.sys
#init=/bin/sh # singleuser sh
#root=hda1 ro # root hd partition 1 read-only
#kstack
Expand Down
Loading
Loading