u-boot driver model: using sandbox_defconfig, "demo hello 5" got error "Command 'demo' failed: Error -22" - u-boot

u-boot version: 2021.07-RC3
[Description]
Build and run u-boot:
make sandbox_defconfig
make
./u-boot -d u-boot.dtb
Type the following on the command-line:
=> demo hello 5
I Got the following Error:
Command 'demo' failed: Error -22
[Analysis]
Index 5 is the device named 'hexagon' defined in arch/sandbox/dts/sandbox.dtsi:
hexagon {
compatible = "demo-simple";
colour = "white";
sides = <6>;
};
device_probe will call of_to_plat, which finally call demo_parse_dt in drivers/demo/demo-uclass.c.
int demo_parse_dt(struct udevice *dev)
{
struct dm_demo_pdata *pdata = dev_get_plat(dev);
int dn = dev_of_offset(dev);
pdata->sides = fdtdec_get_int(gd->fdt_blob, dn, "sides", 0);
pdata->colour = fdt_getprop(gd->fdt_blob, dn, "colour", NULL);
if (!pdata->sides || !pdata->colour) {
debug("%s: Invalid device tree data\n", __func__);
return -EINVAL;
}
return 0;
}
Here, I got 0 for pdata->sides, and NULL for pdata->colour. Seem that fdtdec_get_int and fdt_getprop hadn't get the correct values from device tree.
I notice that dn here is in int type, but dev->node_.of_offset is in long type. So dn contains a truncated offset value. However, I'm not sure if the error I got is related to this.

I face similar issue too.
I follow your clues and edit like this. It seems working.
int demo_parse_dt(struct udevice *dev)
{
struct dm_demo_pdata *pdata = dev_get_plat(dev);
int dn = dev_of_offset(dev);
pdata->sides = dev_read_s32_default(dev, "sides", 0);
pdata->colour = dev_read_prop(dev, "colour", NULL);
if (!pdata->sides || !pdata->colour) {
printf("%s: Invalid device tree data\n", __func__);
return -EINVAL;
}
return 0;
}
I am quite new to u-boot. Anyone found better way, please correct me.

Related

Executable File IMAGE_OPTIONAL_HEADER ImageBase is 0

