In short, most of the IO devices are available through /dev/ports, except the video, which is available through /dev/mem.
int tmp;
#define outb(p,v) tmp=v; lseek(f_io,p,SEEK_SET); write(f_io,&tmp,1);
#define inb(p) lseek(f_io,p,SEEK_SET), read(f_io,&tmp,1), tmp
f_io = open("/dev/ports",O_RDWR);
outb(0x378,printer_data);
The available devices are
Device Group | Ports |
Keyboard/mouse | 60-6f |
RTC | 70-71 |
IDE | 1f0-1f7 |
sound | 0x250-0x25f |
serial (on board) | 2f8 |
Ether10 | 300-31f |
Misc I/O | 338-33a |
serial (external) | 3f8 |
IDE (dma) | e800-e807 |
To get at the video memory, use the following technique:
f_mem = open("/dev/mem", O_RDWR);
p = mmap(0,0x00200000, PROT_READ | PROT_WRITE, MAP_SHARED, f_mem, 0xd0000000);
p[pixel] = pixel_data;
To get at the video ioports, use the following technique:
f_vid_io = open('/dev/mem", O_RDWR);
p = mmap(0, 0x400, PROT_READ | PROT_WRITE, MAP_SHARED, f_vid_io, 0xd0800000);
p[0x3c5] = reg_num; p[0x3c4] = data;
The registers 3c0, 3c1, 3c2, 3c3, 3c4, 3c5, 3c6, 3c7, 3c8, 3c9, 3ce,
3cf, 3d4, 3d5 do what one would expect.
Further information about the video chip will be forthcoming.
First, let's get the easy one out of the way. The "modem" chip is connected to the modem port only. Data flows to and from the modem codec chip through a pre-programmed PCI buffer chip (a XC5202). This chip provides fifo services so that the StrongArm can read/write bursts of 4 words, which gets shifted from/to the codec at the codec speed. Typically the codec chip is programmed to sample the modem port at a fixed rate (usually 9600 samples/sec). The PCI buffer chip also handles the IO for ring detect, modem off-hook, and codec reset.
The "soundblaster"/WaveArtist chip is connected to the internal speaker and microphone, to the external audio ports, to the handset jack and to the phone port.
The audio chip has internal mux/mixer capabilities. Audio out from the sound chip can be routed to the line out port (through power amp chips; stereo). Or, audio can be mixed to mono, and routed to the internal speaker and handset; if you wish handset-only operation, you must mute the internal speaker (io 0x338/0x33a). Audio in can be selected from the line-in jack (stereo) , from the internal microphone, from the handset or from the phone; all of these selections are done through the audio-chip-mixer functions.
In general, here is where you will find audio features
Device | Ports |
audio control | 250 |
joystick/volume control | 251 |
audio data | 252 |
irq control | 254 |
status | 255 |
interrupt status | 25c |
Speaker/Mic | |
select speaker | line out to mono |
mute speaker | 338 through to external shift register |
select microphone | line in mixer rmic |
External Audio | |
select audio in | line in mixer lline & rline |
seelct audio out | line out to lout & rout |
Handset | |
audio out | line out to mono |
audio in | line in mixer lmic |
handset detect | 251, bit 4 |
Telephone | |
audio out | line out to mono |
audio in | line in mixer laux1 |
off-hook detect | 251, bit 5 |
Device | Port |
modem codec | |
EPP mode
Device | Port |
data | 378 |
status | 379 |
control | 37a, bit 5 is "direction" control (1=read, 0=write) |
control-swapper | 37b |
EPP address | 37b |
EPP data | 37c-37f |
ECP mode
Device | Port |
data | 378 |
status | 379 |
control | 37a, bit 5 is "direction" control (1=read, 0=write) |
fast data | 77b |
To select these extended modes, you need to set the '977 superI/O chip mode through its CRF0 on device #1 (printer)
The recommended irq for the printer is 23. The '977 chip and '553 chip think this is irq 7, but the software considers it irq 23. If you need a dma number, please contact me (patb@corelcomputer.com) to arrange this.
The infrared UART operates exactly as stated in the '977 data sheet. Please contact me (patb@corelcomputer.com) if you enable this, as we need to coordinate irq & dma numbers.
The flash that is installed is NOT boot block protected; you can write
to the whole thing.
Address | Device |
e000.0338 (port 338) | 0x30 bits run the expansion shift register, which contains the flash wp bit |
e180.0000 | read access
NOTE: this is byte-wide access, uncached, so it's about .7-1us per word! |
e180.0000 | write a byte to the flash |
e100.0068 | set address bits a0 & a1 to select 1 of 4 bytes to write |
We have provided a flash-write program, and highly recommend that you use it to write to the flash.
At this point, the first block of the flash is NeTTrom (a small boot
loader) and the next 8-10 blocks are a mini-Linux kernel, which does the
2nd stage boot.
The libstdc++ is designed to work with the glibc. But it is a few months behind glibc, so we had to make a few patches to sync them up.
One of the biggest differences that we have from the x86 versions on Linux is that we have a hardware zero page. For most programs, that is not a problem. But it means that we can never have any code or data at address 0. There is one case in the ELF world where this is important.
When you run a program "foo" that has dynamic linking, it normally loads ld-linux.so.2 up at address 0x4000.0000. The other libraries (like libc) follow, add addresses such as 0x401e.0000.
Alternatively, you can invoke your program as "ld-linux.so.2 foo" (on the command line). This will load ld-linux.so.2 first, which then loads your foo program. Because the ld-linux.so.2 binary is a relocatable library, it has no native load address; on the x86, the kernal loads it into address 0. On ArmLinux, we can't do that; so the kernel loads it at 0x0001.0000.
This is just an interesting phenomenon; it shouldn't affect your day to day programming life; if you have a life, that is.