[PATCH] A little wad of patches for 2.3.10

david parsons (o.r.c@p.e.l.l.p.o.r.t.l.a.n.d.o.r.u.s)
21 Jul 1999 23:53:46 -0700


I took the train to California this week, and to while away the time
on the train I took my mighty Thinkpad 701C and a 2.3.10 kernel with me.
I applied a bunch of patches to it to make it actually properly detect
memory and work better with Mastodon, and here they are, just out of the
nick of time (but since they don't touch that much, they may still apply
to 2.3.11; I just got back this afternoon, so 2.3.11 is downloading
even as I proofread.)

This pile of patches:

* Tweaks the top-level makefile so that make clean works on a Mastodon
system (use |grep instead of -regex to pick out files not to delete.)
* Tweaks Menuconfig so that it works on Berkeley AWK as well as GNU
awk.
* Tweaks the makefile for lxdialog so that it doesn't complain if it
can't manually find ncurses -- since the thinkpad only has the a.out
development libraries included, libncurses doesn't live where the
lxdialog expects to find it.
* Puts back old-style fcntl locking, so that old a.out gdbm libraries
won't explode and die.
* Puts in most of my fancy memory detection patches. Tom Leete and I
are beating on the memory detection patches to make memory-mapped
ISA video cards works, so the code I've got to manually set up
memory regions is waiting, in pieces, at the bottom of the codebox.

Needless to say, I'd be tickled pink if these patches made it into the
baseline kernel, so I don't have to carry them around anymore.

____
david parsons \bi/ It takes 5 hours to do ``make bzImage'' on a 486/75,
\/ but only about 20 seconds to have SVGATextMode eat
the vga frame buffer.

diff -Nur linux-2.3.10-orig/Makefile linux-2.3.10/Makefile
--- linux-2.3.10-orig/Makefile Thu Jul 1 10:54:31 1999
+++ linux-2.3.10/Makefile Mon Jul 19 17:14:20 1999
@@ -351,7 +351,7 @@

clean: archclean
rm -f kernel/ksyms.lst include/linux/compile.h
- rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print`
+ find . -name '*.[oas]' -print | grep -v lxdialog/ | xargs rm -f
rm -f core `find . -type f -name 'core' -print`
rm -f core `find . -name '.*.flags' -print`
rm -f vmlinux System.map
diff -Nur linux-2.3.10-orig/arch/i386/boot/setup.S linux-2.3.10/arch/i386/boot/setup.S
--- linux-2.3.10-orig/arch/i386/boot/setup.S Mon Jul 5 20:04:47 1999
+++ linux-2.3.10/arch/i386/boot/setup.S Mon Jul 19 17:10:15 1999
@@ -37,6 +37,7 @@
#include <linux/version.h>
#include <linux/compile.h>
#include <asm/boot.h>
+#include <asm/e820.h>

! Signature words to ensure LILO loaded us right
#define SIG1 0xAA55
@@ -59,7 +60,7 @@

entry start
start:
- jmp start_of_setup
+ jmp trampoline
! ------------------------ start of header --------------------------------
!
! SETUP-header, must start at CS:2 (old 0x9020:2)
@@ -119,6 +120,8 @@
heap_end_ptr: .word modelist+1024 ! space from here (exclusive) down to
! end of setup code can be used by setup
! for local heap purposes.
+trampoline: call start_of_setup
+ .space 1024
! ------------------------ end of header ----------------------------------

start_of_setup:
@@ -245,37 +248,100 @@
loader_ok:
! Get memory size (extended mem, kB)

+ xor eax, eax
+ mov dword ptr [0x1e0], eax
#ifndef STANDARD_MEMORY_BIOS_CALL
- push ebx

- xor ebx,ebx ! preload new memory slot with 0k
- mov [0x1e0], ebx
+ mov dword ptr [E820MEM], eax
+ mov dword ptr [E820NR], eax
+
+! Try three different memory detection schemes. First, try
+! e820h, which lets us assemble a memory map, then try e801h,
+! which returns a 32-bit memory size, and finally 88h, which
+! returns 0-64m
+
+! method E820H:
+! the memory map from hell. e820h returns memory classified into
+! a whole bunch of different types, and allows memory holes and
+! everything. We scan through this memory map and build a list
+! of the first 32 available memory areas, which we return at [0xC20].
+! We also make a stab at the memory size by the somewhat gross approach
+! of setting memsize to the address+size of the LAST available memory
+! we picked up. This assumes that e820 returns memory regions in strictly
+! increasing order; if a bios returns those memory regions in any other
+! order, we will be in for a world of pain.
+!
+
+meme820:
+ mov edx, #0x534d4150 ! ascii `SMAP'
+ xor ebx, ebx ! continuation counter
+
+jmpe820:
+ mov eax, #0x0000e820 ! e820, upper word zeroed
+ mov ecx, #20 ! size of the e820rec
+
+ mov dword ptr [E820+16], #42
+ mov di, #E820 ! es:di points at the
+ push ds ! data record.
+ pop es
+ int 0x15 ! make the call
+ jc meme801 ! fall to e801 if it fails
+
+ cmp eax, #0x534d4150 ! check the return is `SMAP'
+ jne meme801 ! fall to e801 if it fails
+
+ cmp dword ptr [E820+16], #1 ! is this usable memory?
+ jne again820
+
+ ! usable memory: add it to the whitelist
+ !
+good820:
+ mov al, byte ptr [E820NR]
+ cmp al, #E820MAX
+ jnl again820
+ inc byte ptr [E820NR]
+ and ax, #0xff ! clear sign extend
+ shl ax, 3 ! double dword alignment
+ mov si, ax
+ mov ecx, dword ptr [E820+8] ! pick up low dword of memsize
+ mov eax, dword ptr [E820+0] ! pick up low dword of address
+ mov E820MAP(si), eax ! store address in whitelist
+ mov E820MAP+4(si), ecx ! store size in whitelist
+
+ add eax, ecx ! set end_mem to address + memsize
+ mov [E820MEM], eax
+
+again820:
+ cmp ebx, #0 ! check to see if ebx is
+ jne jmpe820 ! set to EOF

