Windows Driver substitue for linux device driver sysfs interface - windows

Let me describe what sysfs does : its a pseudo file system where files, directories are generated by the core kernel or kernel drivers. And these files have read/write access and are a mechanism to control certain kernel level parameters by user space (seperate from ioctls and file operations).
Sysfs from Kernel.org
Sysfs from Wikipedia
The following is an example of how userspace interacts with sysfs.
$ cat /sys/modules/mydriver/foo_count
1
$ echo "2" > /sys/modules/mydriver/foo_count $ cat /sys/modules/mydriver/foo_count
2
The cat command will trigger a read via the show_foo_count() kernel routine, while the echo will trigger a write via the store_foo_count() routine
The following is how the kernel driver/module might intercept the user space activity.
static ssize_t show_foo_count(struct kobject *kobj,struct kobj_attribute *attr,
char *buf)
{
/* This will perform a read operation and contents of buf will be updated*/
...
}
static ssize_t store_foo_count(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf,size_t len)
{
/* Contents are read from buf and stored within the driver's context/state */
...
}
A good example is here
How can one achieve the same sysfs usage on windows drivers ?
I see the following windows concepts, but I am unable to map them to be the equivalent of syfs :
A. Device Objects
B. File Object

Related

Reading user-space address address when debugging kext

I'd like to read user space address from lldb when debugging remote machine driver (kext) via kdp. I know that in code I could use copyin in order to move the code to kernel space and read it easily, so as expected when I've tried to read user memory directly it failed :
(lldb) memory read 0x000070000d15a024
error: kdp read memory failed (error 4)
is there some alternative to copyin during runtime debugging session to convert my data somewhere I could read it from the debugger ?
thanks
Assuming you load the debug scripts for the specific kernel you use (should be in the appropriate KDK), you have the printuserdata command.
This is its description:
printuserdata:
Read userspace data for given task and print based on format provided.
Syntax: (lldb) printuserdata <task_t> <uspace_address> <format_specifier>
params:
<task_t> : pointer to task
<uspace_address> : address to user space memory
<format_specifier> : String representation for processing the data and printing it.
e.g Q -> unsigned long long, q -> long long, I -> unsigned int, i -> int
10i -> 10 ints, 20s -> 20 character string, s -> null terminated string
See: https://docs.python.org/2/library/struct.html#format-characters
options:
-X : print all values in hex.
-O <file path>: Save data to file
Example invocation:
(lldb) printuserdata 0xffffff8013257d80 0x00007fff941f5000 10c

Linux: boot arguments with U-Boot and Flat Image Tree (FIT)

