holes for ISA boards...

Aaron J. Grier (aaron@frye.com)
Fri, 11 Jun 1999 17:55:37 -0700


Summary: how do I make a memory "hole" for doing ISA I/O?

I'm trying to write a driver for an epson video eval board (SED1355)
which will eventually make its way in some form or another to an
embedded system... Unfortunately, the board is ISA, and maps its memory into
IO space starting at 12MB -- which according to the epson docs means
that system memory is limited to 12MB. However, the epson docs also
assume you're using an operating system for which the source is
proprietary... I figured I could somehow put a "hole" by manipulating
page flags, and came up with the following:

Here's the patch of init.c:

--- arch/i386/mm/init.c.orig Thu Jun 10 16:13:22 1999
+++ arch/i386/mm/init.c Fri Jun 11 13:12:27 1999
@@ -423,27 +423,40 @@
start_low_mem += PAGE_SIZE;
}

+ printk("Clearing PG_reserved bits for pages, from %lX to",virt_to_bus((void *)start_mem));
while (start_mem < end_mem) {
+ if(virt_to_bus((void *)start_mem) < 0xC00000 && virt_to_bus((void *)start_mem) >= 0x1000000) {
clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
- start_mem += PAGE_SIZE;
+ } else {
+ set_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ }
+ start_mem += PAGE_SIZE;
}
+ printk(" %lx\n",virt_to_bus((void *)start_mem));
+
for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
if (tmp >= MAX_DMA_ADDRESS)
clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
if (PageReserved(mem_map+MAP_NR(tmp))) {
- if (tmp >= (unsigned long) &_text && tmp < (unsigned long) &_edata) {
- if (tmp < (unsigned long) &_etext)
- codepages++;
- else
- datapages++;
- } else if (tmp >= (unsigned long) &__init_begin
- && tmp < (unsigned long) &__init_end)
- initpages++;
- else if (tmp >= (unsigned long) &__bss_start
- && tmp < (unsigned long) start_mem)
- datapages++;
- else
+ if (virt_to_bus((void *)tmp) >= 0xC00000 && virt_to_bus((void *)tmp) < 0x1000000) {
+ set_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags);
+ clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
reservedpages++;
+ } else {
+ if (tmp >= (unsigned long) &_text && tmp < (unsigned long) &_edata) {
+ if (tmp < (unsigned long) &_etext)
+ codepages++;
+ else
+ datapages++;
+ } else if (tmp >= (unsigned long) &__init_begin
+ && tmp < (unsigned long) &__init_end)
+ initpages++;
+ else if (tmp >= (unsigned long) &__bss_start
+ && tmp < (unsigned long) start_mem)
+ datapages++;
+ else
+ reservedpages++;
+ }
continue;
}
atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
@@ -463,6 +476,8 @@

if (boot_cpu_data.wp_works_ok < 0)
test_wp_bit();
+
+ printk("Done with wp bit test.\n");
}

void free_initmem(void)

It doesn't work, of course... but I don't know why. Here's the oops:

No modules in ksyms, skipping objects
Unable to handle kernel NULL pointer derefernce at virtual address 00000000
current->tss.cr3 = 00101000, %cr3 = 00101000
*pde = 00000000
Oops: 0002
CPU: 0
EIP: 0010:[<c0110950>]
EFLAGS: 00010002
eax: 00000000 ebx: 00000001 ecx: 00000202 edx: 00000000
esi: 00000015 edi: 00000015 ebp: c01c1ef0 esp: c01c1ef8
ds: 0018 es: 0018 ss: 0018
Process swapper (pid: 0, process nr: 0, stackpage=c01c1000)
Stack: 00000015 c01c1f50 c0121504 00000015 00000015 c01c1f50 c01b08a0 00000286
00002000 c01c0000 c016cf1f 00000000 c011faf5 c01b08a8 00000020 c01b08a0
00000286 00000000 00000212 00000001 00000015 00000020 00000000 c011fe97
Call Trace: [<c0121504>] [<c016cf1f>] [<c011faf5>] [<c011fe97>] [<c011f4f4>] [<c01956fe>] [<c106000>]
[<c0191aa0>] [<c0106000>] [<c0100176>]
Code: c7 02 00 00 00 00 83 7a 3c 00 75 28 a1 3c 00 1c c0 c7 42 40

>>EIP: c0110950 <wake_up_process+8/44>
Trace: c0121504 <__get_free_pages+6c/1b8>
Trace: c016cf1f <scrup+6b/108>
Trace: c011faf5 <kmem_cache_grow+fd/374>
Trace: c011fe97 <kmem_cache_alloc+cf/124>
Trace: c011f4f4 <kmem_cache_create+124/530>
Trace: c01956fe <tvecs+163e/6fa5>
Trace: 0c106000 Before first symbol
Trace: c0191aa0 <stext_lock+ba0/1284>
Code: c0110950 <wake_up_process+8/44> 00000000 <_EIP>: <===
Code: c0110950 <wake_up_process+8/44> 0: c7 02 00 00 00 00 movl $0x0,(%edx) <===
Code: c0110956 <wake_up_process+e/44> 6: 83 7a 3c 00 cmpl $0x0,0x3c(%edx)
Code: c011095a <wake_up_process+12/44> a: 75 28 jne c0110984 <wake_up_process+3c/44>
Code: c011095c <wake_up_process+14/44> c: a1 3c 00 1c c0 movl 0xc01c003c,%eax
Code: c0110961 <wake_up_process+19/44> 11: c7 42 40 00 00 00 00 movl $0x0,0x40(%edx)

Kernel panic: Attempted to kill the idle task!
In swapper task - not syncing

Any idea what's going on? Is it impossible for me to poke a hole in memory
from 12-16MB so I can hack on this silly ISA board?

-
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/