2005-05-20 14:05:37

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Screen regen buffer at 0x00b8000


Why can't I consistantly write to the VGA screen regen buffer
and have it appear on the screen????

It looks like access there is cached??? One needs to change
VT consoles to make it appear!!

The screen-regen buffer at this address is hardware, in the
chip! It should not be cached!




#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <sys/mman.h>


#define ERRORS(s) do { \
fprintf(stderr,"Error from line %d, file %s, call %s, (%s)\n",\
__LINE__,__FILE__,(s), strerror(errno)); \
exit(EXIT_FAILURE); } while(0)

#define TYPE (MAP_FIXED|MAP_SHARED|MAP_FILE|MAP_LOCKED)
#define PROT (PROT_READ|PROT_WRITE)

#define SCREEN 0x000b8000
#define ATTRIB 0x1700
#define COL 64
#define FAIL -1

static const char ln[]=" Link is ";
static const char up[]="up ";
static const char dn[]="down ";

int dummy;

int link_stat() // Dummy for testing
{
dummy ^= 1;
return dummy;
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

int main(int args, char *argv[])
{
unsigned short upmsg[sizeof(up) + sizeof(ln)];
unsigned short dnmsg[sizeof(dn) + sizeof(ln)];
size_t i, j, len;
int fd;
unsigned short *sp, *rp;
#if 0
if(fork())
return 0;
#endif

len = getpagesize();
if((fd = open("/dev/mem", O_RDWR)) == FAIL)
ERRORS("open");
if((sp = mmap((void *)SCREEN, len, PROT, TYPE, fd, SCREEN))==MAP_FAILED)
ERRORS("mmap");
for(i=0; i< sizeof(ln)-1; i++)
{
upmsg[i] = (unsigned short) ln[i] | ATTRIB;
dnmsg[i] = (unsigned short) ln[i] | ATTRIB;
}
for(j=0; j< sizeof(up)-1; j++)
{
upmsg[i] = (unsigned short) up[j] | ATTRIB;
dnmsg[i] = (unsigned short) dn[j] | ATTRIB;
i++;
}
i *= sizeof(unsigned short);
rp = &sp[COL];
(void)nice(20);
for(;;)
{
if(link_stat())
memcpy(rp, upmsg, i);
else
memcpy(rp, dnmsg, i);
usleep(500000);
}
return 0; // Not reached
}


Cheers,
Dick Johnson
Penguin : Linux version 2.6.11.9 on an i686 machine (5537.79 BogoMips).
Notice : All mail here is now cached for review by Dictator Bush.
98.36% of all statistics are fiction.


2005-05-20 14:14:45

by Jan-Benedict Glaw

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 2005-05-20 09:48:35 -0400, Richard B. Johnson <[email protected]> wrote:
> len = getpagesize();
> if((fd = open("/dev/mem", O_RDWR)) == FAIL)
> ERRORS("open");
> if((sp = mmap((void *)SCREEN, len, PROT, TYPE, fd, SCREEN))==MAP_FAILED)
> ERRORS("mmap");

Maybe you'd better not fiddle with physical memory, but use the device
abstraction that's ment to offer that interface? That is, use a
framebuffer driver and open /dev/fb* .

MfG, JBG

--
Jan-Benedict Glaw [email protected] . +49-172-7608481 _ O _
"Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg _ _ O
fuer einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));


Attachments:
(No filename) (803.00 B)
signature.asc (189.00 B)
Digital signature
Download all attachments

2005-05-20 14:44:06

by Marco Rogantini

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 2005-05-20 09:48:35 -0400, Richard B. Johnson <[email protected]> wrote:

> if((fd = open("/dev/mem", O_RDWR)) == FAIL)
> ERRORS("open");
> if((sp = mmap((void *)SCREEN, len, PROT, TYPE, fd, SCREEN))==MAP_FAILED)
> ERRORS("mmap");

Try to open("/dev/mem", O_RDWR | O_SYNC). Without this the mapping
will be chached.

-marco

2005-05-20 15:24:33

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005, Marco Rogantini wrote:

