sbull ldd3 example driver gets stuck - linux

I'm writing a block device driver and started with the sbull example from here:
http://lwn.net/images/pdf/LDD3/ldd3_pdf.tar.bz2
I loaded the sbull driver successfully on my machine with kernel version 3.5.0-23.
When I run this code:
int main(){
int fd;
if ((fd = open("/dev/sbulla",O_RDWR)) < 0)
{
perror("open: ");
exit(1);
}
lseek(fd,4096,SEEK_SET);
write(fd,"yonityoyin",10);
lseek(fd,4096*2,SEEK_SET);
write(fd,"yonityoyin",10);
close(fd);
}
The session gets stuck.
If i open another session on the machine and print dmesg i get this after some time:
[56437.815570] INFO: task a.out:4640 blocked for more than 120 seconds.
[56437.822742] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[56437.831563] a.out D ffffffff8180cbe0 0 4640 4639 0x00000000
[56437.831571] ffff880852715c08 0000000000000082 0000000000000000 0000000000000001
[56437.831580] ffff880852715fd8 ffff880852715fd8 ffff880852715fd8 00000000000139c0
[56437.831588] ffff8808547c0000 ffff880851bc2e00 ffff880852715be8 ffff88085fd74258
[56437.831595] Call Trace:
[56437.831623] [<ffffffff81127220>] ? __lock_page+0x70/0x70
[56437.831638] [<ffffffff8169d8b9>] schedule+0x29/0x70
[56437.831643] [<ffffffff8169d98f>] io_schedule+0x8f/0xd0
[56437.831652] [<ffffffff8112722e>] sleep_on_page+0xe/0x20
[56437.831657] [<ffffffff8169c25f>] __wait_on_bit+0x5f/0x90
[56437.831663] [<ffffffff81127c1b>] ? find_get_pages_tag+0xcb/0x170
[56437.831674] [<ffffffff81127388>] wait_on_page_bit+0x78/0x80
[56437.831682] [<ffffffff81078490>] ? autoremove_wake_function+0x40/0x40
[56437.831691] [<ffffffff8112749c>] filemap_fdatawait_range+0x10c/0x1a0
[56437.831701] [<ffffffff81133000>] ? do_writepages+0x20/0x40
[56437.831706] [<ffffffff8112755b>] filemap_fdatawait+0x2b/0x30
[56437.831711] [<ffffffff811298e4>] filemap_write_and_wait+0x44/0x60
[56437.831718] [<ffffffff811c0091>] __sync_blockdev+0x21/0x40
[56437.831722] [<ffffffff811c00c3>] sync_blockdev+0x13/0x20
[56437.831726] [<ffffffff811c0139>] __blkdev_put+0x69/0x1c0
[56437.831736] [<ffffffff811c02eb>] blkdev_put+0x5b/0x160
[56437.831740] [<ffffffff811c0415>] blkdev_close+0x25/0x30
[56437.831750] [<ffffffff81188afe>] __fput+0xbe/0x240
[56437.831756] [<ffffffff81188ca5>] fput+0x25/0x30
[56437.831761] [<ffffffff81185976>] filp_close+0x66/0x90
[56437.831766] [<ffffffff81185a3e>] sys_close+0x9e/0x110
[56437.831775] [<ffffffff816a7029>] system_call_fastpath+0x16/0x1b
What could be the problem with the driver?
Just to be clear, I get this problem with the original sbull driver.

Please refer the newer example code.
https://github.com/martinezjavier/ldd3

Related

The device tree header verification error was encountered during uboot startup