I am trying to get my own build of U-Boot to boot Linux on a Jetson TK1 board. As we are pushing for verified boot I am using the Flat Image Tree (unifying kernel image, device tree blob, ...) to describe my system. U-Boot can load the ITB file and tries to start the kernel but the system hangs after this message.
I assume that this is because no boot arguments are passed to the kernel (the original startup adds loads of arguments) but I am a little dumbfounded on how to pass the arguments to the kernel. I tried setting the bootargs environment variable but this did not change the situation.
How do I pass kernel arguments to the kernel when using an ITB file?
Command line arguments (taken from the APPEND command of the examples extlinux.conf):
console=ttyS0,115200n8 console=tty1 no_console_suspend=1
lp0_vec=2064#0xf46ff000 video=tegrafb mem=1862M#2048M memtype=255 ddr_die=2048M#2048M
section=256M pmuboard=0x0177:0x0000:0x02:0x43:0x00 vpr=151M#3945M tsec=32M#3913M
otf_key=c75e5bb91eb3bd947560357b64422f85 usbcore.old_scheme_first=1 core_edp_mv=1150
core_edp_ma=4000 tegraid=40.1.1.0.0 debug_uartport=lsport,3 power_supply=Adapter
audio_codec=rt5640 modem_id=0 android.kerneltype=normal usb_port_owner_info=0
fbcon=map:1 commchip_id=0 usb_port_owner_info=0 lane_owner_info=6 emc_max_dvfs=0
touch_id=0#0 tegra_fbmem=32899072#0xad012000 board_info=0x0177:0x0000:0x02:0x43:0x00
root=/dev/mmcblk0p1 rw rootwait tegraboot=sdmmc gpt
Content of ITS file:
/dts-v1/;
/ {
description = "Simple image with single Linux kernel and FDT blob";
#address-cells = <1>;
images {
kernel#1 {
description = "Vanilla Linux kernel";
data = /incbin/("./zImage");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0x81008000>;
entry = <0x81008000>;
hash#1 {
algo = "crc32";
};
hash#2 {
algo = "sha1";
};
};
fdt#1 {
description = "Flattened Device Tree blob";
data = /incbin/("./tegra124-pm375.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
hash#1 {
algo = "crc32";
};
hash#2 {
algo = "sha1";
};
};
};
configurations {
default = "conf#1";
conf#1 {
description = "Boot Linux kernel with FDT blob";
kernel = "kernel#1";
fdt = "fdt#1";
};
};
};
U-Boot Output:
Tegra124 (Jetson TK1) # fatload mmc 1 0x90000000 /kernel_fdt.itb
reading /kernel_fdt.itb
5946200 bytes read in 497 ms (11.4 MiB/s)
Tegra124 (Jetson TK1) # bootm 0x90000000
## Loading kernel from FIT Image at 90000000 ...
Using 'conf#1' configuration
Verifying Hash Integrity ... OK
Trying 'kernel#1' kernel subimage
Description: Vanilla Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x900000ec
Data Size: 5910168 Bytes = 5.6 MiB
Architecture: ARM
OS: Linux
Load Address: 0x00000000
Entry Point: 0x00000000
Hash algo: crc32
Hash value: c5b4b377
Hash algo: sha1
Hash value: f001007efe83f563425bfe0659186a32395c946c
Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading fdt from FIT Image at 90000000 ...
Using 'conf#1' configuration
Trying 'fdt#1' fdt subimage
Description: Flattened Device Tree blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x905a30ac
Data Size: 34678 Bytes = 33.9 KiB
Architecture: ARM
Hash algo: crc32
Hash value: e466b23e
Hash algo: sha1
Hash value: ec909ae16e62233d0ed1e1f4c909085abc9b5879
Verifying Hash Integrity ... crc32+ sha1+ OK
Booting using the fdt blob at 0x905a30ac
Loading Kernel Image ... OK
Using Device Tree in place at 905a30ac, end 905ae821
Starting kernel ...
The salient issue is that the system seems to hang after U-Boot outputs the text
Starting kernel ...
If an uncompressed kernel Image file has been loaded, then the actual kernel startup code would be executed next.
But if a uImage or zImage file has been loaded (which are also reported as "uncompressed" because they are self-extracting), then the next code executed would be the decompression routine that is attached to the zImage file. Normally this decompression routine will output text such as
Uncompressing Linux............ done, booting the kernel.
before the actual kernel startup code would be executed, before any processing of the kernel command line, before any processing of the Device Tree blob, and prior to any console output from the kernel (including earlyprintk).
There's a discrepancy between the kernel load & start addresses specified in the image header
Load Address: 0x00000000
Entry Point: 0x00000000
versus what is specified in the DT:
load = <0x81008000>;
entry = <0x81008000>;
Since the kernel image is temporarily loaded at
## Loading kernel from FIT Image at 90000000 ...
the addresses in the DT would seem to be correct, and the addresses in the image header are bogus.
Assuming that there is no physical RAM at 0x00000000, the result will be that the kernel image is copied (or decompressed) to the bogus load address of 0, and then the kernel image will be executed by branching to the bogus entry point of 0. The CPU is likely to hang trying to execute garbage from nonexistent memory, and that correlates perfectly with what you report.
Solution is (1) confirm that the kernel is linked to the correct address and (2) to specify the correct addresses in the mkimage command using the -a and -e command options.
This correction should at least get you past this one point.
When using device tree, you still use bootargs to provide arguments.
Check that:
You have compiled the tree (using compiler scripts/dtc/dtc inside the Linux kernel)
Support for device tree is enabled in the kernel config (symbol CONFIG_USE_OF) (where OF stands for "Open Firmware")
You provided U-Boot the address of the tree: bootm <uImage address> - <dtb address>
Serial console is enabled in the kernel config under Device Drivers -> Character Devices -> Serial Drivers
Console is enabled in bootargs (e.g., console=ttyS0,115200)
I experienced the same or similar issue. My solution (or work around) for this issue was to set the U-Boot environment variables initrd_high and fdt_high to an address in RAM before the relocated U-boot (in my case 8effffff).

Linux GPIOs handling

