[PATCH] Final bits to compile using ia16-unknown-elks-gcc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

-File arch/i86/mm/user.c is now only C. The assembly
 functions were moved to arch/i86/mm/segment.c
-Changes in several Makefile's and Makefile-rules to
 support compiling using ia16-unknown-elks-gcc
-Addition of a C runtime library function needed by
 ia16-unknown-elks-gcc

The kernel was compiled with BCC and tested with QEMU.
Code size was reduced in 16 bytes.

Compilation using BCC is as usual.
To actually compile using ia16-unknown-elks-gcc you need:

 1. The ia16-unknown-elks toolchain and a helper named
    att2as86. In later posts I'll explain how to build them.
 2. To have the binaries of the above utilities in your PATH
 3. Rename the following files from *.c to *.S
     arch/i86/kernel/bios16.c
     arch/i86/kernel/irqtab.c
     arch/i86/kernel/printreg.c
     arch/i86/mm/segment.c
 4. Apply the following patch:
 *****************************************************************************

 diff -Nur elks.orig/arch/i86/kernel/Makefile elks/arch/i86/kernel/Makefile
--- elks.orig/arch/i86/kernel/Makefile  2015-06-12 10:31:05.309516062 -0500
+++ elks/arch/i86/kernel/Makefile       2015-06-12 10:59:04.241934884 -0500
@@ -47,6 +47,12 @@
 #########################################################################
 # Commands.

+irqtab.o: irqtab.s
+
+bios16.o: bios16.s
+
+printreg.o: printreg.s
+
 entry.o: entry.s
        as86 -0 -u -o entry.o entry.s

diff -Nur elks.orig/arch/i86/mm/Makefile elks/arch/i86/mm/Makefile
--- elks.orig/arch/i86/mm/Makefile      2015-06-12 10:31:05.553638057 -0500
+++ elks/arch/i86/mm/Makefile   2015-06-12 10:59:04.413934880 -0500
@@ -40,6 +40,8 @@
 #########################################################################
 # Commands.

+segment.o: segment.s
+
 all:   mm.a

 mm.a: $(OBJS)

*****************************************************************************

 5. In file Makefile-rules, uncomment the line:

 #USEIA16   = y

Steps 3 and 4 also work to compile with BCC, but the renaming
of the files cannot be done with patches. Once steps 3 and 4 are
done, only step 5 is the difference to use one or another compiler.

Using ia16-unknown-elks-gcc with flag -Os resulted in savings
in code size of 3056 bytes, compared to BCC.
The produced kernel boots but fails to recognize the disk.
Probably this is because the compilers have different calling
conventions.

Juan
diff -Nur elks.orig/arch/i86/lib/divmodsi3.s elks/arch/i86/lib/divmodsi3.s
--- elks.orig/arch/i86/lib/divmodsi3.s	1969-12-31 18:00:00.000000000 -0600
+++ elks/arch/i86/lib/divmodsi3.s	2015-06-11 15:21:41.000000000 -0500
@@ -0,0 +1,90 @@
+
+	.text
+	.extern	ldivmod
+	.extern	ludivmod
+
+	.globl	___divsi3
+	.even
+
+___divsi3:
+	push	bp
+	mov	bp,sp
+	push	bx
+	push	cx
+	push	di
+	mov	ax,4[bp]
+	mov	bx,6[bp]
+	mov	cx,8[bp]
+	mov	di,10[bp]
+	call	ldivmod
+	mov	dx,di
+	mov	ax,cx
+	pop	di
+	pop	cx
+	pop	bx
+	pop	bp
+	ret
+
+	.globl	___modsi3
+	.even
+
+___modsi3:
+	push	bp
+	mov	bp,sp
+	push	bx
+	push	cx
+	push	di
+	mov	ax,4[bp]
+	mov	bx,6[bp]
+	mov	cx,8[bp]
+	mov	di,10[bp]
+	call	ldivmod
+	mov	dx,bx
+	pop	di
+	pop	cx
+	pop	bx
+	pop	bp
+	ret
+
+	.globl	___udivsi3
+	.even
+
+___udivsi3:
+	push	bp
+	mov	bp,sp
+	push	bx
+	push	cx
+	push	di
+	mov	ax,4[bp]
+	mov	bx,6[bp]
+	mov	cx,8[bp]
+	mov	di,10[bp]
+	call	ludivmod
+	mov	dx,di
+	mov	ax,cx
+	pop	di
+	pop	cx
+	pop	bx
+	pop	bp
+	ret
+
+	.globl	___umodsi3
+	.even
+
+___umodsi3:
+	push	bp
+	mov	bp,sp
+	push	bx
+	push	cx
+	push	di
+	mov	ax,4[bp]
+	mov	bx,6[bp]
+	mov	cx,8[bp]
+	mov	di,10[bp]
+	call	ludivmod
+	mov	dx,bx
+	pop	di
+	pop	cx
+	pop	bx
+	pop	bp
+	ret
diff -Nur elks.orig/arch/i86/lib/Makefile elks/arch/i86/lib/Makefile
--- elks.orig/arch/i86/lib/Makefile	2015-04-26 11:39:15.000000000 -0500
+++ elks/arch/i86/lib/Makefile	2015-06-11 15:13:23.000000000 -0500
@@ -29,7 +29,13 @@
 #########################################################################
 # Objects to be compiled.
 