I have a problem when using orangepi3.
I have an image that can be used under normal circumstances,
but the following problem occasionally occurs.
Once this problem occurs, the image burned in this time can no longer be used, and only the burned image can be reproduced
The following errors are reported during uboot startup.
Hit any key to stop autoboot: 0
no mmc device at slot 0
mmc2(part 0) is current device
2512 bytes read in 5 ms (490.2 KiB/s)
## Executing script at 43100000
U-boot loaded from SD
Boot script loaded from mmc
** Bad device mmc 0 **
** File not found /boot/dtb/sunxi/sun50i-h6-orangepi3.dtb **
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
8247895 bytes read in 404 ms (19.5 MiB/s)
19425352 bytes read in 945 ms (19.6 MiB/s)
but i am sure this file is exists;
Because when this error exists, I enter uboot and print the device tree. It can print correctly, but executing the command boot will still report this error.
And I checked the file system afterwards and found that the file exists in the path
.
I checked the uboot source code and found this error in the function fdt_check_header
int fdt_check_header(const void *fdt)
{
if (fdt_magic(fdt) == FDT_MAGIC) {
/* Complete tree */
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
/* Unfinished sequential-write blob */
if (fdt_size_dt_struct(fdt) == 0)
return -FDT_ERR_BADSTATE;
} else {
return -FDT_ERR_BADMAGIC;
}
return 0;
}
But in uboot init_sequence_f exe reserve_fdt also have the verification of the device tree header,and the verification has passed.
but in uboot autoboot_command run_command_list cmd_list an error occurred in the device tree header checked.resulting in failure to enter the kernel correctly.
Before entering FDT_ check_ I added a print function before the header function
Before entering the function fdt_check_header() I add a print like following in reserve_fdt()
static int reserve_fdt(void)
{
/*
* If the device tree is sitting immediate above our image then we
* must relocate it. If it is embedded in the data section, then it
* will be relocated with other data.
*/
if (gd->fdt_blob) {
pr_msg("reserve_fdt fdt_check_headeris %d\n",fdt_magic(gd->fdt_blob));
if(fdt_check_header(gd->fdt_blob) != 0)
{
pr_msg("fdt header check error\n");
return -1;
}
//reserve memory for expand dtb ,because cmd_fdt will update the base dtb
gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
fdt_set_totalsize((void*)gd->fdt_blob,gd->fdt_size);
gd->start_addr_sp -= gd->fdt_size * 2;
gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
debug("Reserving %lu Bytes for FDT at: %08lx\n",
gd->fdt_size, gd->start_addr_sp);
}
return 0;
}
And in function fdt_valid() add too;
static int fdt_valid(struct fdt_header **blobp)
{
const void *blob = *blobp;
int err;
if (blob == NULL) {
printf ("The address of the fdt is invalid (NULL).\n");
return 0;
}
printf("fdt_valid fdt_check_header is %d\n",fdt_magic(blob));
err = fdt_check_header(blob);
if (err == 0)
return 1; /* valid */
if (err < 0) {
printf("libfdt fdt_check_header(): %s", fdt_strerror(err));
/*
* Be more informative on bad version.
*/
if (err == -FDT_ERR_BADVERSION) {
if (fdt_version(blob) <
FDT_FIRST_SUPPORTED_VERSION) {
printf (" - too old, fdt %d < %d",
fdt_version(blob),
FDT_FIRST_SUPPORTED_VERSION);
}
if (fdt_last_comp_version(blob) >
FDT_LAST_SUPPORTED_VERSION) {
printf (" - too new, fdt %d > %d",
fdt_version(blob),
FDT_LAST_SUPPORTED_VERSION);
}
}
printf("\n");
*blobp = NULL;
return 0;
}
return 1;
}
Then,when the error occurs,the log is as follows:
U-Boot 2014.07-orangepi (Oct 29 2021 - 09:07:58) Xunlong Software
[1.947]uboot commit : b65841975dcb31f64a2c69344f60db12b98791ae
[1.947]secure enable bit: 0
[1.947]normal mode: with secure monitor
I2C: ready
[1.949]pmbus: ready
[1.949][ARISC] :arisc initialize
[1.975][ARISC] :arisc para ok
[SCP] :sunxi-arisc driver begin startup 2
[SCP] :arisc version: []
[SCP] :sunxi-arisc driver v1.10 is starting
[1.987][ARISC] :sunxi-arisc driver startup succeeded
[1.989]PMU: AXP806
[1.989]PMU: AXP806 found
[1.989]bat_vol=0, ratio=0
[1.989]set pc_bias(1) bias:1800
[1.989]set pg_bias(5) bias:1800
[1.989]set power on vol to default
[1.989]dcdca_vol = 1000, onoff=1
[1.993]aldo2_vol = 3300, onoff=1
[1.998]bldo3_vol = 1800, onoff=1
[2.002]cldo2_vol = 3300, onoff=1
[2.006]cldo3_vol = 3300, onoff=1
[2.010]find power_sply to end
[2.010]cant find pll setting(1320M) from pll table,use default(408M)
[2.012]PMU: cpux 408 Mhz,AXI=204 Mhz
[2.013]PLL6=600 Mhz,AHB1=200 Mhz, APB1=100Mhz MBus=400Mhz
[2.017]DRAM: 1 GiB
[2.019]reserve_fdt fdt_check_headeris -804389139
[2.026]fdt addr: 0x79ccb0e0
[2.026]gd->fdt_size: 0x1a6c0
[2.030]Relocation Offset is: 34e03000
[2.095]gic: sec monitor mode
[2.095]line:180 func:check_ir_boot_recovery start
[2.095]ir boot recovery not used
[2.095][key recovery] no use
[2.096][box standby] read rtc = 0x0
[2.096][box standby] start_type = 0x1
[2.096][box standby] to kernel
[2.096]workmode = 0,storage type = 2
[2.098]MMC: 2
SUNXI SD/MMC: 2
[mmc]: [0-60|61]
[mmc]: [0-51|52]
[mmc]: [7-48|42]
[mmc]: [0-11|12] [26-29|4] [34-50|17]
[mmc]: [0-48|49] [54-56|3] [58-63|6]
[mmc]: [0-26|27] [54-63|10]
[mmc]: [0-58|59]
[mmc]: [6-51|46] [53-58|6]
[mmc]: [1-7|7] [9-56|48]
[mmc]: [1-26|26]
Normal
[6.618]MMC: 2
SUNXI SD/MMC: 2, SUNXI SD/MMC: 2
[6.624]sunxi flash init ok
[6.624]hdmi hdcp not enable!
Using default environment
[6.625]inter uboot shell
Hit any key to stop autoboot: 0
no mmc device at slot 0
mmc2(part 0) is current device
2512 bytes read in 5 ms (490.2 KiB/s)
## Executing script at 43100000
U-boot loaded from SD
Boot script loaded from mmc
** Bad device mmc 0 **
**** File not found /boot/dtb/sunxi/sun50i-h6-orangepi3.dtb **
fdt_valid fdt_check_header is -1271711085
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
fdt_valid fdt_check_header is -1271711085
libfdt fdt_check_header(): FDT_ERR_BADMAGIC**
8247895 bytes read in 404 ms (19.5 MiB/s)
19425352 bytes read in 945 ms (19.6 MiB/s)
## Booting kernel from Legacy Image at 41000000 ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 19425288 Bytes = 18.5 MiB
Load Address: 41000000
Entry Point: 41000000
Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 43300000 ...
Image Name: uInitrd
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 8247831 Bytes = 7.9 MiB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Loading Kernel Image ... OK
reserving fdt memory region: addr=40020000 size=800
reserving fdt memory region: addr=48000000 size=1000000
reserving fdt memory region: addr=48100000 size=4000
reserving fdt memory region: addr=48104000 size=1000
reserving fdt memory region: addr=48105000 size=1000
reserving fdt memory region: addr=79ccb0e0 size=18f20
Loading Ramdisk to 49822000, end 49fffa17 ... OK
Using Device Tree in place at 44000000, end 4401d6bf
[8.736]disp_ioctl, display not init yet
[8.736]disp_ioctl, display not init yet
Starting kernel ...
INFO: BL3-1: Next image address = 0x41000000
INFO: BL3-1: Next image spsr = 0x3c5
WARNING: Unimplemented Standard Service Call: 0xc0000026
and the number fdt_check_headeris -804389139 id normol;
This why?
Why is the verification still correct in the front, but an error occurs in the back?
Have you ever encountered this problem? Or can you give me some advice? Thanks!
Are the report logs same when each reboot ?
If same, the DTB in hardware storage is fine.
And you should be concerned about memory overwriting between two fdt_magic function calls.
You're on 2014.07 which is missing both support for modern ext4 filesystem images as well as the warning / refusal to mount modern ext4 filesystem images that have features enabled by default that show symptoms such as "file I know exists, I can see it in Linux, are not found". Please upgrade to current U-Boot.

