Hi Aubrey,
Aubrey Li wrote:
> On 8/2/07, Gavin Maltby <[EMAIL PROTECTED]> wrote:
>
>> On 08/02/07 14:18, Aubrey Li wrote:
>>
>>> Hi all,
>>>
>>> I can access a Global structure by mdb-> Global_struct=X, it prints
>>> the address of that structure. Now I want to access it from user
>>> space, so I wrote a driver and put it in the read op.
>>> cmn_err(CE_NOTE, "Global structure = 0x%x\n", (unsigned
>>> int)&Global_struct);
>>>
>>> The driver build successful but report error( undefined symbol) when
>>> issue "add_drv mydriver".
>>> It's wired for me. Can't the driver access the global variable of the
>>> kernel?
>>>
>> Yes there are restrictions.
>>
>> The 'mem' driver already exists for this purpose - it supplies /dev/zero,
>> /dev/mem, /dev/physmem, /dev/kmem, /dev/allkmem etc. Together with
>> /dev/ksyms (see manpage) they provide the infrastructure on top
>> of which libkvm builds, and mdb just uses those interfaces.
>> So you can lookup a symbol or symbols using kvm_nlist and then
>> read out the structure with kvm_read. Those are supplied
>> by libkvm and you can use that to build standalone applications.
>> Alternatively, work within the friendlier mdb api but accept
>> living in a dcmd or walker.
>>
>> Cheers
>>
>> Gavin
>>
>>
>>
> Hi Gavin,
>
> Thanks for your quick reply.
> I don't think a standalone application is my purpose, but I'm not
> familiar with kvm_read.
> I wanna dump a kernel global structure from user space, even using
> kvm_read, I think I can only get an address? So I need type-casting to
> convert the address to an structure pointer, here I need the structure
> define, where kernel header is needed.
> So Is the driver still a better choice?
>
Once you have the address (from the driver cmn_err() call), you could
just open /dev/kmem, lseek to the address, and print the contents of the
structure, something like:
fd = open("/dev/kmem", O_RDONLY);
lseek(fd, kernel_address, SEEK_SET);
read(fd, &global_structure, sizeof(global_structure));
printf("xxx = %x\n", global_structure.xxx);
printf("yyy = %x\n", global_structure.yyy);
...
Instead of printing the global address from the driver, you could
instead add an ioctl to get the address, and then
have you app open the device, ioctl to get the address, and then do the
above. Really, if all you want to do
is print the structure from user space, it would be much simpler to use
mdb to do this. mdb is in user space.
Also, the driver can access global variables. If you are getting an
"undefined symbol" when you try to load the
driver, it sounds like the global symbol is defined in some other module
(driver), and the module/driver where the
symbol is defined is not loaded when the driver is being added. When
you build the driver, use:
$ ld -r -dy -N drv/foo mydriver.o -o mydriver
to specify that your driver (mydriver) has a dependency on the "foo"
module (where "foo" defines the global).
max
_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code