Getting kernel image size in uboot - u-boot

I'm attempting to create custom functionality for kernel authenticity validation on my uboot on an armv8 based platform. The method in which context I'm working in is boot_jump_linux, seen in uboot source here, around line #50.
The parameter (bootm_headers_t *images) includes the information on where the kernel is loaded in memory. With that I've been able to iterate over the specific memory area and otherwise I have everything I need, but I'm missing the information on the length of kernel data. The struct under *images references multiple relevant data structures found here:
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
typedef struct image_info {
ulong start, end; /* start/end of blob */
ulong image_start, image_len; /* start of image within blob, len of image */
ulong load; /* load addr for the image */
uint8_t comp, type, os; /* compression, type of image, os type */
uint8_t arch; /* CPU architecture */
} image_info_t;
All values in the above image_header have a similar constant value, including timestamp, so that leads me to believe that they haven't been initialized. Additionally the image_info struct contains values of 0 all length related fields.
Is there some other way of determining the kernel size, or should I just fall back on to a predetermined default value?

Related

Cannot run a large structure filled with arrays win C

I'm building a SAE J1939 library for embedded systems such as Arduino, STM32, AVR etc.
But I have an issue I don't understand. First when I compile. No error!
But when I run, I get this assembler error. It's all about the J1939 struct.
Why does this happen? Is the heap to small?
Can't find a source file at
"C:\mingw810\i686-810-posix-dwarf-rt_v6-rev0\build\gcc-8.1.0\i686-w64-mingw32\libgcc/../../../../../src/gcc-8.1.0/libgcc/config/i386/cygwin.S"
Locate the file or edit the source lookup path to include its
location.
Run this code below to reproduce the error:
#include <stdio.h>
#include <stdlib.h>
#include "stdint.h"
/* PGN: 0x00E800 - Storing the Acknowledgement from the reading process */
struct Acknowledgement {
uint8_t control_byte; /* This indicates the status of the requested information about PGN: */
uint8_t group_function_value; /* The function code that specify cause of the control byte e.g time out or aborted */
uint8_t address; /* Address from the ECU where the acknowledgement is comming from */
uint32_t PGN_of_requested_info; /* Information request about the PGN */
};
/* PGN: 0x00EC00 - Storing the Transport Protocol Connection Management from the reading process */
struct TP_CM {
uint8_t control_byte; /* What type of message are we going to send */
uint16_t total_message_size; /* Total bytes our complete message includes */
uint8_t number_of_packages; /* How many times we are going to send packages via TP_DT */
uint32_t PGN_of_the_packeted_message; /* Our message is going to activate a PGN */
};
/* PGN: 0x00EB00 - Storing the Transport Protocol Data Transfer from the reading process */
struct TP_DT {
uint8_t sequence_number; /* When this sequence number is the same as number_of_packages from TP_CM, then we have our complete message */
uint8_t data[7][256]; /* Package data of 2D array where first index is data0 -> data6 and second index is sequence of the data */
};
/* PGN: 0x00EE00 - Storing the Address claimed from the reading process */
struct Name {
uint32_t identity_number; /* Specify the ECU serial ID - 0 to 2097151 */
uint16_t manufacturer_code; /* Specify the ECU manufacturer code - 0 to 2047 */
uint8_t function_instance; /* Specify the ECU function number - 0 to 31 */
uint8_t ECU_instance; /* Specify the ECU number - 0 to 7 */
uint8_t function; /* Specify the ECU function - 0 to 255 */
uint8_t vehicle_system; /* Specify the type of vehicle where ECU is located - 0 to 127 */
uint8_t arbitrary_address_capable; /* Specify if the ECU have right to change address if addresses conflicts - 0 to 1 */
uint8_t industry_group; /* Specify the group where this ECU is located - 0 to 7 */
uint8_t vehicle_system_instance; /* Specify the vehicle system number - 0 to 15 */
};
/* PGN: 0x00FECA - Storing the DM1 Active diagnostic trouble codes from the reading process */
struct DM1 {
/* These are SAE lamps can have 1 = ON and 0 = OFF */
uint8_t SAE_lamp_status_malfunction_indicator;
uint8_t SAE_lamp_status_red_stop;
uint8_t SAE_lamp_status_amber_warning;
uint8_t SAE_lamp_status_protect_lamp;
uint8_t SAE_flash_lamp_malfunction_indicator;
uint8_t SAE_flash_lamp_red_stop;
uint8_t SAE_flash_lamp_amber_warning;
uint8_t SAE_flash_lamp_protect_lamp;
/* Fault location, problem and codes */
uint32_t SPN; /* Location where the fault exist */
uint8_t FMI; /* Type of problem */
uint8_t SPN_conversion_method; /* If SPN_conversion_method = 1 that means Diagnostics Trouble Code are aligned using a newer conversion method. If SPN_conversion_method = 0 means one of the three Diagnostics Trouble Code conversion methods is used and ECU manufacture shall know which of the three methods is used */
uint8_t occurence_count; /* This tells how many times failure has occurred. Every time fault goes from inactive to active, the occurence_count is incremented by 1. If fault becomes active for more than 126 times the occurence_count remains 126 */
};
/* PGN: 0x00D800 - Storing the DM15 response from the reading process */
struct DM15 {
uint16_t number_of_allowed_bytes; /* How many bytes we are allowed to write or read to */
uint8_t status; /* Status of the response */
uint32_t EDC_parameter; /* Status code */
uint8_t EDCP_extention; /* Describe how we should interpret the EDC parameter as a status code or error code */
uint16_t seed; /* Response of the key if we need more key or no key at all */
};
/* PGN: 0x00D700 - Storing the DM16 binary data transfer from the reading process */
struct DM16 {
uint8_t number_of_occurences; /* How many bytes we have sent */
uint8_t raw_binary_data[256]; /* Here we store the bytes */
};
/* Storing the error codes from the reading process */
struct DM {
uint8_t errors_dm1_active; /* How many errors of DM1 we have right now */
uint8_t errors_dm2_active; /* How many errors of DM2 is active */
struct DM1 dm1[256]; /* dm1 can contains multiple error messages */
struct DM1 dm2[256]; /* dm2 contains previously active errors from dm1 */
struct DM15 dm15; /* dm15 is the memory access response from DM14 memory request */
struct DM16 dm16; /* dm16 is the binary data transfer after DM15 memory response (if it was proceeded) */
/* Add more DM here */
};
/* PGN: 0x00FEDA - Storing the software identification from the reading process */
struct Software_identification {
uint8_t length_of_each_identification; /* The length of each identification - Not part of J1939 standard */
uint8_t number_of_fields; /* How many numbers contains in the identifications array */
uint8_t identifications[256]; /* This can be for example ASCII */
};
/* PGN: 0x00FDC5 - Storing the ECU identification from the reading process */
struct ECU_identification {
uint8_t length_of_each_field; /* The real length of the fields - Not part of J1939 standard */
uint8_t ecu_part_number[256]; /* ASCII field */
uint8_t ecu_serial_number[256]; /* ASCII field */
uint8_t ecu_location[256]; /* ASCII field */
uint8_t ecu_type[256]; /* ASCII field */
uint8_t ecu_manufacturer[256]; /* ASCII field */
uint8_t ecu_hardware_version[256]; /* ASCII field */
};
/* PGN: 0x00FEEB - Storing the component identification from the reading process */
struct Component_identification {
uint8_t length_of_each_field; /* The real length of the fields - Not part of J1939 standard */
uint8_t component_product_date[256]; /* ASCII field */
uint8_t component_model_name[256]; /* ASCII field */
uint8_t component_serial_number[256]; /* ASCII field */
uint8_t component_unit_name[256]; /* ASCII field */
};
/* PGN: 0x00FE30 (65072) to 0x00FE3F (65087) */
struct Auxiliary_valve_command {
uint8_t standard_flow; /* Command flow */
uint8_t fail_safe_mode; /* If the user want the valve to go to neutral */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
};
/* PGN: 0x00FE10 (65040) to 0x00FE1F (65055) */
struct Auxiliary_valve_estimated_flow {
uint8_t extend_estimated_flow_standard; /* A measurement */
uint8_t retract_estimated_flow_standard; /* A measurement */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint8_t fail_safe_mode; /* The mode if we are going to use fail safe mode or not */
uint8_t limit; /* Enter a limit code */
};
/* PGN: 0x00C400 (50176) */
struct General_purpose_valve_command {
uint8_t standard_flow; /* Command flow */
uint8_t fail_safe_mode; /* If the user want the valve to go to neutral */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint16_t extended_flow; /* Another command flow */
};
/* PGN: 0x00C600 (50688) */
struct General_purpose_valve_estimated_flow {
uint8_t extend_estimated_flow_standard; /* A measurement */
uint8_t retract_estimated_flow_standard; /* A measurement */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint8_t fail_safe_mode; /* The mode if we are going to use fail safe mode or not */
uint8_t limit; /* Enter a limit code */
uint16_t extend_estimated_flow_extended; /* A measurement */
uint16_t retract_estimated_flow_extended; /* A measurement */
};
struct Auxiliary_valve_measured_position {
uint16_t measured_position_procent; /* Procent position */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint16_t measured_position_micrometer; /* Micrometer position */
};
typedef struct {
/* For information about other ECU */
uint8_t number_of_ECU;
uint8_t number_of_cannot_claim_address;
uint8_t ECU_address[256];
struct Acknowledgement acknowledgement[256];
struct TP_CM tp_cm[256];
struct TP_DT tp_dt[256];
struct Name name[256];
struct DM dm[256];
struct Software_identification software_identification[256];
struct ECU_identification ecu_identification[256];
struct Component_identification component_identification[256];
struct Auxiliary_valve_estimated_flow auxiliary_valve_estimated_flow[256][16];
struct General_purpose_valve_estimated_flow general_purpose_valve_estimated_flow[256];
struct Auxiliary_valve_measured_position auxiliary_valve_measured_position[256][16];
/* For information about this ECU */
struct Name this_name;
uint8_t this_ECU_address;
struct DM this_dm;
struct Software_identification this_software_identification;
struct ECU_identification this_ecu_identification;
struct Component_identification this_component_identification;
struct Auxiliary_valve_command this_auxiliary_valve_command[16];
struct General_purpose_valve_command this_general_purpose_valve_command;
} J1939;
int main(void) {
J1939 j1939;
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
return EXIT_SUCCESS;
}
This information is not a compilation error. You execute a debugger and try to debug a part of program without located sources. This could happen if your program stops in a compiled library. Then we can use a assembler instruction only. As mentioned above try to set breakpoint into your main() funcion.