system_call value is different each time when I use rdmsrl(MSR_LSTAR, system_call)

I'm writing a lkm to get sys_call_table address and I'm trying to get it by IDT (I have tested other methods and they work). The problem is that when I use rdmsrl to get register MSR_LSTAR, it's different each time.
I have tried function rdmsrl (MSR_LSTAR) and asm sentences in Ubuntu 18.04.1 with kernel 4.15.0-51.
asm("rdmsr" : "=a" (low), "=d" (high) : "c" (IA32_LSTAR));
system_call = (void*)(((long)high<<32) | low);
printk(KERN_INFO "system_call: 0x%llx", system_call);
rdmsrl(MSR_LSTAR, sct_off);
printk("sct_off: %016llx\n", sct_off);
The result is as follows:
system_call: 0xfffffe0000006000
system_call: 0xfffffe000008a000
system_call: 0xfffffe0000032000
Do you have CONFIG_RETPOLINE=y enabled? (check via cat /usr/src/`uname -r`/.config | grep RETPOLINE). If so, for CPUs where Kernel Page Table Isolation is enabled MSR_LSTAR holds the trampoline per-cpu entry SYSCALL64_entry_trampoline instead of the standard entry_SYSCALL_64 for your kernel version.

How do I use pwm-beeper module in Linux Kernel?