> On Fri, 2005-05-20 09:48:35 -0400, Richard B. Johnson <[email protected]> wrote:
>
>> if((fd = open("/dev/mem", O_RDWR)) == FAIL)
>> ERRORS("open");
>> if((sp = mmap((void *)SCREEN, len, PROT, TYPE, fd, SCREEN))==MAP_FAILED)
>> ERRORS("mmap");
>
> Try to open("/dev/mem", O_RDWR | O_SYNC). Without this the mapping
> will be chached.
>
> -marco
>

Doesn't help.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.11.9 on an i686 machine (5537.79 BogoMips).
Notice : All mail here is now cached for review by Dictator Bush.
98.36% of all statistics are fiction.

2005-05-20 15:31:37

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005, Jan-Benedict Glaw wrote:

> On Fri, 2005-05-20 09:48:35 -0400, Richard B. Johnson <[email protected]> wrote:
>> len = getpagesize();
>> if((fd = open("/dev/mem", O_RDWR)) == FAIL)
>> ERRORS("open");
>> if((sp = mmap((void *)SCREEN, len, PROT, TYPE, fd, SCREEN))==MAP_FAILED)
>> ERRORS("mmap");
>
> Maybe you'd better not fiddle with physical memory, but use the device
> abstraction that's ment to offer that interface? That is, use a
> framebuffer driver and open /dev/fb* .
>
> MfG, JBG

No room for any more drivers. This just writes to a small LCD on an
embedded controller. There should be no reason why I can't
write directly to the physical memory. Anything written to the
physical screen buffer will show up on the screen, as long
as page zero is selected.

I think that I've discovered a bug. I know that what I have written gets
to the screen buffer because I can read in back! This doesn't make
any sense.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.11.9 on an i686 machine (5537.79 BogoMips).
Notice : All mail here is now cached for review by Dictator Bush.
98.36% of all statistics are fiction.

2005-05-20 16:34:58

by Marco Rogantini

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005, Richard B. Johnson wrote:

> Why can't I consistantly write to the VGA screen regen buffer
> and have it appear on the screen????

I wrote the following little program and understood the effect you are
seeing...

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <sys/mman.h>


#define SCREEN 0x000b8000
#define ATTRIB 0x1700

int main (int argc, char **argv) {

int fd;
void *va;
size_t page_size = getpagesize();
unsigned short c = ATTRIB | '0';
int i;

fd = open("/dev/mem", O_RDWR | O_SYNC);
if (!fd) {
perror("open");
exit(1);
}

va = mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, SCREEN);
if (va == (void *) -1) {
perror ("mmap");
exit(1);
}

/* first column of second line of the hardware buffer */
va += 160;

/* printing ascii '0' to '9' */
for (i = 0; i < 10; i++) {
*((unsigned short *) va) = c;
c += 1;
sleep(1);
}

return 0;
}


Do you remember that the linux console uses hardware buffers for
its scrolling capabilities (shift-pgup and shift-pgdown)?

When you hit enter to run your program the display line you are
addressing in your program has gone off by one so it is out of visual.

To see your line you must go to the begginning of the buffer in the
console (shift-pgup until at the top) since you write to the first
line in the hardware buffer.

Hope this helps

-marco

2005-05-20 19:27:24

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005, Richard B. Johnson wrote:
> On Fri, 20 May 2005, Jan-Benedict Glaw wrote:
> > On Fri, 2005-05-20 09:48:35 -0400, Richard B. Johnson
> > <[email protected]> wrote:
> > > len = getpagesize();
> > > if((fd = open("/dev/mem", O_RDWR)) == FAIL)
> > > ERRORS("open");
> > > if((sp = mmap((void *)SCREEN, len, PROT, TYPE, fd,
> > > SCREEN))==MAP_FAILED)
> > > ERRORS("mmap");
> >
> > Maybe you'd better not fiddle with physical memory, but use the device
> > abstraction that's ment to offer that interface? That is, use a
> > framebuffer driver and open /dev/fb* .

/dev/vcs*?

> No room for any more drivers. This just writes to a small LCD on an
> embedded controller. There should be no reason why I can't
> write directly to the physical memory. Anything written to the
> physical screen buffer will show up on the screen, as long
> as page zero is selected.
>
> I think that I've discovered a bug. I know that what I have written gets
> to the screen buffer because I can read in back! This doesn't make
> any sense.