Get USB Host Controller parameters in Linux programmatically

I need to get some parameters related to USB Host Controllers in Linux. I made a lot of searches in the internet and the only way that I found is using pciutils lib. Each PCI device is in the structure pci_dev in pci.h:
struct pci_dev {
struct pci_dev *next; /* Next device in the chain */
u16 domain_16; /* 16-bit version of the PCI domain for backward compatibility */
/* 0xffff if the real domain doesn't fit in 16 bits */
u8 bus, dev, func; /* Bus inside domain, device and function */
/* These fields are set by pci_fill_info() */
int known_fields; /* Set of info fields already known */
u16 vendor_id, device_id; /* Identity of the device */
u16 device_class; /* PCI device class */
int irq; /* IRQ number */
pciaddr_t base_addr[6]; /* Base addresses including flags in lower bits */
pciaddr_t size[6]; /* Region sizes */
pciaddr_t rom_base_addr; /* Expansion ROM base address */
pciaddr_t rom_size; /* Expansion ROM size */
struct pci_cap *first_cap; /* List of capabilities */
char *phy_slot; /* Physical slot */
char *module_alias; /* Linux kernel module alias */
char *label; /* Device name as exported by BIOS */
int numa_node; /* NUMA node */
pciaddr_t flags[6]; /* PCI_IORESOURCE_* flags for regions */
pciaddr_t rom_flags; /* PCI_IORESOURCE_* flags for expansion ROM */
int domain; /* PCI domain (host bridge) */
/* Fields used internally */
struct pci_access *access;
struct pci_methods *methods;
u8 *cache; /* Cached config registers */
int cache_len;
int hdrtype; /* Cached low 7 bits of header type, -1 if unknown */
void *aux; /* Auxiliary data */
struct pci_property *properties; /* A linked list of extra properties */
struct pci_cap *last_cap; /* Last capability in the list */
};
I found also that I can parse pci devices as following:
struct pci_access *pacc1;
struct pci_dev *dev1;
unsigned int c1;
char namebuf1[1024], *name1;
pacc1 = pci_alloc(); /* Get the pci_access structure */
/* Set all options you want -- here we stick with the defaults */
pci_init(pacc1); /* Initialize the PCI library */
pci_scan_bus(pacc1); /* We want to get the list of devices */
for (dev1=pacc1->devices; dev1; dev1=dev1->next) /* Iterate over all devices */
{
pci_fill_info(dev1, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); /* Fill in header info we need */
c1 = pci_read_byte(dev1, PCI_INTERRUPT_PIN); /* Read config register directly */
printf("%04x:%02x:%02x.%d vendor=%04x device=%04x class=%04x irq=%d (pin %d) base0=%lx",
dev1->domain, dev1->bus, dev1->dev, dev1->func, dev1->vendor_id, dev1->device_id,
dev1->device_class, dev1->irq, c1, (long) dev1->base_addr[0]);
/* Look up and print the full name of the device */
name1 = pci_lookup_name(pacc, namebuf1, sizeof(namebuf1), PCI_LOOKUP_DEVICE, dev1->vendor_id, dev1->device_id);
printf(" ***************** %d: (%s)\n", dev1->dev, name1);
}
pci_cleanup(pacc1); /* Close everything */
Is there a way to check in the loop if the corresponding pci device corresponds to an USB Host Controller? Or is there a simpler way to get USB Host Controller infos?