I have set my PWM driven beeper up as per the Linux device tree documentation. I see that this results in an extra input device in /sys/class/input:
root:/sys/class/input/input0# ls
capabilities device event0 id modalias name phys power properties subsystem uevent uniq
root:/sys/class/input/input0# cat name
pwm-beeper
However, I don't see anything related to the duty cycle, polarity etc to actually control the beeper. Perhaps I am very mistaken about pwm-beeper as it is clearly created as an input device. Please help!
[update]
Changes in my dts:
pwm15: dmtimer-pwm#15 {
compatible = "ti,omap-dmtimer-pwm";
ti,timers = <&timer15>;
#pwm-cells = <3>;
};
beeper: pwm-beeper {
compatible = "pwm-beeper";
pwms = <&pwm15 0 5000>;
volume-levels = <0 8 20 40 500>;
default-volume-level = <4>;
};
Relevant dmesg:
[ 6.716560] OF: /pwm-beeper: arguments longer than property
[ 6.716566] of_pwm_get(): can't parse "pwms" property
[ 6.716574] pwm-beeper pwm-beeper: Failed to request PWM device:
-22
[ 6.716590] pwm-beeper: probe of pwm-beeper failed with error -22
I am utterly confused because there is just so little info about this device driver mainlined in Linux!
can you post snippet of DT block you have added?
try this block
pwm-beeper {
compatible = "pwm-beeper";
pwms = <&pwm4 0 5000>;
volume-levels = <0 8 20 40 500>;
default-volume-level = <4>;
};
Update 1
TLDR; either reduce you #pwm-cells to 2
Or add one more field i.e. third field to list
like
pwms = <&pwm4 0 5000 1>;
phandle1: node1 {
#list-cells = <2>;
}
phandle2: node2 {
#list-cells = <1>;
}
node3 {
list = <&phandle1 1 2 &phandle2 3>;
}
here notice list has #list-cells differant
phadle1 has 2
phadle2 has 1
so accordingly list has entries.
This will work
whats you linux version ? can you test it on latest stable ?

device driver fn is not being called when system call in userspace is called