- mov ax,#0xe801
- int 0x15
- jc oldstylemem

-! Memory size is in 1 k chunksizes, to avoid confusing loadlin.
-! We store the 0xe801 memory size in a completely different place,
+
+! method E801H:
+! memory size is in 1k chunksizes, to avoid confusing loadlin.
+! we store the 0xe801 memory size in a completely different place,
! because it will most likely be longer than 16 bits.
! (use 1e0 because that's what Larry Augustine uses in his
! alternative new memory detection scheme, and it's sensible
! to write everything into the same place.)

- and ebx, #0xffff ! clear sign extend
- shl ebx, 6 ! and go from 64k to 1k chunks
- mov [0x1e0],ebx ! store extended memory size
-
- and eax, #0xffff ! clear sign extend
- add [0x1e0],eax ! and add lower memory into total size.
-
- ! and fall into the old memory detection code to populate the
- ! compatibility slot.
+meme801:
+
+ mov ax,#0xe801
+ int 0x15
+ jc mem88
+
+ and edx, #0xffff ! clear sign extend
+ shl edx, 6 ! and go from 64k to 1k chunks
+ mov [0x1e0],edx ! store extended memory size
+
+ and ecx, #0xffff ! clear sign extend
+ add [0x1e0],ecx ! and add lower memory into total size.
+
+! Ye Olde Traditional Methode. Returns the memory size (up to 16mb or
+! 64mb, depending on the bios) in ax.
+mem88:

-oldstylemem:
- pop ebx
-#else
- mov dword ptr [0x1e0], #0
#endif
mov ah,#0x88
int 0x15
diff -Nur linux-2.3.10-orig/arch/i386/kernel/setup.c linux-2.3.10/arch/i386/kernel/setup.c
--- linux-2.3.10-orig/arch/i386/kernel/setup.c Mon Jul 5 20:04:47 1999
+++ linux-2.3.10/arch/i386/kernel/setup.c Mon Jul 19 17:10:15 1999
@@ -49,6 +49,7 @@
#include <asm/smp.h>
#include <asm/cobalt.h>
#include <asm/msr.h>
+#include <asm/e820.h>