+ifeq ($(USEIA16), y)
+OBJS		=peekb.o peekw.o pokew.o bitops.o \
+		 memmove.o string.o fmemset.o border.o setupw.o \
+		 ldivmod.o divmodsi3.o
+else
 OBJS		= $(IOBJS) $(JOBJS) $(LLOBJS) $(LXOBJS)
+endif
 
 # compiler support for integer arithmetic
 
@@ -39,14 +45,14 @@
 
 JOBJS		=inport.o inportb.o outport.o outportb.o \
 		 peekb.o peekw.o pokew.o bitops.o \
-		 memmove.o string.o fmemset.o border.o
+		 memmove.o string.o fmemset.o border.o setupw.o
 #		 ntohl.o ntohs.o
 
 # compiler support for long arithmetic on little-endian (normal) longs
 
 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
+		 lsll.o lsrl.o lsrul.o lsubl.o ltstl.o
 
 # compiler support for long arithmetic on all longs
 
diff -Nur elks.orig/arch/i86/Makefile elks/arch/i86/Makefile
--- elks.orig/arch/i86/Makefile	2015-04-26 11:39:15.000000000 -0500
+++ elks/arch/i86/Makefile	2015-06-09 15:25:22.000000000 -0500
@@ -85,10 +85,23 @@
 toolkit:
 	${MAKE} -C tools all
 
+ifeq ($(USEIA16), y)
 $(BASEDIR)/include/arch/asm-offsets.h: kernel/asm-offsets.c
+	echo '#ifndef ASM_OFFSETS_H' > $(BASEDIR)/include/arch/asm-offsets.h
+	echo '#define ASM_OFFSETS_H' >> $(BASEDIR)/include/arch/asm-offsets.h
 	$(CC) $(CFLAGS) -S -o asm-offsets.s kernel/asm-offsets.c
+	sed -e '/^\tm/ !d' \
+	-e "s/\(.*\t\\$$\)/\#define /" \
+	-e "s/\([0-9][0-9]*\),\t_\([a-zA-Z][_0-9a-zA-Z]*\)/\2 \1/" \
+	< asm-offsets.s >> $(BASEDIR)/include/arch/asm-offsets.h
+	echo '#endif' >> $(BASEDIR)/include/arch/asm-offsets.h
+	rm asm-offsets.s
+
+else
+$(BASEDIR)/include/arch/asm-offsets.h: kernel/asm-offsets.c
 	echo '#ifndef ASM_OFFSETS_H' > $(BASEDIR)/include/arch/asm-offsets.h
 	echo '#define ASM_OFFSETS_H' >> $(BASEDIR)/include/arch/asm-offsets.h
+	$(CC) $(CFLAGS) -S -o asm-offsets.s kernel/asm-offsets.c
 	sed -e '/^[^m].*/ d' \
 	-e 's/\],/  /' \
 	-e 's/ #/ /' \
@@ -100,6 +113,8 @@
 	echo '#endif' >> $(BASEDIR)/include/arch/asm-offsets.h
 	rm asm-offsets.s
 
+endif
+
 #########################################################################
 # Image selection.
 
diff -Nur elks.orig/arch/i86/mm/Makefile elks/arch/i86/mm/Makefile
--- elks.orig/arch/i86/mm/Makefile	2015-06-11 13:27:31.000000000 -0500
+++ elks/arch/i86/mm/Makefile	2015-06-10 18:49:05.000000000 -0500
@@ -35,7 +35,7 @@
 #########################################################################
 # Objects to be compiled.
 
-OBJS  = init.o malloc.o user.o
+OBJS  = init.o malloc.o user.o segment.o
 
 #########################################################################
 # Commands.