i am re-writing a scull device driver.
I have written the open/read/write fns in driver code.
echo "hello" > /dev/myscull0 shows the data being written successfully to my device driver, and open() -> write() ->release() has been called in driver successfully.
Similarly, other operations using standard bash commands are successfull when operated on driver device file. Eg: cat /dev/myscull0 execute drivers read() call.
Now, i am writing a user space program to operate on my device file.
void
scull_open(){
char device_name[DEV_NAME_LENGTH];
int fd = 0;
memset(device_name, 0, DEV_NAME_LENGTH);
if((fgets(device_name, DEV_NAME_LENGTH -1, stdin) == NULL)){
printf("error in reading from stdin\n");
exit(EXIT_SUCCESS);
}
device_name[DEV_NAME_LENGTH -1] = '\0';
if ((fd = open(device_name, O_RDWR)) == -1) {
perror("open failed");
exit(EXIT_SUCCESS);
}
printf("%s() : Success\n", __FUNCTION__);
}
But i am seeing, drivers open() call is not being executed, confirmed from dmesg. I am running the program with sudo privileges, yet no succsess. I supply the input as /dev/myscull0
Infact, after executing the user program, i am seeing two entries in /dev dir
vm#vm:/dev$ ls -l | grep scull
crw-r--r-- 1 root root 247, 1 Feb 27 14:38 myscull0
---Sr-S--- 1 root root 0 Feb 27 14:38 myscull0
vm#vm:/dev$
The first entry was created by me using mknod command, however second entry is created with strange set of permissions after executing the user program.
Output :
/dev/myscull0
scull_open() : Success
Can anyone pls help what wrong i am doing here ?

TinyX shows display using builtin fbtft touchscreen driver but touch doesn't work