I've encountered a problem I am trying to figure out for a while now but I am unable to find anything about it, I am trying to get a mapped file image base from its optional header found in the PE header but the value in the ImageBase is 0?
The file I am trying to get this value from is a 64 bit executable (PE64), so what I am doing is I open the file with (CreateFileW function), then I map it using (CreateFileMappingW and MapViewOfFile functions), then I get the PE Header file with these functions:
IMAGE_DOS_HEADER* FileUtils_GetFileDOSHeader (void* Arg_FileViewMap) {
if (Arg_FileViewMap != NULL) {
return (IMAGE_DOS_HEADER*) Arg_FileViewMap;
}
return NULL;
}
IMAGE_NT_HEADERS* FileUtils_GetFilePEHeader (void* Arg_FileViewMap) {
if (Arg_FileViewMap != NULL) {
IMAGE_DOS_HEADER* Func_FileDOSHeader = FileUtils_GetFileDOSHeader(Arg_FileViewMap);
if (Func_FileDOSHeader != NULL) {
return (IMAGE_NT_HEADERS*) ((INT64) Func_FileDOSHeader + Func_FileDOSHeader->e_lfanew);
}
}
return NULL;
}
Then I use this function to get the optional header or do it directly, same result:
IMAGE_OPTIONAL_HEADER* FileUtils_GetFileOptionalHeader (void* Arg_FileViewMap) {
if (Arg_FileViewMap != NULL) {
IMAGE_NT_HEADERS* Arg_FilePEHeader = FileUtils_GetFilePEHeader(Arg_FileViewMap);
if (Arg_FilePEHeader != NULL) {
return (IMAGE_OPTIONAL_HEADER*) &Arg_FilePEHeader->OptionalHeader;
}
}
return NULL;
}
Then I try to get value and print it out so I would know that its not 0 like so:
wprintf(L"File image base: 0x%015X\n", FileUtils_GetFileOptionalHeader(Func_TargetFileViewMap)->ImageBase);
That is all! Once I compile this code for 64bit and run it, it prints out 0 but it should give me 0x00000010000000, so what is wrong here? The value does print out correctly, I made sure that the value is indeed 0 a lot of times.
Now things to note:
Some executables do give me the ImageBase value, but most of them give me 0 even though that is wrong, for example I open notepad and that gives me 0 but the value should be 0x00000010000000, and to show you that here is a screenshot of what CFF Explorer sees: (http://prntscr.com/) <- Click
It appears that all other values are correct except the ImageBase that is 0 for some reason, if I print out the EntryPoint then the value does match with what the CFF Explorer tells me.
I am using GCC (From MinGW-w64) compiler (C Programming Language) for this
I am not aware of any other invalid values in other headers, its just the ImageBase getting me frustrated.
A quick thing, if you also need to know what the function parameters for opening and mapping the file are then here they are:
HANDLE Func_TargetFile = CreateFileW((wchar_t*) & Func_ConsoleCommand, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE Func_TargetFileMapping = CreateFileMappingW(Func_TargetFile, NULL, PAGE_READWRITE, 0, 0, NULL);
void* Func_TargetFileViewMap = MapViewOfFile(Func_TargetFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
That is all, once again if you are confused of what my question is: Why does the IMAGE_OPTIONAL_HEADER ImageBase gives me a value of 0 even though all other values in the header seem to match what CFF Explorer shows me? - Thank you
PS: I will check consistently, if you need more information then comment below.
I have solved the mistery, it was in the GetFilePEHeader function! The printed out value is now: 0x000000005F5E100
The issue was with the casting, this line of code:
return (IMAGE_NT_HEADERS*) ((char*) (Func_FileDOSHeader) + Func_FileDOSHeader->e_lfanew);
Here is the fixed function:
IMAGE_NT_HEADERS* FileUtils_GetFilePEHeader (void* Arg_FileViewMap) {
if (Arg_FileViewMap != NULL) {
IMAGE_DOS_HEADER* Func_FileDOSHeader = FileUtils_GetFileDOSHeader(Arg_FileViewMap);
if (Func_FileDOSHeader != NULL) {
return (IMAGE_NT_HEADERS*) ((INT64) Func_FileDOSHeader + Func_FileDOSHeader->e_lfanew);
}
}
return NULL;
}
Thank you all for all of your help, this was quite a dumb issue. It took me 3 days to figure this out.

Disable pn53x_check_communication: Input / Output Error message

I'm using libnfc 1.7.1 compiled with c to read from a PN532 reader on a Raspberry Pi. The goal is to make a node for Node-RED that injects the UID of the scanned card or pass errors along about library or reader. I modified the example to give me the UID of a card as the only normal output. I can't have anything printed other than an error when the library can't be loaded, an error when the reader can't be connected, or the UID of the card. I changed the log level to 0 in /etc/nfc/libnfc.conf but my program is still printing "pn53x_check_communication: Input / Output Error" (unwanted) as well as "ERROR: Unable to open NFC device." (wanted) I can't find any way to disable the I/O error message. I looked in the library and found this that returns NFC_EIO which is the I/O error I'm getting, but can't find anywhere that it actually prints that. Short of modifying the library I can't find any way to disable this print. If there is nothing that can be done I can program my node to ignore this output but I would rather eliminate it. My code is below:
#include <stdlib.h>
#include <nfc/nfc.h>
static void
print_long(const uint8_t *pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos = 0; szPos < szBytes; szPos++) {
printf("%03lu", pbtData[szPos]);
}
printf("\n");
}
int
main(int argc, const char *argv[])
{
nfc_device *pnd;
nfc_target nt;
// Allocate only a pointer to nfc_context
nfc_context *context;
// Initialize libnfc and set the nfc_context
nfc_init(&context);
if (context == NULL) {
printf("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
// Open, using the first available NFC device which can be in order of selection:
// - default device specified using environment variable or
// - first specified device in libnfc.conf (/etc/nfc) or
// - first specified device in device-configuration directory (/etc/nfc/devices.d) or
// - first auto-detected (if feature is not disabled in libnfc.conf) device
pnd = nfc_open(context, NULL);
//Send error
if (pnd == NULL) {
printf("ERROR: %s\n", "Unable to open NFC device.");
exit(EXIT_FAILURE);
}
// Set opened NFC device to initiator mode
if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init");
exit(EXIT_FAILURE);
}
while(true){
// Poll for a ISO14443A (MIFARE) tag
const nfc_modulation nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
//Print decimal version of UID and wait until it's removed to scan again
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) > 0) {
print_long(nt.nti.nai.abtUid, nt.nti.nai.szUidLen);
while (0 == nfc_initiator_target_is_present(pnd, NULL)) {}
}
}
}

IIO device buffer always null

I am using an IMU sensor called LSM6DSL with the iio drivers. They work fine if I display the raw values with the command:
cat /sys/bus/iio/devices/iio:device0/in_accel_x_raw
Then I decided to use the libiio so I can read all these values from a C program :
struct iio_context *context = iio_create_local_context();
struct iio_device *device = iio_context_get_device(context, 1);
struct iio_channel *chan = iio_device_get_channel(device, 0);
iio_channel_enable(chan);
if (iio_channel_is_scan_element(chan) == true)
printf("OK\n");
struct iio_channel *chan2 = iio_device_get_channel(device, 1);
iio_channel_enable(chan2);
struct iio_buffer *buff = iio_device_create_buffer(device, 1, true);
if (buff == NULL)
{
printf("Error: %s\n", strerror(errno));
return (1);
}
And this is the result :
OK
Error: Device or resource busy
Am I missing something? Let me know if you need more informations.
I guess I found the answer, and I didn't pay attention to the effects of the ncurses library (sorry for not mentioning that I was using it).
I moved these functions before the initialization of ncurses and now the buffer is created successful.

pam_acct_mgmt seg faulting when Max Num of Days is < Num days of warning before expiration

I am writing a very simple PAM authentication function shown below.
int authenticate(char* user, char* pass)
{
int value = pam_start("passwd", user, &conv, &pamh);
if (value == PAM_SUCCESS)
{
reply = (struct pam_response*)malloc(sizeof(struct pam_response));
reply[0].resp = pass;
reply[0].resp_retcode = 0;
value = pam_authenticate(pamh, 0);
if (value == PAM_SUCCESS)
{
// This call is seg faulting.
value = pam_acct_mgmt(pamh, 0);
return value;
}
else
printf("Failed on Authentication\n");
}
}
pam_end(pamh, value);
return value;
}
conv is defined as the following:
int nullConv(int num_msg, const struct pam_message** msg, struct pam_response** resp,
void* appdata_ptr)
{
*resp = reply;
return PAM_SUCCESS;
}
static struct pam_conv conv = { nullConv, NULL };
This is a very simple function that works most of the time. I am working on a Linux box. When I mess with a user account, say bob and make his Maximum number of days between password change less than Number of days of warning before password expires by using...
#chage -M 28 bob
#chage -W 29 bob
The application seg faults at the call to pam_acct_mgmt. If I change it so that the Maximum number is greater than the Number before warning, my application runs as expected.
#chage -M 30 bob. Now I'm fine and the user can log in.
I found the following post:
https://serverfault.com/questions/249671/switch-on-pam-debugging-to-syslog
and followed the accepted solution. The results I found in my /var/log/debug.log file stated pam_tally(system-auth:auth): unknown option: reset
The line in my PAM /etc/pam.d/system-auth file it was referring to was a line that read
account required pam_tally.so reset
When I removed the reset option, everything works fine.
By the way pam_vsyslog has a serious bug. It was segfaulting on a simple strcmp.

