Skip to content
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
4 changes: 0 additions & 4 deletions elks/arch/i86/boot/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ _start:

call start_kernel // no return

.global int3
int3: int $3 // C breakpoint for emu86
ret

#if defined(CONFIG_ARCH_SWAN)
early_putchar:
1: in $0xB3,%al
Expand Down
12 changes: 0 additions & 12 deletions elks/arch/i86/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,6 @@ entry.S: syscall.dat mkentry.sh
strace.o: strace.c
$(CC) $(CFLAGS) -fno-optimize-sibling-calls -c -o strace.o strace.c

#
# Special compilations apparently needed for startup failure using emu86 w/ROM
# FIXME Apparent stack trashing but not fully verified
irq.o: irq.c
$(CC) $(CFLAGS) -fno-defer-pop -c -o irq.o irq.c

#irq-8259.o: irq-8259.c
# $(CC) $(CFLAGS) -fno-defer-pop -c -o irq-8259.o irq-8259.c

#timer-8254.o: timer-8254.c
# $(CC) $(CFLAGS) -fno-defer-pop -c -o timer-8254.o timer-8254.c

#########################################################################
# Standard commands.

Expand Down
2 changes: 0 additions & 2 deletions elks/arch/i86/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,4 @@ void INITPROC irq_init(void)

enable_timer_tick(); /* reprogram timer for 100 HZ */
#endif

init_bh(TIMER_BH, timer_bh);
}
9 changes: 1 addition & 8 deletions elks/arch/i86/kernel/irqtab.S
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ utask:
#ifdef CHECK_SS
//
// We were in user mode, first confirm
// FIXME: won't work - panic requires valid SS and SS == DS!
//
mov %ss,%di
cmp TASK_USER_SS(%si),%di // entry SS = current->t_regs.ss?
Expand Down Expand Up @@ -378,14 +379,6 @@ 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

// short *getsp(void) - get stack pointer
.global getsp
getsp:
Expand Down
3 changes: 2 additions & 1 deletion elks/arch/i86/kernel/strace.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ static void check_kstack(int n)
static int max;

#ifdef CHECK_ISTACK
check_istack();
if (tracing & TRACE_ISTACK)
check_istack();
#endif
s = syscall_info(current->t_regs.orig_ax);
if (s == &notimp)
Expand Down
13 changes: 13 additions & 0 deletions elks/include/arch/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ void do_bottom_half(void);
: "memory"); \
v; })

/* set stack pointer */
#define setsp(newsp) \
asm volatile ("mov %%ax,%%sp" \
: /* no output */ \
:"a" ((unsigned short)(newsp)) \
:"memory")

/* breakpoint interrupt */
#define int3() \
asm volatile ("int $3\n"\
: /* no output */ \
: /* no input */)

#ifdef CONFIG_ARCH_SWAN
/* acknowledge interrupt */
#define ack_irq(i) \
Expand Down
1 change: 0 additions & 1 deletion elks/include/linuxmt/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ 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 short *getsp(void);
extern int run_init_process(const char *cmd);
extern int run_init_process_sptr(const char *cmd, char *sptr, int slen);
Expand Down
2 changes: 1 addition & 1 deletion elks/init/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ include $(BASEDIR)/Makefile-rules
all: main.o

main.o: main.c
$(CC) $(CFLAGS) -fno-defer-pop -c -o main.o main.c
$(CC) $(CFLAGS) -fno-optimize-sibling-calls -fno-defer-pop -c -o main.o main.c


#########################################################################
Expand Down
76 changes: 50 additions & 26 deletions elks/init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linuxmt/devnum.h>
#include <linuxmt/heap.h>
#include <linuxmt/prectimer.h>
#include <linuxmt/timer.h>
#include <linuxmt/debug.h>
#include <arch/segment.h>
#include <arch/ports.h>
Expand Down Expand Up @@ -90,10 +91,12 @@ static void INITPROC finalize_options(void);
static char * INITPROC option(char *s);
#endif /* CONFIG_BOOTOPTS */

static void FARPROC far_start_kernel(void);
static void INITPROC early_kernel_init(void);
static void INITPROC kernel_init(void);
static void INITPROC kernel_banner(seg_t init, seg_t extra);
static void init_task(void);
static void idle_loop(void);

