Hi, This patch aims to improve portability to other platforms. With this goal, there should not be any assembly code at the upper level directories. This patch moves the "hard_reset_now" function, written entirely in assembler, from the "kernel" directory, to the architecture dependent file "arch/i86/kernel/system.c". The function init_task() in file init/main.c had an small assembly code sequence to start the init task. The function run_init_process() was defined in the arch dependent file "arch/i86/kernel/process.c" to be similar to mainstream linux, and to include that assembly code. This modification had the side effect of saving ~100 bytes of code. The last bit of assembly in init/main.c is the delay function. Both C and assembly implementations existed in this file, as an example of how inefficient is bcc, but used the assembly one. I replaced the C imple- mentation of delay() with a more compact (but neither faster nor more portable) code than any of the original versions, and removed the assembly code. I found that bcc ignores the "register" keyword. Then, it's not possible to write faster code in C. Also, it's safe to remove any "register" keyword. The Image builded without errors. The kernel was tested with QEMU and dioscuri emulators. Also in a PPro pc booting from floppy. Greetings, Juan diff -Nurb elks.orig/arch/i86/kernel/process.c elks/arch/i86/kernel/process.c --- elks.orig/arch/i86/kernel/process.c 2012-03-26 14:28:24.000000000 -0600 +++ elks/arch/i86/kernel/process.c 2012-05-03 17:27:44.000000000 -0500 @@ -372,6 +372,36 @@ #endasm #endif +int run_init_process(char *cmd, char *ar) +{ + int num; + unsigned short int *pip = (unsigned short int *)ar; + + *pip++ = 0; + *pip++ = (unsigned short int) &ar[6]; + *pip++ = 0; + if(num = sys_execve(cmd, ar, 18)) + return num; +#ifndef S_SPLINT_S + /* Brackets round the following code are required as a work around + * for a bug in the compiler which causes it to jump past the asm + * code if they are not there. + */ + { +#asm + cli + mov bx, _current + mov sp, 2[bx] ! user stack offset + mov ax, 4[bx] ! user stack segment + mov ss, ax + mov ds, ax + mov es, ax + iret ! reloads flags = >reenables interrupts +#endasm + } +#endif +} + /* * We only need to do this as long as we support old format binaries * that grow stack and heap towards each other diff -Nurb elks.orig/arch/i86/kernel/system.c elks/arch/i86/kernel/system.c --- elks.orig/arch/i86/kernel/system.c 2012-03-26 14:28:24.000000000 -0600 +++ elks/arch/i86/kernel/system.c 2012-05-03 17:27:44.000000000 -0500 @@ -11,6 +11,21 @@ int arch_cpu; /* Processor type */ extern long int basmem; +/* Stubs for functions needed elsewhere */ + +void hard_reset_now(void) +{ +#ifndef S_SPLINT_S +#asm + mov ax,#0x40 ! No memory check on reboot + mov ds, ax + mov [0x72],#0x1234 + jmp #0xffff:0 + +#endasm +#endif +} + void setup_arch(seg_t *start, seg_t *end) { register __ptask taskp; diff -Nurb elks.orig/init/main.c elks/init/main.c --- elks.orig/init/main.c 2012-03-26 14:28:24.000000000 -0600 +++ elks/init/main.c 2012-05-04 15:01:03.000000000 -0500 @@ -27,6 +27,7 @@ /**************************************/ static void init_task(void); +extern int run_init_process(char *, char *); extern __ptask _reglasttask, _regnexttask; @@ -92,14 +93,7 @@ { int num; - /* Make sure the correct exec stack is in place for init. */ - - unsigned short int *pip = (unsigned short int *) args; - - *++pip = (unsigned short int) &args[5]; - mount_root(); - printk("Loading init\n"); /* The Linux kernel traditionally attempts to start init from 4 locations, @@ -113,149 +107,43 @@ * So, I've modified the ELKS kernel to follow this tradition. */ - if ((num = sys_execve("/sbin/init", args, 18))) { - + num = run_init_process("/sbin/init", args); printk("sys_execve(\"/sbin/init\",args,18) => %d.\n",num); - - if ((num = sys_execve("/etc/init", args, 18))) { - + num = run_init_process("/etc/init", args); printk("sys_execve(\"/etc/init\",args,18) => %d.\n",num); - - if ((num = sys_execve("/bin/init", args, 18))) { - + num = run_init_process("/bin/init", args); printk("sys_execve(\"/bin/init\",args,18) => %d.\n",num); - #ifdef CONFIG_CONSOLE_SERIAL num = sys_open("/dev/ttyS0", 2, 0); #else num = sys_open("/dev/tty1", 2, 0); #endif - if (num < 0) printk("Unable to open /dev/tty (error %u)\n", -num); if (sys_dup(0) != 1) printk("dup failed\n"); - sys_dup(0); - printk("No init - running /bin/sh\n"); - if (sys_execve("/bin/sh", args, 0)) + num = run_init_process("/bin/sh", args); + printk("sys_execve(\"/bin/sh\",args,18) => %d.\n",num); panic("No init or sh found"); - } - } - } - - -#ifndef S_SPLINT_S - - /* Brackets round the following code are required as a work around - * for a bug in the compiler which causes it to jump past the asm - * code if they are not there. - * - * This kludge is here because we called sys_execve directly, rather - * than via syscall_int (a BIOS interrupt). So we simulate the last - * part of syscall_int, which restores context back to the user process. - */ - { -#asm - cli - mov bx, _current - mov sp, 2[bx] ! user stack offset - mov ax, 4[bx] ! user stack segment - mov ss, ax - mov ds, ax - mov es, ax - iret ! reloads flags = >reenables interrupts -#endasm - } -#endif - - panic("iret failed!"); } /* * Yes its the good old bogomip counter */ -#ifdef USE_C - static void delay(jiff_t loops) { - jiff_t i; - for (i = loops; i >= 0; i--) - /* Do nothing */ ; + do { + do { + } while((*((unsigned int *)(&loops)))--); + } while((*(((unsigned int *)(&loops))+1))--); } -#else - -static void delay(jiff_t loops); - -#ifndef S_SPLINT_S - -/* - * The C one just shows bcc isnt always[often] a very good - * compiler. This is a non optimal but fairly passable assembler - * bogomips that should be constant over compilers. - */ - -#asm - .text - -_delay: - -! Create the stack frame - - push bp - mov bp,sp - -! Get the high word - - mov ax,6[bp] - -! Delay the higher word - - or ax,ax - jz dellow - -axlp: - xor bx,bx - -! Delay a complete low word loop time - -bxlp: - dec bx - jnz bxlp - -! Now back around for the next high word - - dec ax - jnz axlp - -! Delay for the low part of the time - -dellow: - mov ax,4[bp] - or ax,bx - jz deldone - -dellp: - dec ax - jnz dellp - -! Recover stack frame and return - -deldone: - pop bp - ret -#endasm - -#endif - -#endif - int calibrate_delay(void) { jiff_t ticks, bogo, sub; diff -Nurb elks.orig/kernel/Makefile elks/kernel/Makefile --- elks.orig/kernel/Makefile 2012-03-26 14:28:24.000000000 -0600 +++ elks/kernel/Makefile 2012-05-04 15:09:34.000000000 -0500 @@ -25,7 +25,7 @@ DISTFILES = -NOINDENT = memdumpk.c stubs.c +NOINDENT = memdumpk.c ######################################################################### # Include standard commands. @@ -35,7 +35,7 @@ ######################################################################### # Objects to compile. -OBJS = sched.o printk.o sleepwake.o dma.o version.o sys.o stubs.o fork.o \ +OBJS = sched.o printk.o sleepwake.o dma.o version.o sys.o fork.o \ exit.o time.o signal.o ######################################################################### diff -Nurb elks.orig/kernel/stubs.c elks/kernel/stubs.c --- elks.orig/kernel/stubs.c 2012-03-26 14:28:24.000000000 -0600 +++ elks/kernel/stubs.c 2012-05-03 17:27:44.000000000 -0500 @@ -1,14 +0,0 @@ -/* Stubs for functions needed elsewhere */ - -void hard_reset_now(void) -{ -#ifndef S_SPLINT_S -#asm - mov ax,#0x40 ! No memory check on reboot - mov ds, ax - mov [0x72],#0x1234 - jmp #0xffff:0 - -#endasm -#endif -} -- To unsubscribe from this list: send the line "unsubscribe linux-8086" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html