X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f Date: Wed, 08 Nov 2006 08:47:53 -0800 From: Ivor Bowden User-Agent: Thunderbird 1.5.0.7 (Windows/20060909) MIME-Version: 1.0 Newsgroups: comp.os.msdos.djgpp Subject: Re: Accessing absolute address above 1MB References: <1162915098 DOT 476438 DOT 52420 AT k70g2000cwa DOT googlegroups DOT com> In-Reply-To: <1162915098.476438.52420@k70g2000cwa.googlegroups.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Lines: 135 Message-ID: <4551fd54$0$12071$88260bb3@free.teranews.com> NNTP-Posting-Date: 08 Nov 2006 15:52:52 GMT X-Complaints-To: abuse AT teranews DOT com To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com This is the way I do it: /* get the address */ laddr=addr=strtoul(argv[n],&chptr,0); /* map the memory */ /* note map routine changes addr to base_addr */ if ((slctr=map(&addr,size))==-1) printf("failed\n"); laddr-=addr; /* read the data */ _farpeekb(slctr,laddr);printf("0x%02x\n",data); And here is the map routine: /* map physical memory */ u_int map(u_int* addr, u_int size) { __dpmi_meminfo mi; int selector; u_int mapsize; if (*addr < 0x100000) { if (*addr+size <= 0x100000) { *addr=0; return _dos_ds; } else { printf("address + size crosses DOS 0x100000 boundry - exiting\n"); return -1; } } mapsize=0x400; while ((size+(*addr&(mapsize-1)))>mapsize) mapsize<<=1; *addr &=~(mapsize-1); /*printf("mapped addr = 0x%08x, mapped size = 0x%08x\n",*addr,mapsize);*/ mi.handle = 0; /* what should it be? */ mi.address = *addr; mi.size = mapsize; if (__dpmi_physical_address_mapping(&mi)) { printf ("__dpmi_physical_address_mapping failed\n"); return -1; } selector = __dpmi_allocate_ldt_descriptors(1); if (selector == -1) { printf ("__dpmi_allocate_ldt_descriptors failed\n"); return -1; } if(__dpmi_set_segment_base_address(selector,mi.address)) { printf ("__dpmi_set_segment_base_address failed\n"); return -1; } if(__dpmi_set_segment_limit(selector,mi.size-1)) { printf ("__dpmi_set_segment_limit failed\n"); return -1; } return selector; } I have a cool little program that can R/W any memory or IO location, as well as PCI config registers and probing the PCI bus. It used to be on the company web site, but with the new corporate it is gone now, but I can still send it to whoever wants it. It only works with DOS, Windows <= W98 (NOT NT,2K,XP,etc), Unix and VxWorks (separate compile versions). Program name is Peritool. Ivor on 11/7/2006 7:58 AM PDT countingtoten AT gmail DOT com wrote: > I am trying to access the memory address 0x3FFF0000 in DOS using dpmi. > When executed, I receive the following seg fault: > > Exiting due to signal SIGSEGV > General Protection Fault at eip=00003af6 > eax=000001cf ebx=00000299 ecx=00000000 edx=3fff0000 esi=00000054 > edi=0000ff70 > ebp=0008ff08 esp=0008ff08 > program=C:\DOCUME~1\WEINERT\DESKTOP\TEST\DPMITEST.EXE > cs: sel=01a7 base=02990000 limit=0009ffff > ds: sel=01af base=02990000 limit=0009ffff > es: sel=01af base=02990000 limit=0009ffff > fs: sel=01cf base=3fff0000 limit=00000fff > gs: sel=01bf base=00000000 limit=0010ffff > ss: sel=01af base=02990000 limit=0009ffff > App stack: [0008ff70..0000ff70] Exceptn stack: [0000fed0..0000df90] > > Call frame traceback EIPs: > 0x00003af6 > 0x00001e8a > 0x000036c8 > > from this code: > > #include > #include > #include > #include > > int selector; > > int main(int argc, char** argv) > { > __dpmi_meminfo mi; > int selector; > char buffer[4]; > > /* Map the physical device address to linear memory. */ > mi.address = 0x3FFF0000; > mi.size = 0x1000; > > if(mi.address < 0x100000) > { > buffer[0] = _farpeekb(_dos_ds, mi.address); > } > else > { > __dpmi_physical_address_mapping (&mi); > selector = __dpmi_allocate_ldt_descriptors (1); > __dpmi_set_segment_base_address (selector, mi.address); > __dpmi_set_segment_limit (selector, mi.size - 1); > > buffer[0] = _farpeekb(selector, mi.address); > } > } > -- Posted via a free Usenet account from http://www.teranews.com