/*
* Machine setup..
@@ -82,6 +83,8 @@
unsigned char table[0];
};

+struct e820map e820 = { 0 };
+
unsigned char aux_device_present;

#ifdef CONFIG_BLK_DEV_RAM
@@ -101,6 +104,9 @@
#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
+#define E820_MEM (*(unsigned long *) (PARAM+E820MEM))
+#define E820_MAP_NR (*(char*) (PARAM+E820NR))
+#define E820_MAP ((unsigned long *) (PARAM+E820MAP))
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
@@ -277,9 +283,27 @@
#ifndef STANDARD_MEMORY_BIOS_CALL
{
unsigned long memory_alt_end = (1<<20) + (ALT_MEM_K<<10);
- /* printk(KERN_DEBUG "Memory sizing: %08x %08x\n", memory_end, memory_alt_end); */
+ unsigned long *mem = E820_MAP;
+
if (memory_alt_end > memory_end)
memory_end = memory_alt_end;
+
+ if (E820_MEM > memory_end)
+ memory_end = E820_MEM;
+
+ if ((e820.nr_map = E820_MAP_NR) > 0) {
+ int x;
+
+ if (e820.nr_map > E820MAX)
+ e820.nr_map = 0;
+ else for (x = 0; x < e820.nr_map; x++) {
+ e820.map[x].addr = *(mem++);
+ e820.map[x].size = *(mem++);
+ /*printk("E820: region %d, %lu bytes @ %08lx\n",
+ x, e820.map[x].size, e820.map[x].addr);*/
+ }
+ }
+
}
#endif

diff -Nur linux-2.3.10-orig/arch/i386/mm/init.c linux-2.3.10/arch/i386/mm/init.c
--- linux-2.3.10-orig/arch/i386/mm/init.c Tue Jun 29 09:22:08 1999
+++ linux-2.3.10/arch/i386/mm/init.c Mon Jul 19 17:10:15 1999
@@ -27,6 +27,7 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
+#include <asm/e820.h>

extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
@@ -391,6 +392,19 @@
unsigned long tmp;
unsigned long endbase;

+ unsigned long start_seg = 0;
+ unsigned long size_seg = ~0;
+ int nr_map = 0;
+
+ if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ }
+
+
end_mem &= PAGE_MASK;
high_memory = (void *) end_mem;
max_mapnr = num_physpages = MAP_NR(end_mem);
@@ -426,7 +440,23 @@
}

while (start_mem < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ if (start_mem > start_seg) {
+ if (start_mem < start_seg + size_seg)
+ clear_bit(PG_reserved,
+ &mem_map[MAP_NR(start_mem)].flags);
+ else if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ continue; /* be paranoid in case the */
+ /* e820 code hasn't collapsed */
+ /* adjacent usable memory */
+ }
+ else
+ break; /* no more valid memory */
+ }
start_mem += PAGE_SIZE;
}
for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
diff -Nur linux-2.3.10-orig/drivers/block/loop.c linux-2.3.10/drivers/block/loop.c
--- linux-2.3.10-orig/drivers/block/loop.c Mon Jul 5 20:15:24 1999
+++ linux-2.3.10/drivers/block/loop.c Mon Jul 19 19:19:48 1999
@@ -375,7 +375,7 @@
a file structure */
lo->lo_backing_file = NULL;
} else if (S_ISREG(inode->i_mode)) {
- if (!inode->i_op->bmap) {
+ if (!inode->i_op->smap) {
printk(KERN_ERR "loop: device has no block access/not implemented\n");
goto out_putf;
}
diff -Nur linux-2.3.10-orig/fs/binfmt_aout.c linux-2.3.10/fs/binfmt_aout.c
--- linux-2.3.10-orig/fs/binfmt_aout.c Thu Jul 1 10:45:57 1999
+++ linux-2.3.10/fs/binfmt_aout.c Mon Jul 19 21:43:00 1999
@@ -389,21 +389,25 @@
flush_icache_range((unsigned long) 0,
(unsigned long) ex.a_text+ex.a_data);
} else {
+#if 0
if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
(N_MAGIC(ex) != NMAGIC))
printk(KERN_NOTICE "executable not page aligned\n");
+#endif

fd = open_dentry(bprm->dentry, O_RDONLY);
if (fd < 0)
return fd;
file = fget(fd);

+#if 0
if ((fd_offset & ~PAGE_MASK) != 0) {
printk(KERN_WARNING
"fd_offset is not page aligned. Please convert program: %s\n",
file->f_dentry->d_name.name
);
}
+#endif

if (!file->f_op || !file->f_op->mmap || ((fd_offset & ~PAGE_MASK) != 0)) {
fput(file);
@@ -533,10 +537,12 @@
start_addr = ex.a_entry & 0xfffff000;

if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
+#if 0
printk(KERN_WARNING
"N_TXTOFF is not page aligned. Please convert library: %s\n",
file->f_dentry->d_name.name
);
+#endif

do_mmap(NULL, start_addr & PAGE_MASK, ex.a_text + ex.a_data + ex.a_bss,
PROT_READ | PROT_WRITE | PROT_EXEC,
diff -Nur linux-2.3.10-orig/fs/locks.c linux-2.3.10/fs/locks.c
--- linux-2.3.10-orig/fs/locks.c Mon Jul 5 20:11:07 1999
+++ linux-2.3.10/fs/locks.c Mon Jul 19 17:13:56 1999
@@ -448,10 +448,10 @@
current->pid, current->comm);
}
}
+#endif
if (!(filp->f_mode & 3))
goto out_putf;
break;
-#endif
default:
error = -EINVAL;
goto out_putf;
@@ -648,11 +648,22 @@
init_waitqueue_head(&fl->fl_wait);
fl->fl_flags = FL_POSIX;