I have some question about Linux kernel and GPIOs. I know that in Linux everything is file so when I do something like
echo 30 > /sys/class/gpio/export
and
echo 1 > /sys/class/gpio/gpio30/value
what really happens? I mean how does sysfs handle that? Does it call system calls implemented in gpiolib?
The gpiolib registers the value attribute in this way:
static const DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store);
It creates a device attribute named value, with permission 644; on read it calls gpio_value_show, on write it calls gpio_value_store
What sysfs does, is to redirect read and write to the correspondent function of a sysfs attribute.

RS232 serial port communication in kernelspace

I'm writing a kernel module for Linux v3.2 to control an external laser, but I'm having trouble communicating signals through the RS232 serial port on the machine.
There seems to be a serial driver already compiled in my kernel holding ownership to the ioport addresses I want to access:
# cat /proc/ioports | grep serial
02e8-02ef : serial
02f8-02ff : serial
03f8-03ff : serial
This makes sense since Linux allows userspace programs to use the /dev/ttyS* device nodes to communicate via the serial ports. For example, here's how I setup the device for an LCD panel:
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
...
/* Initialization and configuration */
const char *const lcd_dev = "/dev/ttyS1";
int lcd_dev_fd = open(lcd_dev, O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(lcd_dev_fd, F_SETFL, 0);
struct termios options;
tcgetattr(lcd_dev_fd, &options);
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_oflag &= ~OPOST;
tcsetattr(lcd_dev_fd, TCSANOW, &options);
...
/* sending bytes */
const unsigned char scls[] = {0xFE, 'X', 0xFE, 75, 0xFE, 84, 0xFE, 'H'};
write(lcd_dev_fd, scls, sizeof(scls);
However, this is a userspace interface and thus incompatible with my kernelspace module. I need a way to produce the same effect (RS232 serial I/O) but from within kernelspace.
Although I can unload the default Linux serial driver and replace it with my own custom RS232 driver, I don't want to reinvent the wheel here -- the default Linux serial driver appears to support the functionality I require.
Is there a simple way to communicate via the RS232 serial ports in kernelspace (perhaps through this default Linux serial driver), or do I just have to program my own custom RS232 driver?
Take a look at line disciplines. You can use it to attach a tty device to some read and write routines defined in kernelspace and thus write a driver using a serial line. The line discipline gets attached to it from user space and the kernel will do all the rest.
A good example is slcan (drivers/net/can/slcan.c). Examples for the libc calls handling this can be found in can-utils (https://gitorious.org/linux-can/can-utils). If you prefer working by book chapter 18 of Linux Device Drivers will give a good first step: http://www.makelinux.net/ldd3/chp-18, though the book is not very up to date. Some details may also be found at http://www.linusakesson.net/programming/tty/.

Profiling the memory used by linux kernel

I have linux kernel 2.6.30 on an ARM based embedded device.
I have to do some kernel memory usage profiling on the device.
I am thinking of monitoring the ps output on various kernel threads and modules while I carry out actions like wifi on/off etc.
Can you suggest me:
Which threads I need to monitor? How to monitor the kernel module memory usage?
sometimes it is useful to get the real info straight from the kernel, I have used this little C program I threw together to get real system info in an output format that is suited for the shell (it compiles down to a pretty small binary if that matters) --
#include <sys/sysinfo.h>
int main(int argc, char **argv){
struct sysinfo info;
sysinfo(&info);
printf( "UPTIME_SECONDS=%d\n"
"LOAD_1MIN=%d\n"
"LOAD_5MIN=%d\n"
"LOAD_15MIN=%d\n"
"RAM_TOT=%d\n"
"RAM_FREE=%d\n"
"MEMUSEDKB=%d\n"
"RAM_SHARED=%d\n"
"RAM_BUFFERS=%d\n"
"SWAP_TOT=%d\n"
"SWAP_FREE=%d\n"
"PROCESSES=%d\n",
info.uptime,
info.loads[0],
info.loads[1],
info.loads[2],
info.totalram,
info.freeram,
(info.totalram-info.freeram)*info.mem_unit/1024,
info.sharedram,
info.bufferram,
info.totalswap,
info.freeswap,
info.procs);
}
I use it in the shell like this:
eval `sysinfo`
BEFORERAM=$MEMUSEDKB
command &
sleep .1 #sleep value may need to be adjusted depending on command's run time
eval `sysinfo`
AFTERRAM=$MEMUSEDKB
echo RAMDELTA is $(($AFTERRAM - BEFORERAM ))

Resources