I'm using an "adafruitts" touchscreen with a raspi to control a usb peripheral.
The full raspbian kernel takes forever to boot (50 seconds), and part of that is due to the touchscreen driver loading (by modprobe/udev) and initializing.
During the first 20-30 seconds of boot, the display is not loaded, so it is blank. I need this to be a user-friendly item that cannot be blank for 30 seconds each time it is turned on, so I've used buildroot to build a small kernel with the touchscreen driver built-in. (I am on a steep learning curve with buildroot and kernel building in general).
The display driver is fbtft_device.c patched to include the adafruitts display. This patch defines the "touch" half:
/* Touch device spi-half of adafruit touchscreen */
.name = "adafruitts",
.spi = &(struct spi_board_info) {
.modalias = "stmpe610",
.max_speed_hz = 500000,
.mode = SPI_MODE_0,
.chip_select = 1,
.platform_data = &(struct stmpe_platform_data) {
.blocks = STMPE_BLOCK_TOUCHSCREEN | STMPE_BLOCK_GPIO,
.irq_over_gpio = 1,
.irq_gpio = 24,
.irq_trigger = IRQF_TRIGGER_FALLING,
.irq_base = GPIO_IRQ_START + GPIO_IRQS,
.ts = &(struct stmpe_ts_platform_data) {
.sample_time = 4,
.mod_12b = 1,
.ref_sel = 0,
.adc_freq = 2,
.ave_ctrl = 3,
.touch_det_delay = 4,
.settling = 2,
.fraction_z = 7,
.i_drive = 0,
},
}
},
.is_support = 1,
.gpio_settings = (struct gpio_setting []) {
{
.gpio = 24,
.pull = pull_up,
}
},
.gpio_num_settings = 1,
},
and the LCD half:
}, {
/* LCD component of adafruit touchscreen */
.name = "adafruitts",
.spi = &(struct spi_board_info) {
.modalias = "fb_ili9340",
.max_speed_hz = 16000000,
.mode = SPI_MODE_0,
.chip_select = 0,
.platform_data = &(struct fbtft_platform_data) {
.display = {
.buswidth = 8,
.backlight = 1,
},
.bgr = true,
.gpios = (const struct fbtft_gpio []) {
{ "dc", 25 },
{},
},
}
}
}, {
by including:
fbtft_device.name=adafruitts
in the cmdline.txt for the boot loader, I've gotten the display half of the system to work (it boots in ~ 5 seconds :) ) with tinyX/matchbox desktop showing the desktop, but I cannot get the touchscreen part to work (the cursor does not move when I touch the screeen).
Somehow I have to bind the touch part of the touchscreen to tinyX, but I have not been able to figure out how to do this.
I have tried to specify the keyboard (and mouse) when launching tinyX:
X -keybd smpte610 (for example)
but X reports it cannot find the driver.
How can I verify the touch screen input device was successfully loaded?
The boot log has these messages about fbtft_device:
fbtft_device: SPI devices registered:
fbtft_device: spidev spi0.0 500kHz 8 bits mode=0x00
fbtft_device: spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device: 'fb' Platform devices registered:
fbtft_device: bcm2708_fb id=-1 pdata? no
fbtft_device: Deleting spi0.1 (spi0.1)
fbtft_device: Looking at item 0
fbtft_device: Setting pin 24 to 2
stmpe-spi: probe of spi0.1 failed with error -22
fbtft_device: Deleting spi0.0 (spi0.0)
Console: switching to colour frame buffer device 40x30
graphics fb0: fb_ili9340 frame buffer, 320x240, 150 KiB video memory, 16 KiB buffer memory, fps=20, spi0.0 at 16 MHz
fbtft_device: GPIOS used by 'adafruitts':
fbtft_device: 'dc' = GPIO25
fbtft_device: SPI devices registered:
fbtft_device: stmpe610 spi0.1 48000kHz 8 bits mode=0x00
fbtft_device: fb_ili9340 spi0.0 16000kHz 8 bits mode=0x00
kgdb: Registered I/O driver kgdboc.
Is the kgdb message associated with fbtft_device or something else?
If I look in /dev/input I see: event0, event1, and mice. event0 and event1 are associated with an attached keyboard (according to the boot log) and I have no mouse attached. Should there be some other items in input?
If the touch screen input device IS loaded, how to I specify the correct driver for tinyX?
Thanks
What I learned:
By comparing the boot messages in my modprobe/udev/module loading kernel with the fast built-in kernel, it shows:
stmpe-spi: probe of spi0.1 failed with error -22
is a "bad" thing.
A successful driver load will say (something like):
bcm2708_spi.0: registered child spi0.0
and then later:
input: stmpe-ts as /devices/virtual/input/input0
I fixed the "probe" failure by making these changes to my kernel configuration file. (Sorry, I don't want to include the whole thing, so these are the changes from when I had the issue to when the driver successfully loaded according to the syslog):
< Touch Did Not respond > Touch Did respond
> CONFIG_INPUT_FF_MEMLESS=y
< CONFIG_INPUT_POLLDEV=m > CONFIG_INPUT_POLLDEV=y
< CONFIG_INPUT_EVDEV=m > CONFIG_INPUT_EVDEV=y
< CONFIG_TOUCHSCREEN_STMPE=m > CONFIG_TOUCHSCREEN_STMPE=y
> CONFIG_KEYBOARD_STMPE=y
< CONFIG_SERIO=m > CONFIG_SERIO_SERPORT=m
> CONFIG_SPI_DEBUG=y
< CONFIG_SPI_SPIDEV=y
> CONFIG_SPI_GPIO=y
My main objective with these changes was to try to make sure that the dependent drivers were also built-in, and I enabled the debug. (Some of these were magically set by menuconfig, and this is diff from the "non-default" values from buildroot, so the diff is - different)
With this config, I now have event0, event1, event2, mice, and mouse0. The syslog says event1 and event2 are associated with the usb keyboard I have attached. I have no extra mouse attached.
I could use "evtest" to see events from /dev/input/event0 whenever I touched the display. evtest'ing /dev/input/mouse0 threw "Inappropriate ioctl for device"
I restarted X (tinyX) using:
X -mouse mouse,,/dev/input/mouse0
and touches worked, but the touch axis is rotated from the display axis.
I could not figure out a way to fix this in tinyX, so I'm going with a full blown Xorg implementation.
Make sure you have enabled the evdev input support in tinyx (BR2_PACKAGE_XSERVER_XORG_SERVER_KDRIVE_EVDEV) and use the syntax specified in hw/kdrive/src/kinput.c:
/*
* You can call your kdriver server with something like:
* $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
* evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
*/

Resources