Getting parent for kobject_add

Is there any simple method for getting parent to use in kobject_add function? I want to put the file in /sys/module/mymodule/parameters. I've got already working parameter, but I create it in wrong directory. I've found that there is module_subsys in module.h, but I have no idea how to use it.
It's my code for init function:
static int __init init_hello(void)
{
subsystem_register(&module_subsys);
struct my_attr *a;
Major = misc_register(&mydevice);
mykobj = kzalloc(sizeof(*mykobj), GFP_KERNEL);
if (mykobj) {
kobject_init(mykobj, &mytype);
kobj_set_kset_s(mykobj, module_subsys);
if (kobject_add(mykobj, NULL, "%s", "sysfs_example")) {
printk("Sysfs creation failed\n");
kobject_put(mykobj);
mykobj = NULL;
return -1;
}
}
a = container_of(&(my_first.attr), struct my_attr, attr);
msg_Ptr = kzalloc(a->value, GFP_KERNEL);
bytesindev=0;
if(Major) {
printk(KERN_ALERT "Rejestrowanie urządzenia nie powiodło się\n");
return Major;
}
return SUCCESS;
}
Never tried it myself, but &THIS_MODULE->mkobj.kobj looks appropriate.
I didn't see any kernel code that uses kobject_add directly with this, so perhaps it isn't the right way.
If you've registered a device driver, then &dev->kobj looks like a good way.

Resources