Time from startup in linux kernel

I would like to retrieve time passed since kernel's start (in kernel space). It should be the match the time printk(); is using (For example:[ 5.832000] message ).
jiffies provide different time, so I am not sure it fits me.
How can I achieve this?
What about using get_monotonic_boottime? jiffies are initialized to 5 minutes before boot to ensure that there is an overflow soon after booting and detect bugs.
printk implementation lies in kernel/printk/printk.c souce file.
Here it uses following structure before writing log into buffer which we see in console.
struct printk_log {
u64 ts_nsec; /* timestamp in nanoseconds */
u16 len; /* length of entire record */
u16 text_len; /* length of text buffer */
u16 dict_len; /* length of dictionary buffer */
u8 facility; /* syslog facility */
u8 flags:5; /* internal record flags */
u8 level:3; /* syslog level */
};
ts_nsec -> This parameter is set by function "local_clock" which in turn calls "Sched_clock" [ defined in /kernel/sched/clock.c ].
unsigned long long __weak sched_clock(void)
{
return (unsigned long long)(jiffies - INITIAL_JIFFIES)
* (NSEC_PER_SEC / HZ);
}
#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
i think this will give you more insight about the printk logging

error: dereferencing pointer to incomplete type when accessing struct

I am not sure why this is happening. I am doing an assignment and the code somehow does not compile.
This is the header file
#include <stdint.h>
typedef struct
{
uint8_t jump_code[3]; /* Ignore this */
char oemname[8]; /* Might as well ignore this one too */
uint8_t ssize[2]; /* Sector size in bytes */
uint8_t csize; /* Cluster size in sectors */
uint8_t reserved[2]; /* Number of reserved sectors for boot sectors */
uint8_t numfat; /* Number of FATs */
uint8_t numroot[2]; /* Number of Root directory entries */
uint8_t sectors16[2]; /* number of sectors in the file system */
uint8_t media[1]; /* Media descriptor type */
uint8_t sectperfat16[2];/* Number of sectors per FAT */
uint8_t sectpertrack[2];/* Number of sectors per track */
uint8_t heads[2]; /* Number of heads */
uint8_t prevsect[2]; /* Number of sectors before FS partition */
uint8_t ignore[482]; /* Ignore these */
} boot_sect_t;
This is the part that gives the error:
struct boot_sect_t* boot = malloc(sizeof(boot_sect_t));
boot->ssize[0] = buffer[11]; //error here
boot->ssize[1] = buffer[12]; //error here
The error is:
error: dereferencing pointer to incomplete type when accessing struct
you need to change
struct boot_sect_t* boot = malloc(sizeof(boot_sect_t));
to
boot_sect_t* boot = malloc(sizeof(boot_sect_t));
boot_sect_t is already a typedef. no need to write struct boot_sect_t.

