Forum Discussion
Altera_Forum
Honored Contributor
13 years agoHey guys,
my cfi-flash is now working again :) I dont know why flashcp froze my system. I simply made a new kernel-configuration and now it works perfect. I guess I had messed up my config somewhere. Nevertheless accessing the otp-register from my cfi-flash was still causing a kernel-panic, Null Pointer reference in particular. I looked through the code and I stumbled on something. When I'm calling ioctl with OTPSELECT to change the mode, the function otp_select_filemode is called in mtdchar.c. There is a call to another function:
/*
* Make a fake call to mtd_read_fact_prot_reg() to check if OTP
* operations are supported.
*/
if (mtd_read_fact_prot_reg(mtd, -1, -1, &retlen, NULL) == -EOPNOTSUP P)
return -EOPNOTSUPP;
I dont know if its really a bug, but thats the cause of my kernel-panic. the 3rd parameter is len with type size_t. size_t is defined to be __kernel_size_t which is defined as unsigned long. So this would cause an overflow of len. In read_fact_prot_reg() is another call to the function cfi_intelext_otp_walk, which does mostly all the work except the actual read from the otp-register. This does do_otp_read (action points to that function). The code-lines:
while (len > 0) {
/* flash geometry fixup */
data_offset = reg_prot_offset + 1;
data_offset *= cfi->interleave * cfi->device_type;
reg_prot_offset *= cfi->interleave * cfi->device_type;
reg_fact_size *= cfi->interleave;
reg_user_size *= cfi->interleave;
if (user_regs) {
groups = reg_user_groups;
groupsize = reg_user_size;
/* skip over factory reg area */
groupno = reg_fact_groups;
data_offset += reg_fact_groups * reg_fact_size;
} else {
groups = reg_fact_groups;
groupsize = reg_fact_size;
groupno = 0;
}
while (len > 0 && groups > 0) {
if (!action) {
} else if (from >= groupsize) {
from -= groupsize;
data_offset += groupsize;
} else {
int size = groupsize;
data_offset += from;
size -= from;
from = 0;
if (size > len)
size = len;
ret = action(map, chip, data_offset,
buf, size, reg_prot_offset,
groupno, groupsize);
if (ret < 0)
return ret;
buf += size;
len -= size;
*retlen += size;
data_offset += size;
}
groupno++;
groups--;
}
well, len is positive, groups will be 1. from is actually -1, so else. And there is a call action() with our buf which is NULL. In there the function tries to copy data to that location -> kernel panic I solved this problem changing the 3rd parameter -1 to 0. I guess this was the idea afterall, that the function just checks if there are otp-register and not trying to read them. Maybe I wrote too much here, but now you guys can easily track down this one, if its really a bug. I guess it is, correct me if I'm wrong =) And my usb is still not working properly, so if anybody knows something there, i would appreciate it. kind regards, Tobias Biehl