diff -Nur elks.orig/arch/i86/mm/segment.c elks/arch/i86/mm/segment.c
--- elks.orig/arch/i86/mm/segment.c	2015-06-11 13:27:16.000000000 -0500
+++ elks/arch/i86/mm/segment.c	2015-06-10 17:24:19.000000000 -0500
@@ -0,0 +1,123 @@
+/*
+ *	Assembly user access routines for the kernel.
+ */
+ 
+#include <arch/asm-offsets.h>
+
+#ifndef S_SPLINT_S
+#asm
+
+    .text
+
+/* void memcpy_fromfs(void *daddr, void *saddr, size_t len);*/
+    .globl  _memcpy_fromfs
+
+_memcpy_fromfs:
+
+    push    bp
+    mov	    bp,sp
+    mov	    bx,_current
+    mov	    dx,es
+    mov	    ax,ds
+    mov	    es,ax
+    mov	    ds,TASK_USER_DS[bx]
+    mov	    ax,di
+    mov	    di,4[bp]
+    mov	    bx,si
+    mov	    si,6[bp]
+    mov	    cx,8[bp]
+    cld
+    rep
+    movsb
+    mov	    si,bx
+    mov	    di,ax
+    mov	    ax,es
+    mov	    ds,ax
+    mov	    es,dx
+    pop	    bp
+    ret
+
+/* void memcpy_tofs(void *daddr, void *saddr, size_t len);*/
+    .globl  _memcpy_tofs
+
+_memcpy_tofs:
+
+    push    bp
+    mov	    bp,sp
+    mov	    bx,_current
+    mov	    dx,es
+    mov	    es,TASK_USER_DS[bx]
+    mov	    ax,di
+    mov	    di,4[bp]
+    mov	    bx,si
+    mov	    si,6[bp]
+    mov	    cx,8[bp]
+    cld
+    rep
+    movsb
+    mov	    si,bx
+    mov	    di,ax
+    mov	    es,dx
+    pop	    bp
+    ret
+
+/* void fmemcpy(dseg, dest, sseg, src, size); */
+    .globl  _fmemcpy
+
+_fmemcpy:
+
+    push    bp
+    mov	    bp,sp
+    push    ds
+    mov	    dx,es
+    mov	    es,4[bp]
+    mov	    ax,di
+    lds	    di,6[bp]
+    mov	    bx,si
+    mov	    si,10[bp]
+    mov	    cx,12[bp]
+    cld
+    rep
+    movsb
+    mov	    si,bx
+    mov	    di,ax
+    mov	    es,dx
+    pop	    ds
+    pop	    bp
+    ret
+
+/* int strlen_fromfs(void *saddr); */
+
+    /*  scasb uses es:di, not ds:si, so it is not necessary
+     *  to save and restore ds
+     */
+    .globl  _strlen_fromfs
+
+_strlen_fromfs:
+
+    push    bp
+    mov	    bp,sp
+    mov	    bx,_current
+    mov	    dx,es
+    mov	    es,TASK_USER_DS[bx]	! source segment
+    mov	    bx,di
+    mov	    di,4[bp]		! source address
+    xor	    al,al		! search for NULL byte
+    cld
+    mov	    cx,#-1
+    repne
+    scasb
+    sub	    di,4[bp]		! calc len +1
+    dec	    di
+    mov	    ax,di		! save in local var ds
+    mov	    di,bx
+    mov	    es,dx
+    pop	    bp
+    ret
+
+    .data
+    .extern _current
+
+#endasm
+#endif
+
diff -Nur elks.orig/arch/i86/mm/user.c elks/arch/i86/mm/user.c
--- elks.orig/arch/i86/mm/user.c	2015-06-11 13:27:16.000000000 -0500
+++ elks/arch/i86/mm/user.c	2015-06-09 17:22:19.000000000 -0500
@@ -4,9 +4,9 @@
  
 #include <linuxmt/types.h>
 #include <linuxmt/sched.h>
-#include <arch/segment.h>
 #include <linuxmt/mm.h>
 #include <linuxmt/errno.h>
+#include <arch/segment.h>
 
 int verfy_area(void *p, size_t len)
 {
@@ -27,33 +27,6 @@
     return 0;
 }
 