Even if it's only in the CPU cache, of course you can read it back (using the
CPU, not DMA ;-).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2005-05-20 19:45:46

by Valdis Klētnieks

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005 21:26:59 +0200, Geert Uytterhoeven said:
> On Fri, 20 May 2005, Richard B. Johnson wrote:

> > I think that I've discovered a bug. I know that what I have written gets
> > to the screen buffer because I can read in back! This doesn't make
> > any sense.
>
> Even if it's only in the CPU cache, of course you can read it back (using the
> CPU, not DMA ;-).

No, the bug is in Richard's assuming that because he can read it back in means
that it's in the screen buffer. In fact, it only means he wrote it into some
memory location that he can read back in. ;)

Now if he added a description that verified that a read *from the screen buffer*
(rather than "from where he wrote") shows his changes, *then* he'd have something...


Attachments:
(No filename) (226.00 B)

2005-05-20 20:00:14

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005 [email protected] wrote:

> On Fri, 20 May 2005 21:26:59 +0200, Geert Uytterhoeven said:
>> On Fri, 20 May 2005, Richard B. Johnson wrote:
>
>>> I think that I've discovered a bug. I know that what I have written gets
>>> to the screen buffer because I can read in back! This doesn't make
>>> any sense.
>>
>> Even if it's only in the CPU cache, of course you can read it back (using the
>> CPU, not DMA ;-).
>
> No, the bug is in Richard's assuming that because he can read it back in means
> that it's in the screen buffer. In fact, it only means he wrote it into some
> memory location that he can read back in. ;)
>
> Now if he added a description that verified that a read *from the screen
> buffer*
> (rather than "from where he wrote") shows his changes, *then* he'd have
> something...
>

Well MAP_FIXED must either mmap the physical location I provided or
it must fail. Since it didn't fail, I figure that it did what I
told it to do. Now, that "FIXED" refers to a fixed offset. Geert is
correct when he says that it's probably just in cache. Now begs
the question... Why would a hardware buffer ever be cached? That's
why I think I found a bug. It certainly shouldn't be cached.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.11.9 on an i686 machine (5554.17 BogoMips).
Notice : All mail here is now cached for review by Dictator Bush.
98.36% of all statistics are fiction.

2005-05-20 20:01:55

by Linus Torvalds

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000



On Fri, 20 May 2005, Richard B. Johnson wrote:
>
> Why can't I consistantly write to the VGA screen regen buffer
> and have it appear on the screen????

Don't do it.

> It looks like access there is cached??? One needs to change
> VT consoles to make it appear!!

No.

> The screen-regen buffer at this address is hardware, in the
> chip! It should not be cached!

It's not cached, and it's hardware, and you don't know your VGA well
enough.

0x00b8000 may be the beginning of video memory (in certain text
configurations) but it is _not_ where the screen is. That is offset by the
text offset register (I forget what index that is), and what you're seeing
is almost certainly due to the fact that the kernel VGA console driver
scrolls by just changing that offset, instead of moving lots of slow PCI
memory around.

Switching consoles works for you, because it ends up resetting the offset.

Anyway, you really _really_ shouldn't do anything like this in the first
place.

Linus

2005-05-20 20:18:10

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005, Linus Torvalds wrote:

>
>
> On Fri, 20 May 2005, Richard B. Johnson wrote:
>>
>> Why can't I consistantly write to the VGA screen regen buffer
>> and have it appear on the screen????
>
> Don't do it.
>

Well I started out opening /dev/vcs, lseeking to 64, and writing
a string. This "sort of" worked, but screen attributes got messed
up so the "blue" screen attribute 0x17 ended up eventually being
black.

So, I decided to directly write. It doesn't work as you explain
because hardware scroll is being used.

>
> Anyway, you really _really_ shouldn't do anything like this in the first
> place.
>
> Linus
>

Yes, and I didn't want to. However a customer wants some status to
be always displayed in the upper-right-hand corner of a 4x5 LCD
with a tiny CPU board.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.11.9 on an i686 machine (5554.17 BogoMips).
Notice : All mail here is now cached for review by Dictator Bush.
98.36% of all statistics are fiction.