pcap datalink LINUX_SLL

I'm trying to write a simple packet sniffer using libpcap. The first thing i'm trying to do when i capture a packet is to recognise the datalink protocol used and find the size of the header for that protocol in order to find the ip packet. The problem is that sometimes libpcap returns as datalink layer protocol the LINUX_SLL which is described as "Linux cooked" does anyone know the format of the headers for that protocol? or at least the size of the header.
Thanks a lot
Giorgos
Or check the new tcpdump.org "link-layer header types" page for descriptions of the link-layer types.
I think this will solve your problem for good:
http://wiki.wireshark.org/SLL
Better yet, use Wireshark to read the pcap and it will show you the field types and their size.
/*
* A DLT_LINUX_SLL fake link-layer header.
*/
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */
struct sll_header {
uint16_t sll_pkttype; /* packet type */
uint16_t sll_hatype; /* link-layer address type */
uint16_t sll_halen; /* link-layer address length */
uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
uint16_t sll_protocol; /* protocol */
};
/*
* A DLT_LINUX_SLL2 fake link-layer header.
*/
#define SLL2_HDR_LEN 20 /* total header length */
struct sll2_header {
uint16_t sll2_protocol; /* protocol */
uint16_t sll2_reserved_mbz; /* reserved - must be zero */
uint32_t sll2_if_index; /* 1-based interface index */
uint16_t sll2_hatype; /* link-layer address type */
uint8_t sll2_pkttype; /* packet type */
uint8_t sll2_halen; /* link-layer address length */
uint8_t sll2_addr[SLL_ADDRLEN]; /* link-layer address */
};

Resources