mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	Without the units these numbers are confusing. Add a comment about the unit being 'bytes' and mention 'buildman' as the source. Suggested-by: Lukasz Majewski <lukma@denx.de> Signed-off-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			252 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			252 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
Logging in U-Boot
 | 
						|
=================
 | 
						|
 | 
						|
Introduction
 | 
						|
------------
 | 
						|
 | 
						|
U-Boot's internal operation involves many different steps and actions. From
 | 
						|
setting up the board to displaying a start-up screen to loading an Operating
 | 
						|
System, there are many component parts each with many actions.
 | 
						|
 | 
						|
Most of the time this internal detail is not useful. Displaying it on the
 | 
						|
console would delay booting (U-Boot's primary purpose) and confuse users.
 | 
						|
 | 
						|
But for digging into what is happening in a particular area, or for debugging
 | 
						|
a problem it is often useful to see what U-Boot is doing in more detail than
 | 
						|
is visible from the basic console output.
 | 
						|
 | 
						|
U-Boot's logging feature aims to satisfy this goal for both users and
 | 
						|
developers.
 | 
						|
 | 
						|
 | 
						|
Logging levels
 | 
						|
--------------
 | 
						|
 | 
						|
There are a number logging levels available, in increasing order of verbosity:
 | 
						|
 | 
						|
   LOGL_EMERG	- Printed before U-Boot halts
 | 
						|
   LOGL_ALERT	- Indicates action must be taken immediate or U-Boot will crash
 | 
						|
   LOGL_CRIT	- Indicates a critical error that will cause boot failure
 | 
						|
   LOGL_ERR	- Indicates an error that may cause boot failure
 | 
						|
   LOGL_WARNING	- Warning about an unexpected condition
 | 
						|
   LOGL_NOTE	- Important information about progress
 | 
						|
   LOGL_INFO	- Information about normal boot progress
 | 
						|
   LOGL_DEBUG	- Debug information (useful for debugging a driver or subsystem)
 | 
						|
   LOGL_DEBUG_CONTENT	- Debug message showing full message content
 | 
						|
   LOGL_DEBUG_IO	- Debug message showing hardware I/O access
 | 
						|
 | 
						|
 | 
						|
Logging category
 | 
						|
----------------
 | 
						|
 | 
						|
Logging can come from a wide variety of places within U-Boot. Each log message
 | 
						|
has a category which is intended to allow messages to be filtered according to
 | 
						|
their source.
 | 
						|
 | 
						|
The following main categories are defined:
 | 
						|
 | 
						|
   LOGC_NONE	- Unknown category (e.g. a debug() statement)
 | 
						|
   UCLASS_...	- Related to a particular uclass (e.g. UCLASS_USB)
 | 
						|
   LOGC_ARCH	- Related to architecture-specific code
 | 
						|
   LOGC_BOARD	- Related to board-specific code
 | 
						|
   LOGC_CORE	- Related to core driver-model support
 | 
						|
   LOGC_DT	- Related to device tree control
 | 
						|
   LOGC_EFI	- Related to EFI implementation
 | 
						|
 | 
						|
 | 
						|
Enabling logging
 | 
						|
----------------
 | 
						|
 | 
						|
The following options are used to enable logging at compile time:
 | 
						|
 | 
						|
   CONFIG_LOG		- Enables the logging system
 | 
						|
   CONFIG_MAX_LOG_LEVEL - Max log level to build (anything higher is compiled
 | 
						|
				out)
 | 
						|
   CONFIG_LOG_CONSOLE	- Enable writing log records to the console
 | 
						|
 | 
						|
If CONFIG_LOG is not set, then no logging will be available.
 | 
						|
 | 
						|
The above have SPL versions also, e.g. CONFIG_SPL_MAX_LOG_LEVEL.
 | 
						|
 | 
						|
 | 
						|
Log commands
 | 
						|
------------
 | 
						|
 | 
						|
The 'log' command provides access to several features:
 | 
						|
 | 
						|
   level - access the default log level
 | 
						|
   format - access the console log format
 | 
						|
   rec - output a log record
 | 
						|
   test - run tests
 | 
						|
 | 
						|
Type 'help log' for details.
 | 
						|
 | 
						|
 | 
						|
Using DEBUG
 | 
						|
-----------
 | 
						|
 | 
						|
U-Boot has traditionally used a #define called DEBUG to enable debugging on a
 | 
						|
file-by-file basis. The debug() macro compiles to a printf() statement if
 | 
						|
DEBUG is enabled, and an empty statement if not.
 | 
						|
 | 
						|
With logging enabled, debug() statements are interpreted as logging output
 | 
						|
with a level of LOGL_DEBUG and a category of LOGC_NONE.
 | 
						|
 | 
						|
The logging facilities are intended to replace DEBUG, but if DEBUG is defined
 | 
						|
at the top of a file, then it takes precedence. This means that debug()
 | 
						|
statements will result in output to the console and this output will not be
 | 
						|
logged.
 | 
						|
 | 
						|
 | 
						|
Logging destinations
 | 
						|
--------------------
 | 
						|
 | 
						|
If logging information goes nowhere then it serves no purpose. U-Boot provides
 | 
						|
several possible determinations for logging information, all of which can be
 | 
						|
enabled or disabled independently:
 | 
						|
 | 
						|
   console - goes to stdout
 | 
						|
 | 
						|
 | 
						|
Log format
 | 
						|
----------
 | 
						|
 | 
						|
You can control the log format using the 'log format' command. The basic
 | 
						|
format is:
 | 
						|
 | 
						|
   LEVEL.category,file.c:123-func() message
 | 
						|
 | 
						|
In the above, file.c:123 is the filename where the log record was generated and
 | 
						|
func() is the function name. By default ('log format default') only the
 | 
						|
function name and message are displayed on the console. You can control which
 | 
						|
fields are present, but not the field order.
 | 
						|
 | 
						|
 | 
						|
Filters
 | 
						|
-------
 | 
						|
 | 
						|
Filters are attached to log drivers to control what those drivers emit. Only
 | 
						|
records that pass through the filter make it to the driver.
 | 
						|
 | 
						|
Filters can be based on several criteria:
 | 
						|
 | 
						|
   - maximum log level
 | 
						|
   - in a set of categories
 | 
						|
   - in a set of files
 | 
						|
 | 
						|
If no filters are attached to a driver then a default filter is used, which
 | 
						|
limits output to records with a level less than CONFIG_LOG_MAX_LEVEL.
 | 
						|
 | 
						|
 | 
						|
Logging statements
 | 
						|
------------------
 | 
						|
 | 
						|
The main logging function is:
 | 
						|
 | 
						|
   log(category, level, format_string, ...)
 | 
						|
 | 
						|
Also debug() and error() will generate log records  - these use LOG_CATEGORY
 | 
						|
as the category, so you should #define this right at the top of the source
 | 
						|
file to ensure the category is correct.
 | 
						|
 | 
						|
You can also define CONFIG_LOG_ERROR_RETURN to enable the log_ret() macro. This
 | 
						|
can be used whenever your function returns an error value:
 | 
						|
 | 
						|
   return log_ret(uclass_first_device(UCLASS_MMC, &dev));
 | 
						|
 | 
						|
This will write a log record when an error code is detected (a value < 0). This
 | 
						|
can make it easier to trace errors that are generated deep in the call stack.
 | 
						|
 | 
						|
 | 
						|
Code size
 | 
						|
---------
 | 
						|
 | 
						|
Code size impact depends largely on what is enabled. The following numbers are
 | 
						|
generated by 'buildman -S' for snow, which is a Thumb-2 board (all units in
 | 
						|
bytes):
 | 
						|
 | 
						|
This series: adds bss +20.0 data +4.0 rodata +4.0 text +44.0
 | 
						|
CONFIG_LOG: bss -52.0 data +92.0 rodata -635.0 text +1048.0
 | 
						|
CONFIG_LOG_MAX_LEVEL=7: bss +188.0 data +4.0 rodata +49183.0 text +98124.0
 | 
						|
 | 
						|
The last option turns every debug() statement into a logging call, which
 | 
						|
bloats the code hugely. The advantage is that it is then possible to enable
 | 
						|
all logging within U-Boot.
 | 
						|
 | 
						|
 | 
						|
To Do
 | 
						|
-----
 | 
						|
 | 
						|
There are lots of useful additions that could be made. None of the below is
 | 
						|
implemented! If you do one, please add a test in test/py/tests/test_log.py
 | 
						|
 | 
						|
Convenience functions to support setting the category:
 | 
						|
 | 
						|
   log_arch(level, format_string, ...) - category LOGC_ARCH
 | 
						|
   log_board(level, format_string, ...) - category LOGC_BOARD
 | 
						|
   log_core(level, format_string, ...) - category LOGC_CORE
 | 
						|
   log_dt(level, format_string, ...) - category LOGC_DT
 | 
						|
 | 
						|
Convenience functions to support a category defined for a single file, for
 | 
						|
example:
 | 
						|
 | 
						|
   #define LOG_CATEGORY   UCLASS_USB
 | 
						|
 | 
						|
all of these can use LOG_CATEGORY as the category, and a log level
 | 
						|
corresponding to the function name:
 | 
						|
 | 
						|
   logc(level, format_string, ...)
 | 
						|
 | 
						|
More logging destinations:
 | 
						|
 | 
						|
   device - goes to a device (e.g. serial)
 | 
						|
   buffer - recorded in a memory buffer
 | 
						|
 | 
						|
Convert debug() statements in the code to log() statements
 | 
						|
 | 
						|
Support making printf() emit log statements a L_INFO level
 | 
						|
 | 
						|
Convert error() statements in the code to log() statements
 | 
						|
 | 
						|
Figure out what to do with BUG(), BUG_ON() and warn_non_spl()
 | 
						|
 | 
						|
Figure out what to do with assert()
 | 
						|
 | 
						|
Add a way to browse log records
 | 
						|
 | 
						|
Add a way to record log records for browsing using an external tool
 | 
						|
 | 
						|
Add commands to add and remove filters
 | 
						|
 | 
						|
Add commands to add and remove log devices
 | 
						|
 | 
						|
Allow sharing of printf format strings in log records to reduce storage size
 | 
						|
for large numbers of log records
 | 
						|
 | 
						|
Add a command-line option to sandbox to set the default logging level
 | 
						|
 | 
						|
Convert core driver model code to use logging
 | 
						|
 | 
						|
Convert uclasses to use logging with the correct category
 | 
						|
 | 
						|
Consider making log() calls emit an automatic newline, perhaps with a logn()
 | 
						|
   function to avoid that
 | 
						|
 | 
						|
Passing log records through to linux (e.g. via device tree /chosen)
 | 
						|
 | 
						|
Provide a command to access the number of log records generated, and the
 | 
						|
number dropped due to them being generated before the log system was ready.
 | 
						|
 | 
						|
Add a printf() format string pragma so that log statements are checked properly
 | 
						|
 | 
						|
Enhance the log console driver to show level / category / file / line
 | 
						|
information
 | 
						|
 | 
						|
Add a command to add new log records and delete existing records.
 | 
						|
 | 
						|
Provide additional log() functions - e.g. logc() to specify the category
 | 
						|
 | 
						|
--
 | 
						|
Simon Glass <sjg@chromium.org>
 | 
						|
15-Sep-17
 |