/*
* This function is called using the interrupt stack as a temporary stack.
Expand All @@ -102,52 +105,72 @@ static void init_task(void);
* switched again to the tiny idle task struct stack area and then becomes the
* idle task. Must be compiled using -fno-defer-pop, as otherwise stack pointer
* cleanup is delayed after function calls, which interferes with SP resets.
* No return is allowed since SP is switched, and the memory used by far_start_kernel
* is released after kernel initialization is complete.
*/
void start_kernel(void)
{
flag_t flags; /* check interrupts - should already be disabled! */
save_flags(flags);
if (flags & 0x0200)
printk("INT ON "); /* warning message for bad setup.S code */
clr_irq();
//tracing = TRACE_KSTACK | TRACE_ISTACK;
far_start_kernel(); /* start executing in reusable memory */
}

static void FARPROC far_start_kernel(void)
{
flag_t flags; /* get CPU flag word */
save_flags(flags);
clr_irq(); /* we're running on the kernel interrupt stack! */
printk("INT %x ", flags); /* to show interrupt status after setup.S */
printk("START\n");
early_kernel_init(); /* read bootopts using kernel temp stack */

/*
* Allocate the task array + smaller task struct for the idle task.
* The idle task struct has a smaller stack in t_kstack[] and no t_regs.
* This works because the idle task always runs at intr_count 1, so
* interrupts will always save registers onto istack, and never
* to the t_regs struct at the end of a normal task struct.
*/
task = heap_alloc(max_tasks * sizeof(struct task_struct) +
TASK_KSTACK + IDLESTACK_BYTES, HEAP_TAG_TASK|HEAP_TAG_CLEAR);
if (!task) panic("No task mem");
idle_task = (struct task_struct *)
((char *)task + max_tasks * sizeof(struct task_struct));
early_kernel_init(); /* read bootopts using kernel interrupt stack */

/*
* Allocate the task array + smaller task struct for the idle task.
* The idle task struct has a smaller stack in t_kstack[] and no t_regs.
* This works because the idle task always runs at intr_count 1, so
* interrupts will always save registers onto istack, and never
* to the t_regs struct at the end of a normal task struct.
*/
task = heap_alloc(max_tasks * sizeof(struct task_struct) +
TASK_KSTACK + IDLESTACK_BYTES, HEAP_TAG_TASK|HEAP_TAG_CLEAR);
if (!task) panic("No task mem");
idle_task = (struct task_struct *)
((char *)task + max_tasks * sizeof(struct task_struct));
setsp(&(task+1)->t_regs.ax); /* change to a large temp stack (unused task #1) */
debug("SP SWITCH\n");

debug("endbss %x task %x idle_task %x idle_stack %x\n",
_endbss, task, idle_task, &idle_task->t_kstack[IDLESTACK_BYTES/2]);

sched_init(); /* init the idle and other task structs */
setsp(&(task+1)->t_regs.ax); /* change to a large temp stack (unused task #1) */
kernel_init(); /* continue kernel init running on large stack */

/* allocate task struct #0/pid 1 and setup init_task() to run on next reschedule */
kfork_proc(init_task);
wake_up_process(&task[0]);

idle_loop(); /* no return */
}

