I am porting latest version Linux (linux-stable) to a customized ARM926TEJ-S board, and I want to print messages in the initializing phase. So I am trobuled by the problems of how can i let the uart work in the kernel initializing phase.
printing linux banner in init/main.c:start_kernel()
eventually call printk() to print the message. My question is how the printk() is implemented and how can I let the printk() output to my uart.
Because I know the driver of uart is not initialized there, they are initialize by rest_init() called in the end of start_kernel(). rest_init() will consequently call do_initcalls() and eventually call module_init() of drivers.
And I know putstr("Uncompressing Linux..."); in the uncompressing phase is implemented by arch/arm/boot/compressed/debug.S that using waituart/senduart... that implemented by the files setting by CONFIG_DEBUG_LL_INCLUDE
Related
I have come across a scenario where two drivers (driver1 and driver2) are registering with kernel using module_init(). driver1 is configuring the chip and driver2 is accessing that chip, so driver1's module_init() has to be called before driver2's module_init() call. How we can create this order, as both driver1 and driver2 are registering at the same init call level (i.e using module_init()).
Can driver2 somehow determine that the chip has been properly configured, using either device status (preferred) or the value of a shared variable (messy)?
If so, then driver2's probe routine should return with -EPROBE_DEFER when the chip has not yet been configured (by driver1).
See https://lwn.net/Articles/485194/
drivercore: Add driver probe deferral mechanism
Allow drivers to report at probe time that they cannot get all the resources
required by the device, and should be retried at a later time.
This should completely solve the problem of getting devices
initialized in the right order. Right now this is mostly handled by
mucking about with initcall ordering which is a complete hack, and
doesn't even remotely handle the case where device drivers are in
modules. This approach completely sidesteps the issues by allowing
driver registration to occur in any order, and any driver can request
to be retried after a few more other drivers get probed.
I'm working on an embedded Linux device (based on an NXP i.MX8 mini SoC) and it needs to support microphone audio input using the NXP "micfil" driver (sound/soc/fsl/fsl_micfil.c).
As a part of initializing the microphone, we have added code (to the driver's fsl_micfil_probe function) to set a GPIO line necessary to enable the microphone (by calling devm_gpiod_get_optional)
Our current Linux BSP (based on Yocto's "sumo" release) works great with this patch.
When upgrading to a newer BSP (based on Yocto's "hardknott" release), we find that the GPIO setup call fails. It appears to be happening because the driver's probe function is called before the GPIO subsystem is available. I think we can hack around this by making the GPIO call from some other driver callback (e.g. after an application opens the device), but I would prefer to simply defer this driver's probe operation until after GPIO is available.
Is there a way to do this? To tell Linux that this driver should not be probed until after GPIO starts up? Or maybe have the probe function explicitly call the GPIO startup function?
Or is there a better solution that I haven't thought of yet?
The device driver's probe function can return -EPROBE_DEFER (after any necessary clean-up) to indicate that a resource it requires is not available yet. The driver core will then add the device to a "deferred probe" list and try to call the probe function after a successful probe of some other device.
See the documentation for further information, and heed the warning about not returning -EPROBE_DEFER if any child devices have been created by the probe function.
devm_gpiod_get_optional and similar devm_gpiod_get_ and gpiod_get_ functions that return a struct gpio_desc * value will return ERR_PTR(-EPROBE_DEFER) if the requested GPIO is not yet available. (This is different to the GPIO not being found, which will result in the _optional variants returning NULL and the non-_optional variants returning ERR_PTR(-ENOENT).) The caller can propogate the -EPROBE_DEFER error to its own caller, but again the warning about not returning -EPROBE_DEFER if any child devices have been created should be heeded.
I work on module for ipsec in linux. Look at two different situations when code from my module will be executed.
Executing from process context: application generate some traffic to transmit via network, application should call some syscall to transfer data, then process switch to kernel space and packet go through network subsystem of linux, somewere here will be executed my module, and all finished after affording task to network card. All these steps performed from process context and in any moment scheduler can switch process from one to another. Is as follows fist case of using my module - from process context.
Executing from softirq context: when network card receive packet it generate hardware interrupt, which "prepare" appropriate softirq to run. And packet go through network subsystem of linux (including my module) until some application got it. These steps performed from softirq context and could be interrupted only by hardware interrupt, but not by scheduler work.
The question is: How can I programmatically determine in module, from which context module is executing? It can be some element of struct task_struct or some syscall or something else. I couldn't find it by myself.
It is considered as a bad practice to make a function's control flow dependent from whether it is executed in interrupt context or not.
Citation from the Linux kernel developer (Andrew Morton):
The consistent pattern we use in the kernel is that callers keep track of whether they are running in a schedulable context and, if necessary, they will inform callees about that. Callees don't work it out for themselves.
However, there are several functions(macros) defined in linux/preempt.h for detect current scheduling context: in_atomic(), in_interrupt(). But see that LWN article about their usage.
I would like to see the list of tags (specifically ATAG_MEM) passed to the kernel from the bootloader. What is the best way to do it?
The initial entry code, head-common.S will put the physical address as passed by the bootloader into the __atags_pointer kernel variable just after starting the MMU. That's where the later steps, setup_arch() calling setup_machine_*() (in arch/arm/kernel/atags_parse.c) then retrieve it from. See there for how to access physically-mapped mem.
"Seeing" them at this stage requires some early-boot-printk support, a JTAG debugger or some other mechanism to extract tracing / diagnostic from the device before the driver stack is fully initialized. If that (the ability to extract diagnostics early in boot of your device) is your problem, please clarify the question.
I'm trying to understand a wireless linux device driver.
So after netdev_open is called...
what happens?
I know packets are being transmitted through an xmit function, but how does the code get there?
The dev->hard_start_xmit() function for the netdev is called out of the networking core - see net/core/dev.c (in particular dev_hard_start_xmit() and dev_queue_xmit()). These functions are in turn called out from the protocol handlers - see for example ip_queue_xmit() in net/ipv4/ip_output.c.