tiny_serial driver example from LDD - linux

I have compiled and installed the tiny_serial driver example from the book Linux Device Drivers by Greg Kroah-Hartman. I use the sources from https://github.com/duxing2007/ldd3-examples-3.x.git
The device node /dev/ttytiny0 is successfully created but I am having trouble reading anything from the device. Looking at the driver, it seems that I should be able to read a 't' character.
Running stty gets me the following below error:
root#brijesh-M11BB:~/ldd3-examples-3.x# setserial /dev/ttytiny0
/dev/ttytiny0, UART: unknown, Port: 0x0000, IRQ: 0
root#brijesh-M11BB:~/ldd3-examples-3.x# stty -F /dev/ttytiny0
stty: /dev/ttytiny0: Input/output error
Similarly doing cat /dev/tinytty0 also reports a similar error. I also tried minicom -D /dev/ttytiny0 but the device is always shown as offline.
It seems I am missing something, can anyone please point out what I am missing?
This is happening with me on both Ubuntu 15.10 (3.19.x kernel) and older 2.6.28 kernel.

I have debugged it and found the root cause.
strace shows -EIO on tinytty0 device. -EIO was generated from driver tty layer (-ENO_TTY_DEVICE). The reason for ENO_TTY_DEVICE was port->type is set to 0 (i.e unknown). Setting the port->type = PORT_16550A before adding uart driver resolved the issue.

While the previous answer was correct, it did not explain where to fix the code.
Note: I am using linux kernel 3.10
I implemented the one-line fix in the declaration of the uart_port struct, here is how:
static struct uart_port tiny_port = {
.ops = &tiny_ops,
.type = PORT_16550A, // THIS IS THE FIX
};
I believe this may be a bug in the kernel code, because by not setting the uart_port type, it defaults to PORT_UNKNOWN.
While I understand this may be a protection, it seems more correct to leave it at PORT_UNKNOWN rather than that of another random device.
BONUS POINTS:
After fixing the PORT_UNKNOWN issue, if you get a kernel panic for dividing by 0, comment out the following lines from duxing2007's code:
baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
BONUS POINTS 2:
This link shows how a developer with a similar issue (Ira Snyder) implemented the tiny_exit() function, so that you can remove the kernel module without causing a hang.

Related

Profiling anti-debugging checks in linux

My main requirement is to profile the mentioned anti-debugging check program twice ( Once in the presence of a debugger and the other without it ) to collect some information for analysis during run-time (Assuming only the binary is available)
#include <stdio.h>
#include <sys/ptrace.h>
int i_am_debugged()
{
if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0)
{
printf("Avoid debugging please");
return 1;
}
return 0;
}
int main()
{
if(i_am_debugged())
{
return 1;
}
printf("It's going well ! No debugging !\n");
return 0;
}
Currently , I wrote a Intel PIN tool for the same but I am unable to profile a run when a debugger is not attached because of the way PIN works and always executes 'It's going well ! No debugging !'.
So, my question:
Is there anything I can do (attach a debugger and run the pin tool or something) to profile both types of runs using my PIN tool or will any other type of profiling (for ex Binary translation, etc) help me in this case?
I want to collect specific information about instructions and not just Call graph,etc and hence would like some functionality similar to PIN's C++ programmer interface.
A detailed answer would be great, Thanks.
Pin uses ptrace to inject itself into the application. This means that using gdb won't be possible when attempting to launch an application with Pin, and also that Pin won't successfully attach to an application that is being debugged.
My suggestion is to start Pin with the -pause_tool knob, and then attach gdb to the process. This will make the application's ptrace call return what you want.
I hope i get what you want.
Intel PIN is NOT a debugger. It's more like a VM which on-the-fly instruments binary code (for x86/x64) and then executes this freshly instrumented code.
Because PIN is not opensource, it's internals are rather "secret" ;).
But its CLEARLY not a debugger.
If i understand you correctly you want some sort of test-suite which
runs your application twice, one time with a debugger attached and one time without?
Then you probably should use gdb.
Just start:
./a.out for the normal run
and e.g. (this one is a little hacky ;-) ) for the debugger-run:
Create a file mygdbscript (needs arguments to gdb like: gdb -x ./mygdbscript)
The content of this file is just:
# you probably dont want gdb to stop under ANY circumstances
# as this is an automatic check. So pass all signals to the application.
handle all nostop print pass
run
quit
Then run with gdb -x ./mygdbscript --args ./a.out
Hope this helps :)

tx6s usbotg device-tree changing on it's own

I have a tx6s-8035 SoC which we integrated into a custom board. We connected an Asix 88772B to the usbotg port and we need it to start in host mode.
We grounded the USBOTG_ID pin and we tought it will start in host mode. It didn't happen unfortunately.
I have investigated the issue and I see a strange behaviour... I wrote dr_mode = host as an extra property into the official device-tree. After that I modified the ci_hdrc_imx driver to print what it got in the device_node and it said "peripheral". I backtraced the problem and when the of_usb_get_dr_mode() function is being invoked the device-tree already contains dr_mode = peripheral.
Any ideas? I just can't imagine what happens there...
p.s.: I double-checked that I'm updating the device-tree in a proper manner.
I found the issue:
The u-boot overrides the 'dr_mode' property with it's 'usbotg' parameter so I had to change the environment variable in u-boot and it works since that.
Maybe it helps others too.

