From 343a6e2f89d2a9a40eecd9167b07af00fc59c8c3 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 24 Jun 2015 23:15:39 +0200 Subject: [PATCH] Get to the point of failing to load /init. Seems that running the kernel in large mode and user processes in small mode isn't going to work; there are too many places where the kernel assumes that sizeof(userptr) == sizeof(kernelptr). I'll have to rebuild userland in large mode. --- Kernel/devio.c | 8 +++ Kernel/kernel430x.def | 50 ++++++++--------- Kernel/lowlevel-msp430x.S | 29 +++++++++- Kernel/platform-msp430fr5969/build.mk | 5 +- Kernel/platform-msp430fr5969/config.h | 2 +- Kernel/platform-msp430fr5969/crt0.S | 58 +++++++------------- Kernel/platform-msp430fr5969/kernel.def | 6 ++ Kernel/platform-msp430fr5969/msp430fr5969.ld | 29 +++++----- Kernel/platform-msp430fr5969/tricks.S | 10 ++-- Kernel/start.c | 3 +- Kernel/syscall_exec16.c | 7 ++- 11 files changed, 116 insertions(+), 91 deletions(-) diff --git a/Kernel/devio.c b/Kernel/devio.c index 5f7f7929..ff891163 100644 --- a/Kernel/devio.c +++ b/Kernel/devio.c @@ -506,6 +506,7 @@ void kprintf(const char *fmt, ...) { char *str; unsigned int v; + unsigned long l; char c; va_list ap; @@ -525,6 +526,13 @@ void kprintf(const char *fmt, ...) fmt++; continue; } + if ((*fmt == 'l') && (*(fmt+1) == 'x')) { + l = va_arg(ap, unsigned long); + /* TODO: not 32-bit safe */ + kputhex((uint16_t)(l >> 16)); + kputhex((uint16_t)l); + fmt += 2; + } if (*fmt == 'x' || *fmt == 'd' || *fmt == 'u') { v = va_arg(ap, int); if (*fmt == 'x') diff --git a/Kernel/kernel430x.def b/Kernel/kernel430x.def index f0431a3c..05291952 100644 --- a/Kernel/kernel430x.def +++ b/Kernel/kernel430x.def @@ -1,36 +1,36 @@ U_DATA = udata -; Keep these in sync with struct u_data!! -#define U_DATA__U_PTAB (U_DATA+0) ; struct p_tab* -#define U_DATA__U_PAGE (U_DATA+2) ; uint16_t -#define U_DATA__U_PAGE2 (U_DATA+4) ; uint16_t -#define U_DATA__U_INSYS (U_DATA+6) ; bool -#define U_DATA__U_CALLNO (U_DATA+7) ; uint8_t -#define U_DATA__U_SYSCALL_SP (U_DATA+8) ; void * -#define U_DATA__U_RETVAL (U_DATA+10) ; int16_t -#define U_DATA__U_ERROR (U_DATA+12) ; int16_t -#define U_DATA__U_SP (U_DATA+14) ; void * -#define U_DATA__U_ININTERRUPT (U_DATA+16) ; bool -#define U_DATA__U_CURSIG (U_DATA+17) ; int8_t -#define U_DATA__U_ARGN (U_DATA+18) ; uint16_t -#define U_DATA__U_ARGN1 (U_DATA+20) ; uint16_t -#define U_DATA__U_ARGN2 (U_DATA+22) ; uint16_t -#define U_DATA__U_ARGN3 (U_DATA+24) ; uint16_t -#define U_DATA__U_ISP (U_DATA+26) ; void * (initial stack pointer when _exec()ing) -#define U_DATA__U_TOP (U_DATA+28) ; uint16_t -#define U_DATA__U_BREAK (U_DATA+30) ; uint16_t -#define U_DATA__U_SIGVEC (U_DATA+32) ; table of function pointers (void *) +// Keep these in sync with struct u_data!! +#define U_DATA__U_PTAB (U_DATA+0) // struct p_tab* +#define U_DATA__U_PAGE (U_DATA+2) // uint16_t +#define U_DATA__U_PAGE2 (U_DATA+4) // uint16_t +#define U_DATA__U_INSYS (U_DATA+6) // bool +#define U_DATA__U_CALLNO (U_DATA+7) // uint8_t +#define U_DATA__U_SYSCALL_SP (U_DATA+8) // void * +#define U_DATA__U_RETVAL (U_DATA+10) // int16_t +#define U_DATA__U_ERROR (U_DATA+12) // int16_t +#define U_DATA__U_SP (U_DATA+14) // void * +#define U_DATA__U_ININTERRUPT (U_DATA+16) // bool +#define U_DATA__U_CURSIG (U_DATA+17) // int8_t +#define U_DATA__U_ARGN (U_DATA+18) // uint16_t +#define U_DATA__U_ARGN1 (U_DATA+20) // uint16_t +#define U_DATA__U_ARGN2 (U_DATA+22) // uint16_t +#define U_DATA__U_ARGN3 (U_DATA+24) // uint16_t +#define U_DATA__U_ISP (U_DATA+26) // void * (initial stack pointer when _exec()ing) +#define U_DATA__U_TOP (U_DATA+28) // uint16_t +#define U_DATA__U_BREAK (U_DATA+30) // uint16_t +#define U_DATA__U_SIGVEC (U_DATA+32) // table of function pointers (void *) -; Keep these in sync with struct p_tab!! +// Keep these in sync with struct p_tab!! P_TAB__P_STATUS_OFFSET = 0 P_TAB__P_TTY_OFFSET = 1 P_TAB__P_PID_OFFSET = 2 P_TAB__P_PAGE_OFFSET = 14 -P_RUNNING = 1 ; value from include/kernel.h -P_READY = 2 ; value from include/kernel.h +P_RUNNING = 1 // value from include/kernel.h +P_READY = 2 // value from include/kernel.h -OS_BANK = 0 ; value from include/kernel.h +OS_BANK = 0 // value from include/kernel.h -EAGAIN = 11 ; value from include/kernel.h +EAGAIN = 11 // value from include/kernel.h diff --git a/Kernel/lowlevel-msp430x.S b/Kernel/lowlevel-msp430x.S index b269fdc1..230c9131 100644 --- a/Kernel/lowlevel-msp430x.S +++ b/Kernel/lowlevel-msp430x.S @@ -1,3 +1,4 @@ +#include "platform-msp430fr5969/kernel.def" #include "kernel430x.def" .section ".lowtext" @@ -7,7 +8,7 @@ interrupt_handler: * may be the user process or the kernel's. We haven't saved any * registers yet. */ - mov SP, &istack_switched_sp ; save old stack (16 bit!) + movx.w SP, &istack_switched_sp ; save old stack (16 bit!) mov #istack_top, SP ; load new one pushm.a #13, r15 ; save all registers (r15 to r3) @@ -16,6 +17,30 @@ interrupt_handler: popm.a #13, r15 ; restore all registers (r15 to r3) - mov &istack_switched_sp, SP ; restore stack + movx.w &istack_switched_sp, SP ; restore stack reti +proc doexec + dint + #if 0 + di + call map_process_always + + pop bc ; return address + pop de ; start address + + ld hl, (U_DATA__U_ISP) + ld sp, hl ; Initialize user stack, below main() parameters and the environment + + ; u_data.u_insys = false + xor a + ld (U_DATA__U_INSYS), a + + ex de, hl + + ; for the relocation engine - tell it where it is + ld iy, #PROGLOAD + ei + jp (hl) +#endif + jmp . diff --git a/Kernel/platform-msp430fr5969/build.mk b/Kernel/platform-msp430fr5969/build.mk index b6c4b7ed..6ca72144 100644 --- a/Kernel/platform-msp430fr5969/build.mk +++ b/Kernel/platform-msp430fr5969/build.mk @@ -17,12 +17,15 @@ kernel.srcs = \ ../dev/mbr.c \ ../devio.c \ ../filesys.c \ + ../inode.c \ ../lowlevel-msp430x.S \ ../kdata.c \ ../process.c \ ../simple.c \ ../start.c \ ../swap.c \ + ../syscall_exec16.c \ + ../syscall_fs.c \ ../timer.c \ ../tty.c \ ../usermem.c \ @@ -44,7 +47,7 @@ kernel.asflags += \ -mlarge kernel.ldflags += \ - -g + -s kernel.libgcc = $(shell $(TARGETCC) -mlarge --print-libgcc) kernel.result = $(TOP)/kernel-$(PLATFORM).elf diff --git a/Kernel/platform-msp430fr5969/config.h b/Kernel/platform-msp430fr5969/config.h index 7fd39ab2..a0e25516 100644 --- a/Kernel/platform-msp430fr5969/config.h +++ b/Kernel/platform-msp430fr5969/config.h @@ -42,7 +42,7 @@ extern unsigned char vt_mangle_6847(unsigned char c); extern int __user_base; #define TICKSPERSEC 64 /* Ticks per second */ -#define PROGBASE ((uint16_t)(size_t)&__user_base) /* also data base */ +#define PROGBASE ((uint32_t)(size_t)&__user_base) /* also data base */ #define PROGLOAD PROGBASE /* also data base */ #define PROGTOP 0xfe00 /* Top of program */ diff --git a/Kernel/platform-msp430fr5969/crt0.S b/Kernel/platform-msp430fr5969/crt0.S index d7910a95..71b4d08a 100644 --- a/Kernel/platform-msp430fr5969/crt0.S +++ b/Kernel/platform-msp430fr5969/crt0.S @@ -8,9 +8,6 @@ .globl init_early .globl init_hardware -; Set up the stacks. - - .section ".noinit" ; The interrupt stack. @@ -23,13 +20,7 @@ istack_top: .globl istack_switched_sp .comm istack_switched_sp, 2 -; The userdata/system stack structure. See Kernel/include/kernel.h. -.globl udata -udata: - .fill 512 -kstack_top: - -.text +.section ".lowtext", "ax", @progbits .globl __main __main: ; Disable watchdog timer. @@ -59,23 +50,17 @@ __main: mov.b #0, &CSCTL0_H ; Relock clock registers ; Init stack. - mov #kstack_top, SP + movx.a #kstack_top, SP ; Wipe BSS. - mov #__bssstart, r12 - mov #0, r13 - mov #__bsssize, r14 - calla #memset - - ; Wipe the extra, big bit of BSS. - mov #__bigbssstart, r12 + movx.a #__bssstart, r12 mov #0, r13 - mov #__bigbsssize, r14 + movx.a #__bsssize, r14 calla #memset ; Set some kernel variables. - mov.w #64, &ramsize - mov.w #32, &procmem + movx.w #64, &ramsize + movx.w #32, &procmem ; Call C routines. calla #tty_rawinit @@ -86,37 +71,32 @@ stop: __reti: reti -.globl trap_monitor -trap_monitor: +proc trap_monitor bic.w #GIE, SR jmp trap_monitor -.globl abort -abort: +proc abort bic.w #GIE, SR - mov #1f, r12 - mov #kstack_top, sp + movx.a #1f, r12 + movx.a #kstack_top, sp calla #kprintf jmp . -.data +.data 1 1: .asciz "[abort]\n" .text -.globl ei -ei: +proc ei bis.w #GIE, SR reta -.globl di -di: +proc di ; Return the old interrupt status in r12. mov SR, r12 and #~GIE, r12 bic.w #GIE, SR reta -.globl irqrestore -irqrestore: +proc irqrestore bic.w #GIE, SR ; Ensure off bis.w r12, SR ; Mask in saved value reta @@ -130,17 +110,17 @@ irqrestore: #define standard_interrupt(name, irq) \ .globl name ## _trampoline { \ - .section ".lowtext", "ax", @progbits { \ + .section ".lowtext" { \ name ## _trampoline: \ - mov.b #(irq), &last_interrupt { \ + movx.b #(irq), &last_interrupt { \ bra #interrupt_handler { \ .section #name, "ax", @progbits { \ .word name ## _trampoline #define fallback_interrupt(name) \ - .text { \ - 1: mov #3f, r12 { \ - mov #kstack_top, sp { \ + .section ".lowtext" { \ + 1: movx.a #3f, r12 { \ + movx.a #kstack_top, sp { \ calla #kprintf { \ 2: jmp 2b { \ .data { \ diff --git a/Kernel/platform-msp430fr5969/kernel.def b/Kernel/platform-msp430fr5969/kernel.def index 830a16ac..230a27b6 100644 --- a/Kernel/platform-msp430fr5969/kernel.def +++ b/Kernel/platform-msp430fr5969/kernel.def @@ -1,2 +1,8 @@ U_DATA = udata +.macro proc NAME + .section .text.\NAME + .globl \NAME + \NAME: +.endm + diff --git a/Kernel/platform-msp430fr5969/msp430fr5969.ld b/Kernel/platform-msp430fr5969/msp430fr5969.ld index ed363cd0..a6ed6a5e 100644 --- a/Kernel/platform-msp430fr5969/msp430fr5969.ld +++ b/Kernel/platform-msp430fr5969/msp430fr5969.ld @@ -105,7 +105,9 @@ MEMORY { BSL : ORIGIN = 0x1000, LENGTH = 0x0800 SRAM : ORIGIN = 0x1C00, LENGTH = 0x0800 /* END=0x23FF, size 2048 */ - LOROM : ORIGIN = 0x4400, LENGTH = 0x8000-0x4400 + LOROM : ORIGIN = 0x4400, LENGTH = 0x7e00-0x4400 + UDATA : ORIGIN = 0x7e00, LENGTH = 0x015c + SYSCALL : ORIGIN = 0x7ffc, LENGTH = 0x0004 USER : ORIGIN = 0x8000, LENGTH = 0xfe00-0x8000 LOROMX : ORIGIN = 0xfe00, LENGTH = 0xff80-0xfe00 HIROM : ORIGIN = 0x10000, LENGTH = 0x3FFF @@ -113,6 +115,8 @@ MEMORY { PROVIDE(__user_base = ORIGIN(USER)); PROVIDE(__user_length = LENGTH(USER)); +PROVIDE(udata = ORIGIN(UDATA)); +PROVIDE(kstack_top = ORIGIN(UDATA) + LENGTH(UDATA)); SECTIONS { @@ -178,6 +182,7 @@ SECTIONS KEEP (*(.resetvec)) } > RESETVEC + .rodata : { . = ALIGN(2); *(.plt) @@ -219,13 +224,18 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) - } > HIROM + } > LOROM + + .lowtext : { + . = ALIGN(2); + PROVIDE (_start = .); + *(.lowtext) + } > LOROM .text : { . = ALIGN(2); - PROVIDE (_start = .); KEEP (*(SORT(.crt_*))) - *(.lowtext .text .stub .text.* .gnu.linkonce.t.* .text:*) + *(.text .stub .text.* .gnu.linkonce.t.* .text:*) KEEP (*(.text.*personality*)) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) @@ -237,7 +247,7 @@ SECTIONS KEEP (*(.init)) KEEP (*(.fini)) KEEP (*(.tm_clone_table)) - } > LOROM + } > HIROM .data : { . = ALIGN(2); @@ -282,15 +292,6 @@ SECTIONS } > LOROM PROVIDE (__bsssize = SIZEOF(.bss)); - .bigbss (NOLOAD) : { - . = ALIGN(2); - PROVIDE (__bigbssstart = .); - *(.bigbss .bigbss.*) - . = ALIGN(2); - PROVIDE (__bigbssend = .); - } > LOROM - PROVIDE (__bigbsssize = SIZEOF(.bigbss)); - .noinit (NOLOAD) : { . = ALIGN(2); PROVIDE (__noinit_start = .); diff --git a/Kernel/platform-msp430fr5969/tricks.S b/Kernel/platform-msp430fr5969/tricks.S index 66fb09e0..a1efa04e 100644 --- a/Kernel/platform-msp430fr5969/tricks.S +++ b/Kernel/platform-msp430fr5969/tricks.S @@ -14,19 +14,19 @@ switchout: bic.w #GIE, SR ; interrupts off mov #0, r12 ; set return code pushm.a #12, r15 ; save all registers (r15 to r4) - pushx.a SR ; ...and the status register - mova SP, &U_DATA__U_SP ; save stack pointer + push SR ; ...and the status register + movx SP, &U_DATA__U_SP ; save stack pointer clra &inint ;calla #getproc - calla #switchin ; switch in new process + jmp switchin ; switch in new process calla #trap_monitor ; should never reach here .globl switchin switchin: bic.w #GIE, SR ; interrupts off - mova &U_DATA__U_SP, SP ; restore stack pointer - popx.a SR ; restore status register + movx &U_DATA__U_SP, SP ; restore stack pointer + pop SR ; restore status register popm.a #12, r15 ; restore all registers (r15 to r4) bis.w #GIE, SR ; interrupts on reta diff --git a/Kernel/start.c b/Kernel/start.c index b449fdcd..824375c3 100644 --- a/Kernel/start.c +++ b/Kernel/start.c @@ -80,6 +80,7 @@ void create_init(void) *j = NO_FILE; } /* Poke the execve arguments into user data space so _execve() can read them back */ + kprintf("PROGLOAD=%lx\n", (void*)PROGLOAD); uput(arg, (void *)PROGLOAD, sizeof(arg)); /* Poke in argv[0] - FIXME: Endianisms... */ uputw(PROGLOAD+1 , (void *)(PROGLOAD + 7)); @@ -300,7 +301,6 @@ void fuzix_main(void) if (fmount(root_dev, NULLINODE, 0)) panic("no filesys"); -#if 0 root = i_open(root_dev, ROOTINODE); if (!root) panic("no root"); @@ -311,6 +311,5 @@ void fuzix_main(void) udata.u_root = i_ref(root); rdtime32(&udata.u_time); exec_or_die(); -#endif } diff --git a/Kernel/syscall_exec16.c b/Kernel/syscall_exec16.c index a3784794..710199c0 100644 --- a/Kernel/syscall_exec16.c +++ b/Kernel/syscall_exec16.c @@ -74,8 +74,10 @@ char *envp[]; static int header_ok(uint8_t *pp) { register uint8_t *p = pp; - if (*p != EMAGIC && *p != EMAGIC_2) - return 0; + #if defined(EMAGIC) || defined(EMAGIC_2) + if (*p != EMAGIC && *p != EMAGIC_2) + return 0; + #endif p += 3; if (*p++ != 'F' || *p++ != 'Z' || *p++ != 'X' || *p++ != '1') return 0; @@ -99,6 +101,7 @@ arg_t _execve(void) top = ramtop; + kprintf("name=%lx\n", name); if (!(ino = n_open(name, NULLINOPTR))) return (-1); -- 2.34.1