the environment; implemented dofork and fixed switchin and switchout.
init loads! And runs! And tries to exec /bin/sh! Which fails, because
the environment's mangled by a user-vs-kernel pointer size mismatch.
"g" (udata.u_error)
);
}
-
-int16_t dofork(ptptr child)
-{
- kprintf("dofork\n");
- for (;;);
-}
-
-g \
kernel.ldflags += \
+ --relax \
-s
kernel.libgcc = $(shell $(TARGETCC) -mlarge --print-libgcc)
/* Multiple processes in memory at once */
#undef CONFIG_MULTI
/* Single tasking - for now while we get it booting */
-#define PTABSIZE 1
+#define PTABSIZE 4
#define CONFIG_NO_STARTUP_MESSAGE
extern int __user_base;
extern int __user_top;
+extern int __swap_base;
+extern int __swap_top;
+
#define TICKSPERSEC 64 /* Ticks per second */
#define PROGBASE ((uaddr_t)&__user_base) /* also data base */
#define PROGLOAD PROGBASE /* also data base */
#define PROGTOP ((uaddr_t)&__user_top) /* Top of program */
-#define SWAPBASE PROGBASE
-#define SWAPTOP PROGTOP
+#define SWAPBASE ((uaddr_t)&__swap_base)
+#define SWAPTOP ((uaddr_t)&__swap_top)
#define SWAP_SIZE ((SWAPTOP - SWAPBASE)/512)
#define MAX_SWAPS 8
#define swap_map(x) ((uint8_t*)(x))
; Wipe BSS.
mov.w #__bssstart, r12
- mov #0, r13
- mov.w #__bsssize, r14
- calla #memset
+1:
+ clr.b @r12
+ inc r12
+ cmp.w #__bssend, r12
+ jnz 1b
mov.w #__bss2start, r12
- mov #0, r13
- mov.w #__bss2size, r14
- calla #memset
+1:
+ clr.b @r12
+ inc r12
+ cmp.w #__bss2end, r12
+ jnz 1b
; Set some kernel variables.
mov.w #64, &ramsize
ttyready_t tty_writeready(uint8_t minor)
{
- return (UCA0IFG & UCTXIFG) ? TTY_READY_NOW : TTY_READY_LATER;
+ return (UCA0IFG & UCTXIFG) ? TTY_READY_NOW : TTY_READY_SOON;
}
void tty_setup(uint8_t minor)
RESETVEC : ORIGIN = 0xFFFE, LENGTH = 0x0002
BSL : ORIGIN = 0x1000, LENGTH = 0x0800
- SRAMLO : ORIGIN = 0x1C00, LENGTH = 0x0400
- SRAMHI : ORIGIN = 0x2000, LENGTH = 0x0400
- LOROM : ORIGIN = 0x4400, LENGTH = 0x7ffc-0x4400
+ SRAM : ORIGIN = 0x1C00, LENGTH = 0x0800
+
+ /* The kstack is at 0x7e00, and extends up to 0x8000, with four bytes
+ * reserved under 0x8000 for the syscall vector; UDATA goes at the top
+ * of userspace, just below 0xfe00. */
+ LOROM : ORIGIN = 0x4400, LENGTH = 0x7e00-0x4400
+ KSTACK : ORIGIN = 0x7e00, LENGTH = 0x1fc
SYSCALL : ORIGIN = 0x7ffc, LENGTH = 0x0004
- USER : ORIGIN = 0x8000, LENGTH = 0xfe00-0x8000
+ USER : ORIGIN = 0x8000, LENGTH = 0xfe00-0x8000-240
+ UDATA : ORIGIN = 0xfe00-240, LENGTH = 240
+
+ /* Desperately pack more variables into the 384-byte space between
+ * 0xfe00 and 0xff80 (where the system vectors start). */
LOROMX : ORIGIN = 0xfe00, LENGTH = 0xff80-0xfe00
+
HIROM : ORIGIN = 0x10000, LENGTH = 0x3FFF
}
+PROVIDE(__swap_base = 0x7e00);
+PROVIDE(__swap_top = 0xfe00);
+
PROVIDE(__user_base = ORIGIN(USER));
PROVIDE(__user_length = LENGTH(USER));
PROVIDE(__user_top = ORIGIN(USER) + LENGTH(USER));
-PROVIDE(udata = ORIGIN(SRAMLO));
-PROVIDE(kstack_top = ORIGIN(SRAMLO) + LENGTH(SRAMLO));
+PROVIDE(udata = ORIGIN(UDATA));
+PROVIDE(kstack_top = ORIGIN(KSTACK) + LENGTH(KSTACK));
SECTIONS
{
*(.text.fuzix_main)
*(.text.sgrpsig)
*(.text.srch_dir)
+ *(.text.switchout)
+ *(.text.dofork)
+ *(.text.getproc)
+ *(.text.rargs)
} > LOROM
.text : {
PROVIDE (etext = .);
} > HIROM
+ .bss : {
+ . = ALIGN(2);
+ PROVIDE (__bssstart = .);
+ *(.bss.bufpool);
+ *(.bss.blkdev_table);
+ *(.bss.tod);
+ *(.bss.ttydata);
+ . = ALIGN(2);
+ PROVIDE (__bssend = .);
+ } > LOROM
+ PROVIDE (__bsssize = SIZEOF(.bss));
+
.sram : {
. = ALIGN(2);
PROVIDE (__bss2start = .);
- *(.bss.ptab)
- *(.bss.blk_op)
- *(.bss.of_tab)
- *(.bss.tbuf1)
- *(.bss.blkdev_table)
- *(.bss.fs_tab)
- *(.bss.ttydata)
- *(.bss.ticks)
- *(.bss.tod)
+ *(.bss.*)
. = ALIGN(2);
PROVIDE (__bss2end = .);
- } > SRAMHI
+ } > SRAM
PROVIDE (__bss2size = SIZEOF(.sram));
.data : {
PROVIDE(__romdatastart = LOADADDR(.data));
PROVIDE (__romdatacopysize = SIZEOF(.data));
- .bss : {
- . = ALIGN(2);
- PROVIDE (__bssstart = .);
- *(.bss .bss.* .gnu.linkonce.b.*)
- . = ALIGN(2);
- PROVIDE (__bssend = .);
- } > LOROM
- PROVIDE (__bsssize = SIZEOF(.bss));
-
.MP430.attributes 0 :
{
KEEP (*(.MSP430.attributes))
; possibly the same process, and switches it in. When a process is
; restarted after calling switchout, it thinks it has just returned
; from switchout().
-;
-; This function can have no arguments or auto variables.
-.globl switchout
-switchout:
- bic.w #GIE, SR ; interrupts off
- mov #0, r12 ; set return code
+.globl switchin
+proc switchout
+ dint ; interrupts off
+ clr r12 ; set return code
pushm.a #12, r15 ; save all registers (r15 to r4)
push SR ; ...and the status register
- movx SP, &U_DATA__U_SP ; save stack pointer
- clra &inint
-
- ;calla #getproc
- jmp switchin ; switch in new process
- calla #trap_monitor ; should never reach here
+ mov SP, &U_DATA__U_SP ; save stack pointer
+ clr &inint
-.globl switchin
+ calla #getproc ; find a new process to run
switchin:
- bic.w #GIE, SR ; interrupts off
+ dint ; interrupts off
+ mov.w #U_DATA__U_PTAB, r12
+ mov.b #P_RUNNING, P_TAB__P_STATUS_OFFSET(r12) ; mark process as running
+
movx &U_DATA__U_SP, SP ; restore stack pointer
+ clr &runticks ; reset process run count
pop SR ; restore status register
popm.a #12, r15 ; restore all registers (r15 to r4)
- bis.w #GIE, SR ; interrupts on
+ eint ; interrupts on
reta
+; Forks to swap. On entry, r12 is the process pointer.
+
+proc dofork
+ dint
+
+ ; dofork suspends the parent; the scheduler will resume it again with
+ ; switchin. So we need to save the parent's state is if it had been
+ ; saved with switchout.
+
+ pushm.a #12, r15 ; save all registers (r15 to r4)
+ push SR ; ...and the status register
+ mov SP, &U_DATA__U_SP ; save stack pointer
+ clr &inint
+
+ ; Save the parent process to disk.
+
+ pushx.a r12
+ movx.a &U_DATA__U_PTAB, r12
+ calla #swapout
+ popx.a r12
+
+ ; Okay, done. Anything we change now won't affect the parent. Create the
+ ; child process. First we get rid of all the junk we put on the stack for
+ ; switchin.
+
+ add #12*4 + 2, sp
+
+ ; Now create the child process. (r12 is still the process pointer.)
+
+ calla #newproc
+
+ ; ...and we're ready to go.
+
+ clr &runticks ; reset process run count
+ clr r12 ; child fork returns zero!
+ eint ; interrupts on
+ reta