/* the idle task loop, no return */
static void idle_loop(void)
{
/*
* Set SP to the idle task struct. We then become the idle task and are only
* switched to when the last runnable user mode process sleeps from its
* kernel stack and schedule() is called.
* Set SP to the small stack in the special idle task struct.
* We then become the idle task and are only switched to when the last runnable
* user mode process sleeps from its kernel stack and schedule() is called.
* As a result, the idle task always runs with intr_count 1, which guarantees
* interrupt register saves will be on the interrupt stack, not the idle stack.
*
* NOTE: Any calls to printk afer the small idle stack is set below can cause idle
* NOTE: Any calls to printk after the small idle stack is set below can cause idle
* stack overflow. The good news is that the overflow shouldn't cause much harm
* since it overflows into relatively unused areas of the idle task's task_struct.
*/
setsp(&idle_task->t_kstack[IDLESTACK_BYTES/2]); /* change to small idle task stack */
//hexdump(idle_task->t_kstack, kernel_ds, IDLESTACK_BYTES, 1);
setsp(&idle_task->t_kstack[IDLESTACK_BYTES/2]);
debug("IDLE LOOP %x\n", getsp());
//hexdump(idle_task->t_kstack, kernel_ds, IDLESTACK_BYTES, 0);

init_bh(TIMER_BH, timer_bh); /* finally enable timer bottom halves */

/*
* In the call to schedule below, the init_task function will run, which
Expand All @@ -156,7 +179,7 @@ void start_kernel(void)
* from the kernel and enters user mode until the next clock tick or system call.
*/
while (1) {
#ifdef CHECK_KSTACK
#if defined(CHECK_KSTACK) || 1
if (idle_task->kstack_magic != KSTACK_MAGIC) {
printk("IDLE STACK OFLOW\n");
idle_task->kstack_magic = KSTACK_MAGIC;
Expand Down Expand Up @@ -215,6 +238,7 @@ static void INITPROC kernel_init(void)
#endif
irq_init(); /* installs timer and div fault handlers */

debug("INT ENB\n");
set_irq(); /* interrupts enabled early for jiffie timers */

#ifdef CONFIG_CHAR_DEV_RS
Expand Down
5 changes: 2 additions & 3 deletions elks/kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ struct task_struct *find_empty_process(void)
}
next_task_slot = t;
task_slots_unused--;
memcpy(t, current, /* duplicate current task data into new one */
(current == idle_task)? (TASK_KSTACK+IDLESTACK_BYTES)
: sizeof(struct task_struct));
if (current != idle_task) /* duplicate current task data into new one */
memcpy(t, current, sizeof(struct task_struct));
t->state = TASK_UNINTERRUPTIBLE;
t->pid = get_pid();
t->ticks = 0; /* for CONFIG_CPU_USAGE */
Expand Down
17 changes: 10 additions & 7 deletions elks/kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <stdarg.h>

#define CONFIG_PREC_TIMER 1 /* =1 to include %k precision timer printk format */
#define STATIC static /* avoid stack overflow from printk on idle stack */

dev_t dev_console;

Expand Down Expand Up @@ -123,11 +124,12 @@ static unsigned long conv_ptick(unsigned long v, int *pDecimal, int *pSuffix)
static void numout(unsigned long v, int width, unsigned int base, int type,
int Zero, int alt)
{
int n, i;
unsigned int c;
int i;
char *p;
int Sign, Suffix, Decimal;
char buf[12]; /* small stack: good up to max long octal v */
STATIC int n;
STATIC unsigned int c;
STATIC int Sign, Suffix, Decimal;
STATIC char buf[12]; /* small stack: good up to max long octal v */

Decimal = -1;
Sign = Suffix = 0;
Expand Down Expand Up @@ -188,9 +190,10 @@ static void numout(unsigned long v, int width, unsigned int base, int type,

static void vprintk(const char *fmt, va_list p)
{
int c, n, width, zero, alt, ptrfmt;
unsigned long v;
char *str;
int c, n;
STATIC int width, zero, alt, ptrfmt;
STATIC unsigned long v;
STATIC char *str;

while ((c = *fmt++)) {
if (c != '%')
Expand Down
2 changes: 1 addition & 1 deletion elks/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ void INITPROC sched_init(void)
*/
t = idle_task;
t->state = TASK_RUNNING;
t->kstack_magic = KSTACK_MAGIC;
t->next_run = t->prev_run = t;
//memset(t->t_kstack, 0xff, IDLESTACK_BYTES); /* for debugging idle stack size */
t->kstack_magic = KSTACK_MAGIC;

current = t;
next_task_slot = task;
Expand Down
3 changes: 2 additions & 1 deletion elkscmd/rootfs_template/etc/passwd
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ shutdown::6:0:shutdown:/bin:/bin/shutdown
poweroff::7:0:poweroff:/bin:/bin/poweroff
reboot::8:0:poweroff:/bin:/bin/reboot
meminfo::9:0:meminfo:/root:/bin/meminfo
tty::10:0:tty:/home:/bin/tty
ps::10:0:meminfo:/root:/bin/ps
tty::11:0:tty:/home:/bin/tty
ftp:*:14:50:FTP User:/home/ftp:/bin/sh
nobody:*:99:99:Nobody:/tmp:
user1::101:101:User 1:/home:/bin/sh
Expand Down