How to get a path from an inode on FreeBSD (ZFS and UFS)?

Windows (NtQueryObject), Linux (/proc/self/fd/x) and OS X (F_GETPATH) all have methods for retrieving the path of a currently open file descriptor. Supposedly so does FreeBSD via something like the following code:
size_t len;
int mib[4]={CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC, getpid()};
BOOST_AFIO_ERRHOS(sysctl(mib, 4, NULL, &len, NULL, 0));
std::vector<char> buffer(len*2);
BOOST_AFIO_ERRHOS(sysctl(mib, 4, buffer.data(), &len, NULL, 0));
for(char *p=buffer.data(); p<buffer.data()+len;)
{
struct kinfo_file *kif=(struct kinfo_file *) p;
if(kif->kf_fd==fd)
{
lock_guard<pathlock_t> g(pathlock);
_path=path::string_type(kif->kf_path);
return _path;
}
p+=kif->kf_structsize;
}
This irritatingly works for pretty much every kind of file descriptor except regular files which return a null path, at least in FreeBSD 10. I assume this is an oversight as from examining the kernel code it would seem trivial to return the path, though maybe there were performance reasons not to do so.
procstat uses the same API as the above, and therefore also too only returns paths for everything but regular files. Using statfs() I can at least get the path of the mount point for the file, but retrieving the path fragment between the mount point and the actual file is the problem.
So let me ask this question: Is it possible to ask UFS or ZFS to return a path fragment from an inode, maybe using some magic ioctl or sysctl, or even some utility library? The code in question doesn't need the path the file descriptor was opened with, it only needs some canonical path the file descriptor can currently be found at (this is to handle tracking third party file renames for proposed Boost.AFIO).
My thanks in advance for any help. FreeBSD is the only showstopper out of the major operating systems for this feature, and without it it makes writing filing system race safety detection code impossible :(
Edit: I found a discussion about getting ZFS to convert inodes to paths at http://comments.gmane.org/gmane.os.solaris.opensolaris.zfs/38277. Apparently there is a ZFS_IOC_OBJ_TO_PATH ioctl, but this is not a well trodden code path judging from google
It turns out that the fact that KERN_PROC_FILEDESC doesn't work is in fact a bug in the FreeBSD kernel. I've logged it at https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197695.
KERN_PROC_FILEDESC does work perfectly for directory file descriptors, including tracking renames and deletions. It imperfectly works for regular file descriptors, sometimes returning a path and then quite suddenly returning a null path, and then randomly later returning a path again. I think somewhere in the 10.x release something got broken somewhere :(
Hope that helps anyone else similarly stuck.

Linux: device appears in /dev but cannot be accessed

I have created a Linux device driver and can add it to the system (insmod, mknod). When I look in /dev I see it listed as camerax:
ls -l /dev/camerax
crw-r--r-- 1 root root 245, 0 Jun 27 17:19
Even so, I cannot access it. Whatever I do, I get an error.
For example:
int fd = open("/dev/camerax", O_RDONLY);
printf("%d [%s]\n", fd, strerror(errno));
Generates:
-1 [No such device or address]
I'm running as a super user. Any suggestions?
Your Module is not linked to the special file which you have mentioned so it is giving error.
If your module is successfully inserted verify in /proc/devices using cat command
cat /proc/devices.
file created using mknod in the path /dev/____ is just a refrence to your driver
The major and minor number should match with your inserted device.
I have solved the problem.
Instead of creating the major device number dynamically, as described in the documentation, I now set it explicitly to 61. Everything now works.
The only difference I can see between the working and non-working versions is the major number (and yes, I change anything that uses the device number so I am always using the appropriate one).
This adds one more bizarre feature of the system to my growing list.

svgalib : cant see anything

I had compiled some examples from svgalib, the console show :
Using EGA driver
svglib 1.4.3
Nothing more, its like its drawing somewhere but I cannot see it.
This could be a ver very noob question about svgalib, but also a configuration problem.
Also I check the virtual console that it says is drawing (if I run from X), running from console just stays there. I also put sleep in the code
example code :
include stdlib.h
include vga.h
int main(void)
{
vga_init();
vga_setmode(G320x200x256);
vga_setcolor(4);
vga_drawpixel(10, 10);
sleep(5);
vga_setmode(TEXT);
return EXIT_SUCCESS;
}
compile with
gcc -o tut tut.c -lvga
So do you have other SVGAlib applications working on your system? Such svgatest, which may be in a separate distribution package (svgalib-bin or similar).
Have you configured svgalib for your system? Common locate of the config file is /etc/vga/libvga.config and read man svgalib should give you more details.
I suspect that once you have SVGAlib working in general, the tutorial example program will work.
Install by software manager all svgalibrary.
Set the resolution at yours graphics screen
es : G1024x768x256
set color pixel white = 15
my linux mint (mate) 17.1 on hard disk work fine.
good luck !

Resources