U-boot device management directory 1. Initial device linked list, initial device, and registered Device
1.1 devices_init Function
1.2 Definitions of the devices Structure
1.3 drv_system_init Function
Ii. device registration
2.1 device_register (device_t * Dev)
2.2 device_deregister (char * devname)
3. device search U-boot creates a device linked list through the devices_init function, initializes the device in the devices_init function, and adds the device to the device linked list. U-boot uses the devices_t struct to manage devices. The device linked list is also the linked list of the devices_t struct. Initialize the device through the i2c_init, drv_ LCD _init, drv_video_init, functions, drv_logbuff_init, drv_system_init, modules, modules, and drv_nc_init functions (whether these functions are executed depends on the macro), and register the device through the device_reg. I. Initial device linked list, initial device, and registered Device
In the second stage, U-boot creates a device linked list through the devices_init function, initializes the device, and registers it to the device linked list. In the common/devices. c file, the corresponding header file is nclude/devices. h.
1.1 devices_init Function
Int devices_init (void) {# ifndef config_arm/* already relocated for current arm implementation */ulong relocation_offset = Gd-> reloc_off; int I; /* relocate device name pointers */for (I = 0; I <(sizeof (stdio_names)/sizeof (char *); ++ I) {stdio_names [I] = (char *) (ulong) stdio_names [I]) + relocation_offset );} # endif/* initialize the list */devlist = listcreate (sizeof (device_t); // create a device list if (de Vlist = NULL) {eputs ("Cannot initialize the list of devices! \ N "); Return-1 ;}# if defined (config_hard_i2c) | defined (config_soft_i2c) i2c_init (cfg_i2c_speed, cfg_i2c_slave); // initialize the I2C interface, i2C is not registered to devlist # endif # ifdef config_lcddrv_ LCD _init (); # endif # If defined (config_video) | defined (config_cfb_console) drv_video_init (); # endif # ifdef config_keyboarddrv_keyboard_init (); # endif # ifdef config_logbufferdrv_logbuff_init (); # endifdrv_system_init (); // a serial device is defined here, and register it in devlist # ifdef config_serial_multiserial_devices_init (); # endif # ifdef prepare (); # endif # ifdef config_netconsoledrv_nc_init (); # endifreturn (0 );}
After devices_init (), devlist is created, but only one serial device is registered.
1.2 Definitions of the devices Structure
/* Device information */typedef struct {intflags;/* Device flags: input/output/system */intext;/* supported extensions */charname [16]; /* device name * // * General functions Start and Stop Functions */INT (* Start) (void);/* to start the device */INT (* stop) (void);/* to stop the device * // * output functions output function */void (* putc) (const char C ); /* To put a char */void (* puts) (const char * s);/* To put a string (accelerator) * // * Input Functions Input Function */INT (* tstc) (void);/* to test if a char is ready... */INT (* GETC) (void);/* to get that char * // * Other functions */void * priv;/* Private extensions */} device_t;
1.3 drv_system_init Function
The drv_system_init function initializes a serial device. The source code is as follows:
Static void drv_system_init (void) {device_t dev; // defines a struct memset (& Dev, 0, sizeof (Dev )); // allocate the memory strcpy (Dev. name, "serial"); // name Dev. flags = dev_flags_output | dev_flags_input | dev_flags_system; # ifdef config_serial_software_kerberodev.putc = serial_buffered_putc; Dev. puts = serial_buffered_puts; Dev. GETC = serial_buffered_getc; Dev. tstc = serial_buffered_tstc; # elsedev. putc = serial_putc; Dev. puts = serial_puts; Dev. GETC = serial_getc; Dev. tstc = serial_tstc; # endifdevice_register (& Dev); // register the function # ifdef pai_device_nulldevmemset (& Dev, 0, sizeof (Dev); strcpy (Dev. name, "nulldev"); Dev. flags = dev_flags_output | dev_flags_input | dev_flags_system; Dev. putc = nulldev_putc; Dev. puts = nulldev_puts; Dev. GETC = nulldev_input; Dev. tstc = nulldev_input; device_register (& Dev); # endif}
Ii. device registration
There is a device registration function. One parameter is the devces struct, And the other parameter is the device name.
2.1 device_register (device_t * Dev)
Register the device and add the struct to the end of devlist. the source code of the device_register function is as follows:
int device_register (device_t * dev){ListInsertItem (devlist, dev, LIST_END);return 0;}
/*******************************//* * returns 1 if the item is inserted, returns 0 if out of memory or * bad arguments were passed. */int ListInsertItem (list_t list, void *ptrToItem, int itemPosition){return ListInsertItems (list, ptrToItem, itemPosition, 1);}/*******************************/int ListInsertItems (list_t list, void *ptrToItems, int firstItemPosition, int numItemsToInsert){int numItems = (*list)->numItems;if (firstItemPosition == numItems + 1)firstItemPosition = LIST_END;else if (firstItemPosition > numItems)return 0;if ((*list)->numItems >= (*list)->listSize) {if (!ExpandListSpace (list, -numItemsToInsert))return 0;}if (firstItemPosition == LIST_START) {if (numItems == 0) {/* special case for empty list */firstItemPosition = LIST_END;} else {firstItemPosition = 1;}}if (firstItemPosition == LIST_END) {/* add at the end of the list */if (ptrToItems)memcpy (ITEMPTR (list, numItems), ptrToItems,(*list)->itemSize * numItemsToInsert);elsememset (ITEMPTR (list, numItems), 0,(*list)->itemSize * numItemsToInsert);(*list)->numItems += numItemsToInsert;} else {/* move part of list up to make room for new item */memmove (ITEMPTR (list, firstItemPosition - 1 + numItemsToInsert), ITEMPTR (list, firstItemPosition - 1), (numItems + 1 - firstItemPosition) * (*list)->itemSize);if (ptrToItems)memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems, (*list)->itemSize * numItemsToInsert);elsememset (ITEMPTR (list, firstItemPosition - 1), 0,(*list)->itemSize * numItemsToInsert);(*list)->numItems += numItemsToInsert;}return 1;}
2.2 device_deregister (char * devname)
int device_deregister(char *devname){int i,l,dev_index;device_t *dev = NULL;char temp_names[3][8];dev_index=-1;for (i=1; i<=ListNumItems(devlist); i++) {dev = ListGetPtrToItem (devlist, i);if(strcmp(dev->name,devname)==0) {dev_index=i;break;}}if(dev_index<0) /* device not found */return 0;/* get stdio devices (ListRemoveItem changes the dev list) */for (l=0 ; l< MAX_FILES; l++) {if (stdio_devices[l] == dev) {/* Device is assigned -> report error */return -1;}memcpy (&temp_names[l][0],stdio_devices[l]->name,sizeof(stdio_devices[l]->name));}ListRemoveItem(devlist,NULL,dev_index);/* reassign Device list */for (i=1; i<=ListNumItems(devlist); i++) {dev = ListGetPtrToItem (devlist, i);for (l=0 ; l< MAX_FILES; l++) {if(strcmp(dev->name,temp_names[l])==0) {stdio_devices[l] = dev;}}}return 0;}
3. device search
/* search a device */device_t *search_device (int flags, char *name){int i, items;device_t *dev = NULL;items = ListNumItems (devlist);if (name == NULL)return dev;for (i = 1; i <= items; i++) {dev = ListGetPtrToItem (devlist, i);if ((dev->flags & flags) && (strcmp (name, dev->name) == 0)) {break;}}return dev;}