Cross compiling : problem linking
Fillod Stephane
stephane.fillod at thomson.net
Fri Oct 3 02:34:19 EST 2003
Note to the list: sorry for the RFC2822
> Do you know the replacement for iopl to work on PowerPC?
There's no such crap on PowerPC. No separate IO bus either.
> Final goal is a kernel module, but now I'm writing a test program in
> user space (standalone, dynamic compiled).
Okay, let's use ESP for once :)
Toni, I don't know what's your "base" address, but it is really odd
(well, both ways :) on a PowerPC system. You should borrow some help
from your D-science lab, or have something like a PPC Linux training.
Wolfgang, you've got my agreement to put the following in the FAQ
if it's not already.
This code is for accessing hardware registers from *userland*.
You need CAP_SYS_RAWIO and /dev/mem permissions.
Basically:
volatile void *p = ioremap(MY_HARD_REG_ADDR, 4096);
...
out_8(p, state ^= 0x1);
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#ifdef __PPC__
extern inline void out_8(volatile unsigned char *addr, int val)
{
__asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r"
(val));
}
#else
extern inline void out_8(volatile unsigned char *addr, int val)
{
*add = val & 0xff;
}
#endif
extern inline volatile void * ioremap(unsigned long physaddr, unsigned size)
{
static int axs_mem_fd = -1;
unsigned long page_addr, ofs_addr, reg, pgmask;
void* reg_mem = NULL;
/*
* looks like mmap wants aligned addresses?
*/
pgmask = getpagesize()-1;
page_addr = physaddr & ~pgmask;
ofs_addr = physaddr & pgmask;
/*
* Don't forget O_SYNC, esp. if address is in RAM region.
* Note: if you do know you'll access in Read Only mode,
* pass O_RDONLY to open, and PROT_READ only to mmap
*/
if (axs_mem_fd == -1) {
axs_mem_fd = open("/dev/mem", O_RDWR|O_SYNC);
if (axs_mem_fd < 0) {
perror("AXS: can't open /dev/mem");
return NULL;
}
}
/* memory map */
reg_mem = mmap(
(caddr_t)reg_mem,
size+ofs_addr,
PROT_READ|PROT_WRITE,
MAP_SHARED,
axs_mem_fd,
page_addr
);
if (reg_mem == MAP_FAILED) {
perror("AXS: mmap error");
close(axs_mem_fd);
return NULL;
}
reg = (unsigned long )reg_mem + ofs_addr;
return (volatile void *)reg;
}
extern inline int iounmap(volatile void *start, size_t length)
{
unsigned long ofs_addr;
ofs_addr = (unsigned long)start & (getpagesize()-1);
/* do some cleanup when you're done with it */
return munmap((void*)start-ofs_addr, length+ofs_addr);
}
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-embedded
mailing list