Run as root on a Win7 host machine

Hi,

I searched this forum and internet and didn’t find what I needed so I decided to create this post.

I am currently beginning to use the beagleboard-Xm and I am using the IP connection to run my program directly from the windows 7 host machine to the QNX target. My problem is I want to use use functions that requires root/admin permission but I don’t know how to do it. I can connect and run a program but when I run this one

[code]#include
#include
//#include “GPIO/GPIO.h”
#include “GPIO/GPIO2.h”
#include <sys/mman.h>
#include <pthread.h>
#include <sys/neutrino.h>

void* ClassTest(void*);

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

std::cout << "OBPCest program" << std::endl;
std::cout << "Creating ClassTest Thread"<<std::endl;
pthread_create(NULL,NULL,&ClassTest,NULL);
std::cout << "Thread created" << std::endl;
sleep(60);

}

void* ClassTest (void*){
unsigned long mem;
if (ThreadCtl(_NTO_TCTL_IO,0)== - 1){
std::cout << “Thread control failed”<< std::endl;
}
else{
std::cout << " Thread control successful" << std::endl;
/GPIO GPIO1(GPIO1_base);
GPIO1.SetDir(GPIO_22,OUTPUT);
GPIO1.SetPin(GPIO_22);
/

out32(0x48310034,0x00000000);
out32(0x48310094,0x00200000);
mem = in32(0x4831004);
std::cout<<std::hex<<mem<<std::endl;
mem = in32(0x48310094);
std::cout<<std::hex<<mem<<std::endl;

}
return EXIT_SUCCESS;

}[/code]

Output console

[code]OBPCest program
Creating ClassTest Thread
Thread created
Thread control successful

Process 114709 (GeniaOBPC) terminated SIGSEGV code=1 fltno=11 ip=001025f4(GeniaOBPC@main+0xcc) ref=48310034[/code]

On the QNX website, it is written that I need root permission to use Thread_Ctl(_NTO_TCTL_IO,0) ( directly from QNX website , “You need root permissions to use this command.”). I am running Momentics IDE 4.7 under a windows 7 machine. How can I get access to root permission directly from the IDE?

Thank you
Jean-Francois

Salut Jean-Francois,

Well most probably your are already running as root, the reason is, first the program qconn that is handling the connection on the QNX side from which the IDE is starting the program is running root, so any program started by qconn will also be root. Second the call the ThreadCtl is working, that also mean you are running as root.

The problem are the out32/in32. I think you in32 is missing a 0 (only 7 digits instead of 8), but that is not where the real problem is. QNX uses virtual addresses on a non-x86 processor in/out are actually normal address space. Hence for your program to access this physical address space you must map the address range in your program address space. For IO you can use the mmap_device_io call ( from memory )that will return a handler that you can use in further call to in/out.

Bonne chance.

Well there is a lot of coding error in what I posted first so that didn’t help :stuck_out_tongue:. The problem wasn’t the root permission.

But if I understand what you said Mario, if like in my example, I try to access the physical address 0x48310034, the handle (mmap_addr1) won’t actually be 48310034 but rather a virtual address? If so that would explain why when I print my handle in hexadecimal with that call : mmap_addr1 = mmap_device_io(4,0x48310034); , I get the handle 28000034 and not 48310034 (what I expected… ) .

With that thought, could I use something like that ?

dummy = in32(mmap_addr1);
out32(mmap_addr1, dummy);

Sorry again about that piece of code on the other post, there is so many things that are wrong… I was tired and working on the same thing for 7 hours straight so I didn’t see my errors anymore… :stuck_out_tongue:

Thanks
Jean-Francois

Yes mmap_addr1 is a virtual address! You can use mem_offset if you want to get back the physical address! The code with the dummy variable, that will work fine!

Hope you had a good night sleep, fatigue is a son of a bitch (line stolen from Forrest Griffin) ;-)

Cheers

I was able to flash a LED onboard and offboard so I think i’m good with that.

Thank you for your help Mario

Could you please post a copy of your working code.
Thanks

It’s been modified heavily since as I was only fooling around. But basically if you want to use the beagleboard-XM GPIO you gotta set different registers.

First thing to do is to put the corresponding PADCONF register of gpio you want to MODE 4. For example, the userbutton on the beagleboard-Xm is GPIO_4. If you look through the schematics, you see that. Then you look into section 13 of the Hardware Technical Reference in pages 2460 to 2475 for GPIO_4 to find out that the PADCONF register is CONTROL_PADCONF_SYS_BOOT1[31:16] . You need to set that register first and be sure to put the PAD to MODE4 (mode for GPIO). From that point on , you can use the GPIO registers for that pin. With my tests , I used the MMC_DAT_0 which is GPIO_132. So a fast working code would be this

int main(int argc, char *argv[]) {
	uintptr_t mmap_addr;
	uintt32_t mem;
	if (ThreadCtl(_NTO_TCTL_IO,0)== - 1){ //NEED I/O PRIVILEGES
			std::cout << "Thread control failed"<< std::endl;
			error = 1;
	}
	else{
		mmap_addr = mmap_device_io(4,0x4800215C);//PADCONF
		if (mmap_addr == MAP_DEVICE_FAILED){
			std::cout << " mmap_device_io failed" << std::endl;
			error = 1;
		}
		mem = in32(mmap_addr) & 0xFFFF0000 ;// MMC_DAT_0 is bit 15 to 0
		mem |= 0x00000504; //Check CONTROL_PADCONF_X Register page 2569
		out32(mmap_addr,mem); // write PADCONF Register
		munmap_device_io(mmap_addr,4);

		mmap_addr = mmap_device_io(4,0x49056034);//GPIO Output enable
		// GPIO_132 = GPIO_4 of GPIO5 port (each GPIO port is 32 GPIO)
		if (mmap_addr == MAP_DEVICE_FAILED){
			std::cout << " mmap_device_io failed" << std::endl;
			error = 1;
		}
		//write a 0 in the corresponding bit to set to Output
		out32(mmap_addr,(~0x00000010)); //GPIO_4 as Output
		munmap_device_io(mmap_addr,4);

		while(1){ // infinite loop for this example
			mmap_addr = mmap_device_io(4,0x49056094);//SET DATA OUT register see page 3539
			if (mmap_addr == MAP_DEVICE_FAILED){
				std::cout << " mmap_device_io failed" << std::endl;
				error = 1;
			}
			out32(mmap_addr,0x00000010);
			munmap_device_io(mmap_addr,4);
			sleep(1);

			mmap_addr = mmap_device_io(4,0x49056094);//Clear DATA OUT register see page 3538
			if (mmap_addr == MAP_DEVICE_FAILED){
				std::cout << " mmap_device_io failed" << std::endl;
				error = 1;
			}
			out32(mmap_addr,0x00000010);
			munmap_device_io(mmap_addr,4);
			sleep(1);
		}


	}

}

I have not tested it as I wiped it out on the spot, but it should make the MMC_DAT_0 pin switch state each second. Also it’s not the best way to do it but that pretty much I was able to do it.

Jean-Francois