From: David Given Date: Mon, 29 Jun 2015 21:28:59 +0000 (+0200) Subject: Rearranged the memory layout so udata is at the top of userspace, above X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1823a8132818953b07af6b71ef38a3c975245fd2;p=FUZIX.git Rearranged the memory layout so udata is at the top of userspace, above 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. --- diff --git a/Kernel/lowlevel-msp430x.c b/Kernel/lowlevel-msp430x.c index 01f26f38..3795bc40 100644 --- a/Kernel/lowlevel-msp430x.c +++ b/Kernel/lowlevel-msp430x.c @@ -60,10 +60,3 @@ __attribute__ ((naked)) void unix_syscall_entry(void) "g" (udata.u_error) ); } - -int16_t dofork(ptptr child) -{ - kprintf("dofork\n"); - for (;;); -} - diff --git a/Kernel/platform-msp430fr5969/build.mk b/Kernel/platform-msp430fr5969/build.mk index aa3978d5..41c8d306 100644 --- a/Kernel/platform-msp430fr5969/build.mk +++ b/Kernel/platform-msp430fr5969/build.mk @@ -54,6 +54,7 @@ kernel.asflags += \ -g \ kernel.ldflags += \ + --relax \ -s kernel.libgcc = $(shell $(TARGETCC) -mlarge --print-libgcc) diff --git a/Kernel/platform-msp430fr5969/config.h b/Kernel/platform-msp430fr5969/config.h index 90c82efd..64c7b4ca 100644 --- a/Kernel/platform-msp430fr5969/config.h +++ b/Kernel/platform-msp430fr5969/config.h @@ -7,7 +7,7 @@ /* 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 @@ -31,13 +31,16 @@ 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)) diff --git a/Kernel/platform-msp430fr5969/crt0.S b/Kernel/platform-msp430fr5969/crt0.S index eacfaebe..357efceb 100644 --- a/Kernel/platform-msp430fr5969/crt0.S +++ b/Kernel/platform-msp430fr5969/crt0.S @@ -40,14 +40,18 @@ lowproc trap_reboot ; 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 diff --git a/Kernel/platform-msp430fr5969/devtty.c b/Kernel/platform-msp430fr5969/devtty.c index 89f2a338..62ccba3e 100644 --- a/Kernel/platform-msp430fr5969/devtty.c +++ b/Kernel/platform-msp430fr5969/devtty.c @@ -65,7 +65,7 @@ void tty_sleeping(uint8_t minor) 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) diff --git a/Kernel/platform-msp430fr5969/msp430fr5969.ld b/Kernel/platform-msp430fr5969/msp430fr5969.ld index 580316d6..c15fa13d 100644 --- a/Kernel/platform-msp430fr5969/msp430fr5969.ld +++ b/Kernel/platform-msp430fr5969/msp430fr5969.ld @@ -104,20 +104,32 @@ MEMORY { 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 { @@ -204,6 +216,10 @@ SECTIONS *(.text.fuzix_main) *(.text.sgrpsig) *(.text.srch_dir) + *(.text.switchout) + *(.text.dofork) + *(.text.getproc) + *(.text.rargs) } > LOROM .text : { @@ -215,21 +231,25 @@ SECTIONS 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 : { @@ -257,15 +277,6 @@ SECTIONS 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)) diff --git a/Kernel/platform-msp430fr5969/tricks.S b/Kernel/platform-msp430fr5969/tricks.S index a1efa04e..ba5994d5 100644 --- a/Kernel/platform-msp430fr5969/tricks.S +++ b/Kernel/platform-msp430fr5969/tricks.S @@ -6,28 +6,63 @@ ; 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