-void memcpy_fromfs(void *daddr, void *saddr, size_t len)
-{
-    /*@unused@*/ unsigned short int ds = current->t_regs.ds;
-
-#ifndef S_SPLINT_S
-#asm
-	push	si
-	push	di
-	mov	dx,es
-	mov	bx,ds
-	mov	es,bx
-	mov	di,[bp+.memcpy_fromfs.daddr]	! destination address
-	mov	ds,[bp+.memcpy_fromfs.ds]	! source segment (local variable)
-	mov	si,[bp+.memcpy_fromfs.saddr]	! source address
-	mov	cx,[bp+.memcpy_fromfs.len]	! number of bytes to copy
-	cld
-	rep
-	movsb
-	mov	ds,bx
-	mov	es,dx
-	pop	di
-	pop	si
-#endasm
-#endif
-
-}
-
 int verified_memcpy_fromfs(void *daddr, void *saddr, size_t len)
 {
     int err = verify_area(VERIFY_READ, saddr, len);
@@ -66,29 +39,6 @@
     return 0;
 }
 
-void memcpy_tofs(void *daddr, void *saddr, size_t len)
-{
-    /*@unused@*/ unsigned short int es = current->t_regs.ds;
-
-#ifndef S_SPLINT_S
-#asm
-	push	si
-	push	di
-	mov	dx,es
-	mov	es,[bp+.memcpy_tofs.es]	! destination segment (local variable)
-	mov	di,[bp+.memcpy_tofs.daddr]	! destination address
-	mov	si,[bp+.memcpy_tofs.saddr]	! source address
-	mov	cx,[bp+.memcpy_tofs.len]	! number of bytes to copy
-	cld
-	rep
-	movsb
-	mov	es,dx
-	pop	di
-	pop	si
-#endasm
-#endif
-}
-
 int verified_memcpy_tofs(void *daddr, void *saddr, size_t len)
 {
     int err = verify_area(VERIFY_WRITE, daddr, len);
@@ -101,38 +51,6 @@
     return 0;
 }
 
-/* fmemcpy(dseg, dest, sseg, src, size); */
-
-#ifndef S_SPLINT_S
-#asm	
-
-	.globl	_fmemcpy
-
-_fmemcpy:
-	push	bp
-	mov	bp, sp
-	push	di
-	push	si
-	push	ds
-	push	es
-	pushf
-	mov	es, 4[bp]
-	lds     di, 6[bp]	
-	mov	si, 10[bp]
-	mov	cx, 12[bp]
-	cld			! Must move upwards...
-	rep
-	movsb
-	popf
-	pop	es
-	pop	ds
-	pop	si
-	pop	di
-	pop	bp
-	ret
-#endasm
-#endif
-
 #if 0
 
 int fstrlen(unsigned short int dseg, unsigned short int doff)
@@ -147,40 +65,6 @@
 
 #endif
 