2005-05-20 21:21:08

by [email protected]

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On 5/20/05, Richard B. Johnson <[email protected]> wrote:
> On Fri, 20 May 2005, Linus Torvalds wrote:
> Yes, and I didn't want to. However a customer wants some status to
> be always displayed in the upper-right-hand corner of a 4x5 LCD
> with a tiny CPU board.

The console implements a tiny terminal emulator. Does the emulator
implement the escape sequence for locking an unscrollable line at the
top of the screen? If so lock the line, write your info there, and the
rest of the display will work like normal.

--
Jon Smirl
[email protected]

2005-05-20 21:28:38

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Fri, 20 May 2005, Jon Smirl wrote:

> On 5/20/05, Richard B. Johnson <[email protected]> wrote:
>> On Fri, 20 May 2005, Linus Torvalds wrote:
>> Yes, and I didn't want to. However a customer wants some status to
>> be always displayed in the upper-right-hand corner of a 4x5 LCD
>> with a tiny CPU board.
>
> The console implements a tiny terminal emulator. Does the emulator
> implement the escape sequence for locking an unscrollable line at the
> top of the screen? If so lock the line, write your info there, and the
> rest of the display will work like normal.
>
> --
> Jon Smirl
> [email protected]
>

I'll experiment. I know that real VT100s can set a scrolling region
so I could set a scrolling region from line 2 to 25 if it works.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.11.9 on an i686 machine (5554.17 BogoMips).
Notice : All mail here is now cached for review by Dictator Bush.
98.36% of all statistics are fiction.

2005-05-20 23:39:11

by James Simmons

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

> > Yes, and I didn't want to. However a customer wants some status to
> > be always displayed in the upper-right-hand corner of a 4x5 LCD
> > with a tiny CPU board.
>
> The console implements a tiny terminal emulator. Does the emulator
> implement the escape sequence for locking an unscrollable line at the
> top of the screen? If so lock the line, write your info there, and the
> rest of the display will work like normal.

Yes it does. This is how the penguin is displayed without scrolling in the
framebuffer console.

2005-05-23 18:29:05

by Gábor Lénárt

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

Hello,

On Fri, May 20, 2005 at 04:17:43PM -0400, Richard B. Johnson wrote:
> Well I started out opening /dev/vcs, lseeking to 64, and writing
> a string. This "sort of" worked, but screen attributes got messed
> up so the "blue" screen attribute 0x17 ended up eventually being
> black.

/dev/vcsa != /dev/vcs !!!!

There are two different devices, as far as I remember, one is only for
the characters itself on the console, and one includes attributes as well ...

FYI Documentation/devices.txt:

0 = /dev/vcs Current vc text contents
1 = /dev/vcs1 tty1 text contents
[...]
128 = /dev/vcsa Current vc text/attribute contents
129 = /dev/vcsa1 tty1 text/attribute contents


- G?bor

2005-05-23 18:56:52

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Screen regen buffer at 0x00b8000

On Mon, 23 May 2005, [ISO-8859-2] G?bor L?n?rt wrote:

> Hello,
>
> On Fri, May 20, 2005 at 04:17:43PM -0400, Richard B. Johnson wrote:
>> Well I started out opening /dev/vcs, lseeking to 64, and writing
>> a string. This "sort of" worked, but screen attributes got messed
>> up so the "blue" screen attribute 0x17 ended up eventually being
>> black.
>
> /dev/vcsa != /dev/vcs !!!!
>
> There are two different devices, as far as I remember, one is only for
> the characters itself on the console, and one includes attributes as well ...
>
> FYI Documentation/devices.txt:
>
> 0 = /dev/vcs Current vc text contents
> 1 = /dev/vcs1 tty1 text contents
> [...]
> 128 = /dev/vcsa Current vc text/attribute contents
> 129 = /dev/vcsa1 tty1 text/attribute contents
>
> - G?bor
>

Thanks, I'll check this out.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.11.9 on an i686 machine (5554.17 BogoMips).
Notice : All mail here is now cached for review by Dictator Bush.
98.36% of all statistics are fiction.