+ /*
+ * remap old-style locks into the locking method de jour
+ */
switch (l->l_type) {
case F_RDLCK:
case F_WRLCK:
case F_UNLCK:
fl->fl_type = l->l_type;
+ break;
+ case F_SHLCK :
+ fl->fl_type = F_RDLCK;
+ /*fl->fl_flags |= F_BROKEN;*/
+ break;
+ case F_EXLCK :
+ fl->fl_type = F_WRLCK;
+ /*fl->fl_flags |= F_BROKEN;*/
break;
default:
return (0);
diff -Nur linux-2.3.10-orig/include/asm-i386/e820.h linux-2.3.10/include/asm-i386/e820.h
--- linux-2.3.10-orig/include/asm-i386/e820.h Wed Dec 31 16:00:00 1969
+++ linux-2.3.10/include/asm-i386/e820.h Mon Jul 19 17:10:15 1999
@@ -0,0 +1,34 @@
+/*
+ * structures and definitions for the int 15, ax=e820 memory map
+ * scheme.
+ *
+ * In a nutshell, arch/i386/boot/setup.S populates a scratch table
+ * in the empty_zero_block that contains a list of usable address/size
+ * duples. In arch/i386/kernel/setup.c, this information is
+ * transferred into the e820map, and in arch/i386/mm/init.c, that
+ * new information is used to mark pages reserved or not.
+ *
+ */
+#ifndef __E820_HEADER
+#define __E820_HEADER
+
+#define E820 0x2d0 /* scratch area */
+#define E820MAP 0x300 /* our map */
+#define E820MAX 32 /* number of entries in E820MAP */
+#define E820MEM 0x1e4 /* memtop from e820 calls */
+#define E820NR 0x1e8 /* # entries in E820MAP */
+
+#ifndef __ASSEMBLY__
+
+struct e820map {
+ int nr_map;
+ struct {
+ unsigned long addr;
+ unsigned long size;
+ } map[E820MAX];
+};
+
+extern struct e820map e820;
+#endif/*!__ASSEMBLY__*/
+
+#endif/*__E820_HEADER*/
diff -Nur linux-2.3.10-orig/scripts/Menuconfig linux-2.3.10/scripts/Menuconfig
--- linux-2.3.10-orig/scripts/Menuconfig Sun May 2 09:51:16 1999
+++ linux-2.3.10/scripts/Menuconfig Mon Jul 19 17:23:00 1999
@@ -633,12 +633,13 @@

printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu

+ newmenu = sprintf("MCmenu%d", menu_no);
printf( "function MCmenu%s () {\n"\
"default=$1\n"\
"menu_name %s\n",\
- menu_no, $0) >"MCmenu"menu_no
+ menu_no, $0) >newmenu

- parser(ifile, "MCmenu"menu_no)
+ parser(ifile, newmenu)
}
else if ($1 ~ "endmenu") {
printf("}\n") >>menu
diff -Nur linux-2.3.10-orig/scripts/lxdialog/Makefile linux-2.3.10/scripts/lxdialog/Makefile
--- linux-2.3.10-orig/scripts/lxdialog/Makefile Mon Jul 20 10:05:16 1998
+++ linux-2.3.10/scripts/lxdialog/Makefile Mon Jul 19 17:15:11 1999
@@ -25,21 +25,9 @@
SRCS = $(OBJS:.o=.c)


-all: ncurses lxdialog
+all: lxdialog

lxdialog: $(OBJS)
-
-ncurses:
- @x=`find /lib/ /usr/lib/ /usr/local/lib/ -maxdepth 1 -name 'libncurses.*'` ;\
- if [ ! "$$x" ]; then \
- echo -e "\007" ;\
- echo ">> Unable to find the Ncurses libraries." ;\
- echo ">>" ;\
- echo ">> You must have Ncurses installed in order" ;\
- echo ">> to use 'make menuconfig'" ;\
- echo ;\
- exit 1 ;\
- fi

clean:
rm -f core *.o *~ lxdialog

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/