-#if 1
-
-int strlen_fromfs(void *saddr)
-{
-    int ds = (int) current->t_regs.ds;
-
-    /*  scasb uses es:di, not ds:si, so it is not necessary
-     *  to save and restore ds
-     */
-
-#ifndef S_SPLINT_S
-#asm
-
-	push	di
-	mov	dx,es
-	mov	es,[bp+.strlen_fromfs.ds]	! source segment (local variable)
-	mov	di,[bp+.strlen_fromfs.saddr]	! source address
-	cld
-	xor	al,al		! search for NULL byte
-	mov	cx,#-1
-	repne
-	scasb
-	sub	di,[bp+.strlen_fromfs.saddr]	! calc len +1
-	dec	di
-	mov	[bp+.strlen_fromfs.ds],di	! save in local var ds
-	mov	es,dx
-	pop	di
-#endasm
-#endif
-
-    return ds;
-}
-#endif
-
 unsigned long int get_user_long(void *dv)
 {
     unsigned long retv;
diff -Nur elks.orig/Makefile-rules elks/Makefile-rules
--- elks.orig/Makefile-rules	2015-04-26 11:39:15.000000000 -0500
+++ elks/Makefile-rules	2015-06-10 18:25:27.000000000 -0500
@@ -57,6 +57,8 @@
 
 ARCH		= i86
 
+#USEIA16  	= y
+
 #########################################################################
 # ROOT_DEV specifies the default root-device when making the image.
 # This does not yet work under ELKS. See include/linuxmt/config.h to
@@ -177,33 +179,63 @@
 # Define CPU-specific flags.
 
 ifeq ($(MK_CPU), 8086)
+ifeq ($(USEIA16), y)
+    CPU_AS	= -0
+    CPU_CC	= -mtune=i8086 -fno-inline -fdata-sections -ffunction-sections -mseparate-code-segment -Wl,--gc-sections
+    CPU_LD	= -0
+else
     CPU_AS	= -0
     CPU_CC	= -0
     CPU_LD	= -0
 endif
+endif
 
 ifeq ($(MK_CPU), 80186)
+ifeq ($(USEIA16), y)
+    CPU_AS	= -1
+    CPU_CC	= -mtune=i80186 -fno-inline -fdata-sections -ffunction-sections -mseparate-code-segment -Wl,--gc-sections
+    CPU_LD	= -0
+else
     CPU_AS	= -1
     CPU_CC	= -0
     CPU_LD	= -0
 endif
+endif
 
 ifeq ($(MK_CPU), 80286)
+ifeq ($(USEIA16), y)
+    CPU_AS	= -2
+    CPU_CC	= -mtune=i80286 -fno-inline -fdata-sections -ffunction-sections -mseparate-code-segment -Wl,--gc-sections
+    CPU_LD	= -0
+else
     CPU_AS	= -2
     CPU_CC	= -0
     CPU_LD	= -0
 endif
+endif
 
 ifeq ($(MK_CPU), 80386)
+ifeq ($(USEIA16), y)
+    CPU_AS	= -3
+    CPU_CC	= -3
+    CPU_LD	= -3
+else
     CPU_AS	= -3
     CPU_CC	= -3
     CPU_LD	= -3
 endif
+endif
 
 ifeq ($(MK_CPU), 80486)
+ifeq ($(USEIA16), y)
     CPU_AS	= -3
     CPU_CC	= -3
     CPU_LD	= -3
+else
+    CPU_AS	= -3
+    CPU_CC	= -3
+    CPU_LD	= -3
+endif
 endif
 
 #########################################################################
@@ -219,8 +251,8 @@
 
 AR		= ar
 CC_PROTO	= gcc -I$(INCDIR) -M -MG $(CCDEFS)
-CFLBASE 	= -O -I$(INCDIR) $(CCDEFS) -ansi
-CPP		= $(CC) -I$(INCDIR) -E $(CCDEFS)
+CFLBASE 	= -I$(INCDIR) $(CCDEFS)
+CPP		= $(CC) -I$(INCDIR) -E $(CCDEFS) -ansi
 LINT		= splint
 LINTLEVEL	= -weak
 LCFLAGS 	= -I$(INCDIR) $(CCDEFS)
@@ -230,16 +262,30 @@
 
 ifneq ($(USEBCC), N)
 
+ifeq ($(USEIA16), y)
+################################
+# Definitions using ia16-unknown-elks-gcc compiler
+
+AS		= as86
+ASFLAGS 	= $(CPU_AS) $(ARCH_AS)
+CC		= ia16-unknown-elks-gcc
+CFLAGS		= $(CPU_CC) $(ARCH_CC) -Os $(CFLBASE) -Wall
+LD		= ld86
+LDFLAGS 	= $(CPU_LD) -s
+
+else
 ################################
 # Definitions using BCC compiler
 
 AS		= as86
 ASFLAGS 	= $(CPU_AS) $(ARCH_AS)
 CC		= bcc
-CFLAGS		= $(CPU_CC) $(ARCH_CC) $(CFLBASE)
+CFLAGS		= $(CPU_CC) $(ARCH_CC) -O $(CFLBASE) -ansi
 LD		= ld86
 LDFLAGS 	= $(CPU_LD) -s
 
+endif
+
 else
 
 ################################
@@ -248,7 +294,7 @@
 AS		= as
 ASFLAGS 	= 
 CC		= gcc
-CFLAGS		= -i $(CFLBASE)
+CFLAGS		= -i -O $(CFLBASE) -ansi
 LD		= ld
 LDFLAGS 	= -s -x
 
@@ -266,9 +312,19 @@
 .S.s:
 	gcc -E -traditional -I$(INCDIR) $(CCDEFS) -o $*.s $<
 
+ifeq ($(USEIA16), y)
+.c.o:
+	$(CC) $(CFLAGS) -S -o $*.s $<
+	att2as86 < $*.s > $*.asm
+	$(AS) $(ASFLAGS) -u -o $*.o $*.asm
+	rm $*.s $*.asm
+
+else
 .c.o:
 	$(CC) $(CFLAGS) -c -o $*.o $<
 
+endif
+
 #########################################################################
 # Default target, to allow standard targets to be included. This simply
 # allows `make elks` to be called from any directory in the tree, and

[Index of Archives]     [Kernel]     [Linux ia64]     [DCCP]     [Linux for ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux