setup.S: fix for BIOS/DOS not reporting ext mem size
PATCH 1/1 setup.S: fix for BIOS/DOS not reporting ext mem size
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
setup.S renamed from setup.S.orig +57 -21
@@ -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 <[email protected]> * + * 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? + * <[email protected]> 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
Call kernel function from module
Quoted 115 lines · vda
Linus, Alan,
This patch to i386
setup.Sresulted 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.Srather 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. --
vdadiff -ubB setup.S.orig
setup.Ssetup.S Wed Oct 31 12:21:45 2001 renamed from setup.S.orig Mon Sep 24 00:58:58 2001 +22
-21@@ -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 <[email protected]> * + * 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? + * <[email protected]> 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
setup.S Wed Oct 31 12:21:45 2001 line 384
Quoted 10 lines
setup.S Wed Oct 31 12:21:45 2001 renamed from setup.S.orig Mon Sep 24 00:58:58 2001 +4
-0# 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.
Re: Call kernel function from module
In reply to vda[snip]
Quoted 7 lines
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 innetsyms.cfile. Do you know how I can see my function?
use EXPORT_SYMBOL macro from include/module.h
Quoted 8 lines
Regards,
Niktar.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
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
[email protected] Fax: +972-4-9890564
Optical Access
Senior Software Engineer www.opticalaccess.com
Re: Call kernel function from module
In reply to vdaQuoted 11 lines · Michael Rozhavsky
[snip]
Quoted 7 lines
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 innetsyms.cfile. Do you know how I can see my function?use
EXPORT_SYMBOLmacro frominclude/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
Quoted 16 lines
Quoted 9 lines
Regards,
Niktar.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
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 [email protected] Fax: +972-4-9890564Optical Access
Senior Software Engineer www.opticalaccess.com