public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] setup.S: fix for BIOS/DOS not reporting ext mem size
@ 2001-10-18 10:56 vda
  0 siblings, 0 replies; 5+ messages in thread
From: vda @ 2001-10-18 10:56 UTC (permalink / raw)
  To: linux-kernel

Linus, Alan,

This patch to i386 setup.S resulted from my attempts to load big
bzImages from DOS. Loadlin fails at aroung 1020000 bytes, I didn't
want to mess with that much asm in loadlin src and wrote new
loader from scratch mostly in c.

I had a problem booting from DOS on pc with 196 mb or ram. It turned
out int15/e801 and int15/88 reported zero ext mem -> "Less than 4MB"
type hang. Digging in loadlin sources turned out some horrors
(loadlin hooks itself on int 15/88 and reads CMOS)

I think it's cleaner to do this in setup.S rather than jump thru the
hoops in DOS loader. Attached patch does that *only if* int15 methods
fail. It does not break existing practice, only adds just another
fallback in case of brain damage.

I couldn't resist and fixed some typos, cleaned up some label names
and replaced some instructions with shorter code :-)

Tested on three boxes. Works for me. :-)
-- 
Best regards, vda
mailto:vda@port.imtp.ilyichevsk.odessa.ua

diff -ubB --expand-tabs setup.S.orig setup.S
--- setup.S.orig        Mon Sep 24 00:58:58 2001
+++ setup.S     Thu Oct 18 11:36:24 2001
@@ -39,9 +39,13 @@
  * from Ralf Brown interrupt list seem to indicate AX/BX should be used
  * anyway.  So to avoid breaking many machines (presumably there was a reason
  * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
+ * if CX/DX have been changed in the e801 call and if so use AX/BX.
  * Michael Miller, April 2001 <michaelm@mjmm.org>
  *
+ * Even more fixes for memory detection when started from DOS
+ * TODO: maybe we can just resort to memory scan on our own
+ * to stop using int15/e820,int15/e801,int15/88,cmos once and for all?
+ * <vda@port.imtp.ilyichevsk.odessa.ua> october 2001
  */
 
 #include <linux/config.h>
@@ -297,13 +301,13 @@
 
 #define SMAP  0x534d4150
 
-meme820:
+mem_e820:
         xorl    %ebx, %ebx                      # continuation counter
         movw    $E820MAP, %di                   # point into the whitelist
                                                 # so we can have the bios
                                                 # directly write into it.
 
-jmpe820:
+jmp820:
         movl    $0x0000e820, %eax               # e820, upper word zeroed
         movl    $SMAP, %edx                     # ascii 'SMAP'
         movl    $20, %ecx                       # size of the e820rec
@@ -327,12 +331,10 @@
         jnl     bail820
 
         incb    (E820NR)
-        movw    %di, %ax
-        addw    $20, %ax
-        movw    %ax, %di
+        addw    $20, %di
 again820:
-        cmpl    $0, %ebx                        # check to see if
-        jne     jmpe820                         # %ebx is set to EOF
+        testl   %ebx, %ebx                      # check to see if
+        jnz     jmp820                          # %ebx is set to EOF
 bail820:
 
 
@@ -344,10 +346,10 @@
 # alternative new memory detection scheme, and it's sensible
 # to write everything into the same place.)
 
-meme801:
+mem_e801:
         stc                                     # fix to work around buggy
-        xorw    %cx,%cx                         # BIOSes which dont clear/set
-        xorw    %dx,%dx                         # carry on pass/error of
+        xorw    %cx, %cx                        # BIOSes which dont clear/set
+        xorw    %dx, %dx                        # carry on pass/error of
                                                 # e801h memory size call
                                                 # or merely pass cx,dx though
                                                 # without changing them.
@@ -355,28 +357,62 @@
         int     $0x15
         jc      mem88
 
-        cmpw    $0x0, %cx                       # Kludge to handle BIOSes
-        jne     e801usecxdx                     # which report their extended
-        cmpw    $0x0, %dx                       # memory in AX/BX rather than
-        jne     e801usecxdx                     # CX/DX.  The spec I have read
+        testw   %cx, %cx                        # Kludge to handle BIOSes
+        jnz     e801use_cxdx                    # which report their extended
+        testw   %dx, %dx                        # memory in AX/BX rather than
+        jnz     e801use_cxdx                    # CX/DX.  The spec I have read
         movw    %ax, %cx                        # seems to indicate AX/BX 
         movw    %bx, %dx                        # are more reasonable anyway...
 
-e801usecxdx:
-        andl    $0xffff, %edx                   # clear sign extend
+e801use_cxdx:
+        movzwl  %dx, %edx                       # clear sign extend
         shll    $6, %edx                        # and go from 64k to 1k chunks
-        movl    %edx, (0x1e0)                   # store extended memory size
-        andl    $0xffff, %ecx                   # clear sign extend
-        addl    %ecx, (0x1e0)                   # and add lower memory into
-                                                # total size.
+        movzwl  %cx, %ecx                       # clear sign extend
+        addl    %ecx, %edx                      # add lower memory to
+        movl    %edx, (0x1e0)                   # extended, store
 
 # Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
 # 64mb, depending on the bios) in ax.
 mem88:
 
 #endif
+        #stc                    # guard against brain damage -
+                                #   int 15 must clear cf to indicate success
+        clc                     # unbelievable: some BIOSes/DOSes can leave
+                                #   cf as is so I had to abandon stc trick
         movb    $0x88, %ah
         int     $0x15
+        jc      mem_cmos
+        testw   %ax, %ax
+        jnz     mem_store
+
+# Fallback: if int15/88 fails, get same data from CMOS
+# this works around extremely stupid case I had with PC not booting
+# from DOS when I put 196 megs of RAM in it 
+# (it reported 0 via int15/e801 and int15/88)
+# Also this makes unnecessary for loadlin to jump thru the hoops
+# just in order to let us know ext mem size
+# (it hooks itself on int 15/88 and does CMOS reads for us)
+mem_cmos:
+        pushf                   
+        cli                     
+        movb    $0x18, %al      
+        outb    %al, $0x70      
+        #iodelay?               
+        inb     $0x71, %al
+        movb    %al, %ah
+        #iodelay?
+        movb    $0x17, %al
+        outb    %al, $0x70
+        #iodelay?
+        inb     $0x71, %al
+        popf
+        
+mem_store:
+        cmpw    $0xffff-0x400, %ax      # We want to be sure it won't roll over
+        jbe     mem_store2              # 16 bit value when low 1024k gets added
+        movw    $0xffff-0x400, %ax      # thus max memtop is 0xffff*1k = 64m-1k
+mem_store2:
         movw    %ax, (2)
 
 # Set the keyboard repeat rate to the max



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Call kernel function from module
  2001-10-31 12:31 [PATCH] setup.S: fix for BIOS/DOS not reporting ext mem size vda
@ 2001-10-31 10:54 ` Kirill Ratkin
  2001-10-31 11:34   ` Michael Rozhavsky
  0 siblings, 1 reply; 5+ messages in thread
From: Kirill Ratkin @ 2001-10-31 10:54 UTC (permalink / raw)
  Cc: linux-kernel

vda wrote:
> 
> Linus, Alan,
> 
> This patch to i386 setup.S resulted from my attempts to load big
> bzImages from DOS. Loadlin fails at aroung 1020000 bytes, I didn't
> want to mess with that much asm in loadlin src and wrote new
> loader from scratch mostly in c.
> 
> I had a problem booting from DOS on pc with 196 mb or ram. It turned
> out int15/e801 and int15/88 reported zero ext mem -> "Less than 4MB"
> type hang. Digging in loadlin sources turned out some horrors
> (loadlin hooks itself on int 15/88 and reads CMOS)
> 
> I think it's cleaner to do this in setup.S rather than jump thru the
> hoops in DOS loader. Attached patch does that *only if* int15 methods
> fail. It does not break existing practice, only adds just another
> fallback in case of brain damage.
> 
> Tested on three boxes. Works for me. Applies cleanly to 2.4.13.
> If something is wrong with this patch, let me know about it.
> --
> vda
> 
> diff -ubB setup.S.orig setup.S
> --- setup.S.orig        Mon Sep 24 00:58:58 2001
> +++ setup.S     Wed Oct 31 12:21:45 2001
> @@ -39,9 +39,13 @@
>   * from Ralf Brown interrupt list seem to indicate AX/BX should be used
>   * anyway.  So to avoid breaking many machines (presumably there was a reason
>   * to orginally use CX/DX instead of AX/BX), we do a kludge to see
> - * if CX/DX have been changed in the e801 call and if so use AX/BX .
> + * if CX/DX have been changed in the e801 call and if so use AX/BX.
>   * Michael Miller, April 2001 <michaelm@mjmm.org>
>   *
> + * Even more fixes for memory detection when started from DOS
> + * TODO: maybe we can just resort to memory scan on our own
> + * to stop using int15/e820,int15/e801,int15/88,cmos once and for all?
> + * <vda@port.imtp.ilyichevsk.odessa.ua> october 2001
>   */
> 
>  #include <linux/config.h>
> @@ -297,13 +301,13 @@
> 
>  #define SMAP  0x534d4150
> 
> -meme820:
> +mem_e820:
>         xorl    %ebx, %ebx                      # continuation counter
>         movw    $E820MAP, %di                   # point into the whitelist
>                                                 # so we can have the bios
>                                                 # directly write into it.
> 
> -jmpe820:
> +jmp820:
>         movl    $0x0000e820, %eax               # e820, upper word zeroed
>         movl    $SMAP, %edx                     # ascii 'SMAP'
>         movl    $20, %ecx                       # size of the e820rec
> @@ -327,12 +331,10 @@
>         jnl     bail820
> 
>         incb    (E820NR)
> -       movw    %di, %ax
> -       addw    $20, %ax
> -       movw    %ax, %di
> +       addw    $20, %di
>  again820:
> -       cmpl    $0, %ebx                        # check to see if
> -       jne     jmpe820                         # %ebx is set to EOF
> +       testl   %ebx, %ebx                      # check to see if
> +       jnz     jmp820                          # %ebx is set to EOF
>  bail820:
> 
> @@ -344,10 +346,10 @@
>  # alternative new memory detection scheme, and it's sensible
>  # to write everything into the same place.)
> 
> -meme801:
> +mem_e801:
>         stc                                     # fix to work around buggy
> -       xorw    %cx,%cx                         # BIOSes which dont clear/set
> -       xorw    %dx,%dx                         # carry on pass/error of
> +       xorw    %cx, %cx                        # BIOSes which dont clear/set
> +       xorw    %dx, %dx                        # carry on pass/error of
>                                                 # e801h memory size call
>                                                 # or merely pass cx,dx though
>                                                 # without changing them.
> @@ -355,28 +357,62 @@
>         int     $0x15
>         jc      mem88
> 
> -       cmpw    $0x0, %cx                       # Kludge to handle BIOSes
> -       jne     e801usecxdx                     # which report their extended
> -       cmpw    $0x0, %dx                       # memory in AX/BX rather than
> -       jne     e801usecxdx                     # CX/DX.  The spec I have read
> +       testw   %cx, %cx                        # Kludge to handle BIOSes
> +       jnz     e801use_cxdx                    # which report their extended
> +       testw   %dx, %dx                        # memory in AX/BX rather than
> +       jnz     e801use_cxdx                    # CX/DX.  The spec I have read
>         movw    %ax, %cx                        # seems to indicate AX/BX
>         movw    %bx, %dx                        # are more reasonable anyway...
> 
> -e801usecxdx:
> -       andl    $0xffff, %edx                   # clear sign extend
> +e801use_cxdx:
> +       movzwl  %dx, %edx                       # clear sign extend
>         shll    $6, %edx                        # and go from 64k to 1k chunks
> -       movl    %edx, (0x1e0)                   # store extended memory size
> -       andl    $0xffff, %ecx                   # clear sign extend
> -       addl    %ecx, (0x1e0)                   # and add lower memory into
> -                                               # total size.
> +       movzwl  %cx, %ecx                       # clear sign extend
> +       addl    %ecx, %edx                      # add lower memory to
> +       movl    %edx, (0x1e0)                   # extended, store
> 
>  # Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
>  # 64mb, depending on the bios) in ax.
>  mem88:
> 
>  #endif
> +       #stc                    # guard against brain damage -
> +                               #   int 15 must clear cf to indicate success
> +       clc                     # unbelievable: some BIOSes/DOSes can leave
> +                               #   cf as is so I had to abandon stc trick
>         movb    $0x88, %ah
>         int     $0x15

Hi! Could somebody help me? I added several functions (not sys calls) to
kernel as hardcoded part. Then I write modules which will be call these
functions. But when I load module insmod says me 'can't resolve symbol
my_func_name'.
I exported all my functions in netsyms.c file. Do you know how I can see
my function?

Regards,
Niktar.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Call kernel function from module
  2001-10-31 10:54 ` Call kernel function from module Kirill Ratkin
@ 2001-10-31 11:34   ` Michael Rozhavsky
  2001-10-31 11:46     ` Kirill Ratkin
  0 siblings, 1 reply; 5+ messages in thread
From: Michael Rozhavsky @ 2001-10-31 11:34 UTC (permalink / raw)
  To: Kirill Ratkin; +Cc: linux-kernel

[snip]
> 
> Hi! Could somebody help me? I added several functions (not sys calls) to
> kernel as hardcoded part. Then I write modules which will be call these
> functions. But when I load module insmod says me 'can't resolve symbol
> my_func_name'.
> I exported all my functions in netsyms.c file. Do you know how I can see
> my function?

use EXPORT_SYMBOL macro from include/module.h

> 
> Regards,
> Niktar.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
Best regards.

--
   Michael Rozhavsky			Tel:    +972-4-9936248
   mrozhavsky@opticalaccess.com		Fax:    +972-4-9890564
   Optical Access  
   Senior Software Engineer		www.opticalaccess.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Call kernel function from module
  2001-10-31 11:34   ` Michael Rozhavsky
@ 2001-10-31 11:46     ` Kirill Ratkin
  0 siblings, 0 replies; 5+ messages in thread
From: Kirill Ratkin @ 2001-10-31 11:46 UTC (permalink / raw)
  To: Michael Rozhavsky; +Cc: linux-kernel


Michael Rozhavsky wrote:
> 
> [snip]
> >
> > Hi! Could somebody help me? I added several functions (not sys calls) to
> > kernel as hardcoded part. Then I write modules which will be call these
> > functions. But when I load module insmod says me 'can't resolve symbol
> > my_func_name'.
> > I exported all my functions in netsyms.c file. Do you know how I can see
> > my function?
> 
> use EXPORT_SYMBOL macro from include/module.h
Yes. I added it in netsyms.c and I see all my functions in System.map
file. (into ksyms too)

#ifdef CONFIG_BATON
#include <linux/baton.h>
EXPORT_SYMBOL(baton_init);
EXPORT_SYMBOL(baton_register_hook);
EXPORT_SYMBOL(baton_unregister_hook);
#endif

> 
> >
> > Regards,
> > Niktar.
> > -
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> Best regards.
> 
> --
>    Michael Rozhavsky                    Tel:    +972-4-9936248
>    mrozhavsky@opticalaccess.com         Fax:    +972-4-9890564
>    Optical Access
>    Senior Software Engineer             www.opticalaccess.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] setup.S: fix for BIOS/DOS not reporting ext mem size
@ 2001-10-31 12:31 vda
  2001-10-31 10:54 ` Call kernel function from module Kirill Ratkin
  0 siblings, 1 reply; 5+ messages in thread
From: vda @ 2001-10-31 12:31 UTC (permalink / raw)
  To: Alan Cox, Linus Torvalds; +Cc: linux-kernel

Linus, Alan,

This patch to i386 setup.S resulted from my attempts to load big
bzImages from DOS. Loadlin fails at aroung 1020000 bytes, I didn't
want to mess with that much asm in loadlin src and wrote new
loader from scratch mostly in c.

I had a problem booting from DOS on pc with 196 mb or ram. It turned
out int15/e801 and int15/88 reported zero ext mem -> "Less than 4MB"
type hang. Digging in loadlin sources turned out some horrors
(loadlin hooks itself on int 15/88 and reads CMOS)

I think it's cleaner to do this in setup.S rather than jump thru the
hoops in DOS loader. Attached patch does that *only if* int15 methods
fail. It does not break existing practice, only adds just another
fallback in case of brain damage.

Tested on three boxes. Works for me. Applies cleanly to 2.4.13.
If something is wrong with this patch, let me know about it.
--
vda


diff -ubB setup.S.orig setup.S
--- setup.S.orig	Mon Sep 24 00:58:58 2001
+++ setup.S	Wed Oct 31 12:21:45 2001
@@ -39,9 +39,13 @@
  * from Ralf Brown interrupt list seem to indicate AX/BX should be used
  * anyway.  So to avoid breaking many machines (presumably there was a reason
  * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
+ * if CX/DX have been changed in the e801 call and if so use AX/BX.
  * Michael Miller, April 2001 <michaelm@mjmm.org>
  *
+ * Even more fixes for memory detection when started from DOS
+ * TODO: maybe we can just resort to memory scan on our own
+ * to stop using int15/e820,int15/e801,int15/88,cmos once and for all?
+ * <vda@port.imtp.ilyichevsk.odessa.ua> october 2001
  */

 #include <linux/config.h>
@@ -297,13 +301,13 @@

 #define SMAP  0x534d4150

-meme820:
+mem_e820:
 	xorl	%ebx, %ebx			# continuation counter
 	movw	$E820MAP, %di			# point into the whitelist
 						# so we can have the bios
 						# directly write into it.

-jmpe820:
+jmp820:
 	movl	$0x0000e820, %eax		# e820, upper word zeroed
 	movl	$SMAP, %edx			# ascii 'SMAP'
 	movl	$20, %ecx			# size of the e820rec
@@ -327,12 +331,10 @@
 	jnl	bail820

 	incb	(E820NR)
-	movw	%di, %ax
-	addw	$20, %ax
-	movw	%ax, %di
+	addw	$20, %di
 again820:
-	cmpl	$0, %ebx			# check to see if
-	jne	jmpe820				# %ebx is set to EOF
+	testl	%ebx, %ebx			# check to see if
+	jnz	jmp820				# %ebx is set to EOF
 bail820:


@@ -344,10 +346,10 @@
 # alternative new memory detection scheme, and it's sensible
 # to write everything into the same place.)

-meme801:
+mem_e801:
 	stc					# fix to work around buggy
-	xorw	%cx,%cx				# BIOSes which dont clear/set
-	xorw	%dx,%dx				# carry on pass/error of
+	xorw	%cx, %cx			# BIOSes which dont clear/set
+	xorw	%dx, %dx			# carry on pass/error of
 						# e801h memory size call
 						# or merely pass cx,dx though
 						# without changing them.
@@ -355,28 +357,62 @@
 	int	$0x15
 	jc	mem88
 
-	cmpw	$0x0, %cx			# Kludge to handle BIOSes
-	jne	e801usecxdx			# which report their extended
-	cmpw	$0x0, %dx			# memory in AX/BX rather than
-	jne	e801usecxdx			# CX/DX.  The spec I have read
+	testw	%cx, %cx			# Kludge to handle BIOSes
+	jnz	e801use_cxdx			# which report their extended
+	testw	%dx, %dx			# memory in AX/BX rather than
+	jnz	e801use_cxdx			# CX/DX.  The spec I have read
 	movw	%ax, %cx			# seems to indicate AX/BX
 	movw	%bx, %dx			# are more reasonable anyway...

-e801usecxdx:
-	andl	$0xffff, %edx			# clear sign extend
+e801use_cxdx:
+	movzwl	%dx, %edx			# clear sign extend
 	shll	$6, %edx			# and go from 64k to 1k chunks
-	movl	%edx, (0x1e0)			# store extended memory size
-	andl	$0xffff, %ecx			# clear sign extend
- 	addl	%ecx, (0x1e0)			# and add lower memory into
-						# total size.
+	movzwl	%cx, %ecx			# clear sign extend
+	addl	%ecx, %edx			# add lower memory to
+	movl	%edx, (0x1e0)			# extended, store
 
 # Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
 # 64mb, depending on the bios) in ax.
 mem88:
 
 #endif
+	#stc			# guard against brain damage -
+				#   int 15 must clear cf to indicate success
+	clc			# unbelievable: some BIOSes/DOSes can leave
+				#   cf as is so I had to abandon stc trick
 	movb	$0x88, %ah
 	int	$0x15
+	jc	mem_cmos
+	testw	%ax, %ax
+	jnz	mem_store
+
+# Fallback: if int15/88 fails, get same data from CMOS
+# this works around extremely stupid case I had with PC not booting
+# from DOS when I put 196 megs of RAM in it 
+# (it reported 0 via int15/e801 and int15/88)
+# Also this makes unnecessary for loadlin to jump thru the hoops
+# just in order to let us know ext mem size
+# (it hooks itself on int 15/88 and does CMOS reads for us)
+mem_cmos:
+	pushf			
+	cli
+	movb	$0x18, %al	
+	outb	%al, $0x70
+	#iodelay?		
+	inb	$0x71, %al
+	movb	%al, %ah
+	#iodelay?
+	movb	$0x17, %al
+	outb	%al, $0x70
+	#iodelay?
+	inb	$0x71, %al
+	popf
+	
+mem_store:
+	cmpw	$0xffff-0x400, %ax	# We want to be sure it won't roll over
+	jbe	mem_store2		# 16 bit value when low 1024k gets added
+	movw	$0xffff-0x400, %ax	# thus max memtop is 0xffff*1k = 64m-1k
+mem_store2:
 	movw	%ax, (2)

 # Set the keyboard repeat rate to the max

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-10-31 11:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-10-31 12:31 [PATCH] setup.S: fix for BIOS/DOS not reporting ext mem size vda
2001-10-31 10:54 ` Call kernel function from module Kirill Ratkin
2001-10-31 11:34   ` Michael Rozhavsky
2001-10-31 11:46     ` Kirill Ratkin
  -- strict thread matches above, loose matches on Subject: below --
2001-10-18 10:56 [PATCH] setup.S: fix for BIOS/DOS not reporting ext mem size vda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox