[PATCH] Fixes and rationalization of startup code
Juan Perez-Sanchez <[email protected]>
| Newsgroups | org.kernel.vger.linux-8086 |
|---|---|
| Message-ID | <CAD6VGuat3868Zsu32+GZXP2UTohaCNPe1A9qEdaSxSzsZrPzCw@mail.gmail.com> |
Hi, This patch fixes a bug consisting that, during startup, the determination of cpu class was done AFTER it was needed by some functions. The patch also reorganizes the startup code that was scattered among several files. Greetings, Juan 2. Variable "arch_cpu" was initialized in function "setup_mm". This variable is needed in function "init_IRQ". However, during startup function "init_IRQ" was called before function "setup_mm". 3. In file "arch/i86/kernel/system.c" there was a FIXME note stating that "setupw expects TWO parameters". Actually, that function expects one parameter. 4. Functions "setupw" and "setupb" are almost identical. The only difference is that setupb returns "char" and the 8 most significant bits of register ax are set to zero. NEW OPERATION 1. The architecture independent initialization of task array was moved to function "sched_init". The remaining architecture dependent code was concentrated in function "setup_arch". The call to function "sched_init" is now the first in the startup process. 2. Initialization of variable "arch_cpu" was moved to function "setup_arch". 3. Fixed references to function "setupw" usage. 4. Removed function "setupb". It was replaced with a macro consisting of a call to "setupw" casted to char, saving ~20 bytes. OTHER CHANGES 1. A small optimization to reduce code size was done in files irq.c, irqtab.c and mkentry.sh. There is a reduction in code size of 32 bytes. The Image builded without errors. The kernel was tested with QEMU and dioscuri emulators. Also in a PPro pc booting from floppy.
elksJ.patch
(application/octet-stream, 8.2 KB)
diff -Nurb elks.orig/arch/i86/drivers/char/bioscon.c elks/arch/i86/drivers/char/bioscon.c
--- elks.orig/arch/i86/drivers/char/bioscon.c 2012-05-11 13:26:27.000000000 -0500
+++ elks/arch/i86/drivers/char/bioscon.c 2012-07-03 17:17:03.000000000 -0500
@@ -17,6 +17,8 @@
#include <linuxmt/ntty.h>
#include <linuxmt/debug.h>
+#include <arch/segment.h>
+
#ifdef CONFIG_CONSOLE_BIOS
int read_kbd(void);
diff -Nurb elks.orig/arch/i86/kernel/irq.c elks/arch/i86/kernel/irq.c
--- elks.orig/arch/i86/kernel/irq.c 2012-07-03 17:23:46.000000000 -0500
+++ elks/arch/i86/kernel/irq.c 2012-07-03 17:12:18.000000000 -0500
@@ -149,6 +149,8 @@
/* this version is smaller than the functionally equivalent C version
* at 7 bytes vs. 21 or thereabouts :-) --Alastair Bridgewater
+ *
+ * Further reduced to 5 bytes --Juan Perez
*/
#ifndef S_SPLINT_S
#asm
@@ -157,10 +159,8 @@
_restore_flags:
pop ax
- pop cx
- push cx
- push cx
popf
+ pushf
jmp ax
#endasm
#endif
diff -Nurb elks.orig/arch/i86/kernel/irqtab.c elks/arch/i86/kernel/irqtab.c
--- elks.orig/arch/i86/kernel/irqtab.c 2012-07-03 17:23:56.000000000 -0500
+++ elks/arch/i86/kernel/irqtab.c 2012-07-03 17:12:18.000000000 -0500
@@ -46,11 +46,9 @@
; CS points to this kernel code segment
; ES points to page 0 (interrupt table)
-; DS points to the irqdataseg (cs or CONFIG_ROM_IRQ_DATA)
+; DS points to the kernel data segment
- push ds
- mov dx,ds ;the original value
- cli ;just here
+ cli
#ifdef CONFIG_ROMCODE
mov ax,#CONFIG_ROM_IRQ_DATA
@@ -121,9 +119,8 @@
mov [514],ax
! Tidy up
- pop ds ;the org segments
- mov ax,ds
- mov es,ax
+ mov dx,ds ;the original value
+ mov es,dx ;just here
sti
#endasm
diff -Nurb elks.orig/arch/i86/kernel/mkentry.sh elks/arch/i86/kernel/mkentry.sh
--- elks.orig/arch/i86/kernel/mkentry.sh 2012-05-11 13:26:27.000000000 -0500
+++ elks/arch/i86/kernel/mkentry.sh 2012-07-03 17:12:18.000000000 -0500
@@ -96,9 +96,8 @@
ja _nsyscall
! look up address and jump to function
mov bx,ax
- shl bx,#1 ! multiply by 2
- add bx,#sys_call_table
- j [bx]
+ add bx,ax ! multiply by 2
+ j sys_call_table[bx]
! All unimplemented calls
diff -Nurb elks.orig/arch/i86/kernel/system.c elks/arch/i86/kernel/system.c
--- elks.orig/arch/i86/kernel/system.c 2012-07-03 17:23:46.000000000 -0500
+++ elks/arch/i86/kernel/system.c 2012-07-03 17:12:18.000000000 -0500
@@ -29,7 +29,6 @@
void setup_arch(seg_t *start, seg_t *end)
{
register __ptask taskp;
- int ct;
#ifndef S_SPLINT_S
/*
@@ -37,17 +36,14 @@
*/
#asm
mov bx, #_arch_segs
- mov ax, cs
- mov [bx], ax
+ mov [bx], cs
mov [bx+2], di
- mov ax, ss
- mov [bx+8], ax
+ mov [bx+8], ss
mov [bx+6], si
! This is out of order to save a segment load and a few bytes :)
- mov ax, ds
- mov [bx+4], ax
+ mov [bx+4], ds
mov [bx+10], dx
! mov ds, ax
@@ -58,20 +54,14 @@
arch_segs.lowss = arch_segs.endss;
/*
- * Now create task 0 to be ourself. Set the kernel SP,
+ * arch dependent sched init. Set the kernel SP,
* as we will need this in interrupts.
*/
taskp = &task[0];
taskp->t_regs.cs = get_cs();
-
taskp->t_regs.ds = taskp->t_regs.ss = get_ds(); /* Run in kernel space */
taskp->t_regs.ksp = ((__u16) taskp->t_kstack) + KSTACK_BYTES;
-
- taskp->state = TASK_RUNNING;
taskp->t_kstackm = KSTACK_MAGIC;
- taskp->next_run = taskp->prev_run = taskp;
-
- current = taskp;
#ifdef CONFIG_COMPAQ_FAST
@@ -84,29 +74,12 @@
#endif
/*
- * Mark tasks 1-31 as not in use.
- */
-
- for (ct=1; ct < MAX_TASKS; ct++) {
-
-#if 0
- taskp = &task[ct];
-#endif
-
- taskp++;
- taskp->state=TASK_UNUSED;
- taskp->t_kstackm = KSTACK_MAGIC;
- }
-
-/*
* Fill in the MM numbers - really ought to be in mm not kernel ?
*/
#ifndef CONFIG_ARCH_SIBO
- /* FIXME: setupw expects TWO parameters */
-
- /*@i1@*/ *end = setupw(0x2a) << 6 - RAM_REDUCE;
+ *end = setupw(0x2a) << 6 - RAM_REDUCE;
/* XXX plac: free root ram disk */
@@ -123,6 +96,8 @@
ROOT_DEV = setupw(0x1fc);
+ arch_cpu = setupb(0x20);
+
}
#ifndef S_SPLINT_S
diff -Nurb elks.orig/arch/i86/lib/Makefile elks/arch/i86/lib/Makefile
--- elks.orig/arch/i86/lib/Makefile 2012-05-11 13:26:27.000000000 -0500
+++ elks/arch/i86/lib/Makefile 2012-07-03 17:20:02.000000000 -0500
@@ -46,7 +46,7 @@
LLOBJS =laddl.o landl.o lcmpl.o lcoml.o ldecl.o ldivl.o ldivul.o \
leorl.o lincl.o lmodl.o lmodul.o lmull.o lnegl.o lorl.o \
- lsll.o lsrl.o lsrul.o lsubl.o ltstl.o setupw.o setupb.o
+ lsll.o lsrl.o lsrul.o lsubl.o ltstl.o setupw.o
# compiler support for long arithmetic on all longs
@@ -61,7 +61,7 @@
ar rcs lib86.a $(OBJS)
sync
-setupb.s: setupb.S
+#setupb.s: setupb.S
setupw.s: setupw.S
diff -Nurb elks.orig/arch/i86/lib/setupw.S elks/arch/i86/lib/setupw.S
--- elks.orig/arch/i86/lib/setupw.S 2012-05-11 13:26:27.000000000 -0500
+++ elks/arch/i86/lib/setupw.S 2012-07-03 17:12:18.000000000 -0500
@@ -1,4 +1,4 @@
-! int setupw( unsigned segment, int *offset );
+! int setupw( int *offset );
! returns the word at the far pointer 0x9000:offset
#include <linuxmt/config.h>
@@ -10,7 +10,6 @@
_setupw:
mov cx,ds
pop dx
- pop bx
#ifndef CONFIG_286PMODE
mov ax,#DEF_INITSEG
@@ -19,6 +18,7 @@
#endif
mov ds,ax
+ pop bx
sub sp,*2
mov ax,[bx]
mov ds,cx
diff -Nurb elks.orig/arch/i86/mm/init.c elks/arch/i86/mm/init.c
--- elks.orig/arch/i86/mm/init.c 2012-05-11 13:26:27.000000000 -0500
+++ elks/arch/i86/mm/init.c 2012-07-03 17:12:18.000000000 -0500
@@ -34,8 +34,6 @@
__u16 basemem = setupw(0x2a);
__u16 xms = setupw(2); /* Fetched by boot code */
- arch_cpu = setupb(0x20);
-
for (pi = 0; ((int)pi) < 16; pi++) {
proc_name[(int)pi] = setupb(0x30 + (int)pi);
cpuid[(int)pi] = setupb(0x50 + (int)pi);
diff -Nurb elks.orig/arch/i86/sibo/irqtab.c elks/arch/i86/sibo/irqtab.c
--- elks.orig/arch/i86/sibo/irqtab.c 2012-07-03 17:23:56.000000000 -0500
+++ elks/arch/i86/sibo/irqtab.c 2012-07-03 17:12:18.000000000 -0500
@@ -52,9 +52,7 @@
out 0x15, al
mov al, #0x00
out 0x08, al
- push ds
- mov dx,ds ;the original value
- cli ;just here
+ cli
#ifdef CONFIG_ROMCODE
mov ax,#CONFIG_ROM_IRQ_DATA
@@ -126,9 +124,8 @@
mov [514],ax
! Tidy up
- pop ds ;the org segments
- mov ax,ds
- mov es,ax
+ mov dx,ds ;the original value
+ mov es,dx ;just here
sti
#endasm
diff -Nurb elks.orig/include/arch/segment.h elks/include/arch/segment.h
--- elks.orig/include/arch/segment.h 2012-05-11 13:26:27.000000000 -0500
+++ elks/include/arch/segment.h 2012-07-03 17:21:09.000000000 -0500
@@ -20,7 +20,9 @@
#endif
-extern __u16 setupw(/*unsigned short int, */unsigned short int *);
+extern __u16 setupw(unsigned short int *);
+
+#define setupb(p) ((char)setupw(p))
extern pid_t get_pid(void);
diff -Nurb elks.orig/init/main.c elks/init/main.c
--- elks.orig/init/main.c 2012-07-03 17:23:46.000000000 -0500
+++ elks/init/main.c 2012-07-03 17:12:18.000000000 -0500
@@ -29,8 +29,6 @@
static void init_task(void);
extern int run_init_process(char *, char *);
-extern __ptask _reglasttask, _regnexttask;
-
jiff_t loops_per_sec = 1;
/*
@@ -43,6 +41,7 @@
/* We set the scheduler up as task #0, and this as task #1 */
+ sched_init();
setup_arch(&base, &end);
mm_init(base, end);
init_IRQ();
@@ -63,7 +62,6 @@
device_setup();
inode_init();
fs_init();
- sched_init();
printk("ELKS version %s\n", system_utsname.release);
diff -Nurb elks.orig/kernel/sched.c elks/kernel/sched.c
--- elks.orig/kernel/sched.c 2012-07-03 17:23:56.000000000 -0500
+++ elks/kernel/sched.c 2012-07-03 17:12:18.000000000 -0500
@@ -289,5 +289,24 @@
void sched_init(void)
{
- /* Do nothing */ ;
+ register struct task_struct *taskp;
+
+/*
+ * Now create task 0 to be ourself.
+ */
+ taskp = &init_task;
+ memset(taskp, 0, sizeof(struct task_struct));
+ taskp->state = TASK_RUNNING;
+ taskp->next_run = taskp->prev_run = taskp;
+
+ current = taskp;
+/* nr_running = 0;*/
+
+/*
+ * Mark tasks 1-31 as not in use.
+ */
+
+ while(++taskp < &task[MAX_TASKS])
+ taskp->state=TASK_UNUSED;
+
}