I am new to bootloader and Linux kernel. I have been working on a project where we have to replace booting QNX kernel with Linux kernel .Our current bootloader code has a support for booting QNX kernel.It seems like bootloader also has support for booting Linux(NOT sure) and I need to know is it doing enough to boot Linux Kernel.
Below is what our Bootloader is doing.
Bootloader is calling start_kernel function which have two argument passed to it one is kernel entry point and second is pointer to boot line
1.Address 0X90000ULL which is type casted to boot_params structure.
2.Relocate initrd
3.Copy boot sector ,Set up data and commad line to final resting place
4.Initialize Linux GDT
5.Jump to Kernel entry point
6.Disable interrupt
7.Lunch_kernel()
Now in above code two tricky things which doubted support for Linux kernel booting.
The first thing is the way Jump to kernel entry point, normally I see jumping to kernel entry in uboot or Linux source is in assembly but in our bootloader it simply filing a structure .
struct
{
long Kery;
long kernel_code_segment;
}
jumpv;
void *jump_s;
jumpv.kery=first argument pass to start_kernel;
jumpv.kernel_code_segment=0x10;
jump_s=(void *)&jumpv;
Second thing is the Lunch_kernel() for which definition is not present at all in code base.
Now is above stuff enough to pass control to Linux image or what else I can add/modified to boot the Linux image in our current bootloader code.
We are on working X86 architecture.
Due to some reason we can't do hit and trial on our board until we are sure about things.
Related
Once the Uboot loads the Linux kernel image (ZImage) onto the ram, it invokes it (could be using bootz, bootm or some other commands based on the type of the kernel Image) and then the control goes to booting the kernel. Does the uboot will be informed about the kernel boot result?, means, whether the kernel booting went through completely or got stuck in the middle because of errors?.
I looked at do_bootz, do_bootm_states and boot_selected_os api's in the uboot src code to see if there is any way to know about the final kernel boot result, but I couldn't able to figured it out.
Details:
U-boot Version: 2017.03-rc2
api's are available at: cmd/bootz.c and bootm.c files.
If any one in this community knows about it or have an idea about it, please explain to me or point me to the correct path.
Thanks in advance.
Regards
Vamsi Chagari
After bootm, booti, bootz transfer control to the kernel the memory formerly used by U-Boot will be reused by the operating system. As U-Boot is no longer in memory it cannot be informed about the operating system status.
If you use the bootefi command the U-Boot implementation of the UEFI runtime services stays in memory while the operating system is starting. The UEFI services can be called by the operating system. These include services relating to variables. One use of UEFI variables is the definition of the boot sequence.
Unfortunately UEFI variables are not yet completetly implemented in U-Boot (as of version v2018.07). They currently cannot be accessed after exiting boot services.
I'm playing a little bit with the kernel linux and I got some errors during the boot process : Kernel panic - not syncing: Attempted to kill init!
I want to understand how the boot process of the linux kernel works in general, and especially during and after the start_kernel() function and the load of the rootfs.
Thank you guys.
Lets take an example of porting linux on beaglebone through mmc.,
You get the idea of boot process. It works like this -
First when we power on the board the bootrom code executes(Hard coded in the rom of board) and initialize the CPU, disable MMU.
after executing boot-ROM code it jumps to MLO (X-loader with header, it is board specific) and load it.
MLO executes and load the Uboot it is board specific and all peripherals are initialized here.
Now the Uboot executed and looking for bootcmd where the Kernel and rootfs addressed(in mmc). this calls the kernel
Kernel extracted and than it calls the initramfs (root file system)
Actually user can not interact with hardware by Kernel only thus the rootfs gives user inerface to the kernel to run application.
We have built a simple instruction set simulator for the sparc v8 processor. The model consists of a v8 processor, a main memory and a character input and a character output device. Currently I am able to run simple user-level programs on this simulator which are built using a cross compiler and placed in the modeled main memory directly.
I am trying to get a linux kernel to run on this simulator by building a simplest bootloader. (I'm considering uClinux which is made for mmu-less systems). The uncompressed kernel and the filesystem are both assumed to be present in the main memory itself, and all that my bootloader has to do is pass the relevant information to the kernel and make a jump to the start of the kernel code. I have no experience in OS development or porting linux.
I have the following questions :
What is this bare minimum information that a bootloader has to supply to the kernel ?
How to pass this information?
How to point the kernel to use my custom input/output devices?
There is some documentation available for porting linux to ARM boards, and from this documentation, it seems that the bootloader passes information about the size of RAM etc
via a data structure called ATAGS. How is it done in the case of a Sparc processor? I could not find much documentation for Sparc on the internet. There exists a linux bootloader for the Leon3 implementation of Sparc v8, but I could not find the specific information I was looking for in its code.
I will be grateful for any links that explain the bare minimum information to be passed to a kernel and how to pass it.
Thanks,
-neha
I've not clear what is the difference between drivers that can be "embedded" inside a monolithic kernel and drivers available only as external modules.
What kind of effort is requested to "port" some driver (provided as "external module" only) to a monolithic kernel?
I would like to be able to run Vmware Tools disabling loadable modules support and getting rid of the initrd bazaar.
Though the driver more or less remains the same(in both cases),there are definitely benefits for using "drivers" embedded in monolithic kernel.
I'll try to explain the "effort in porting" the driver part which you've asked.
Depending on the kind of driver you've, essentially you've to figure out how it will fit in the current kernel source tree, its compilation(include your .ko in the uImage) and loading of it while kernel booting. Let's illustrate each step a bit:
a.) Locate the folder (in the kernel source tree) where you think it is best suited to keep your driver code.
b.) Work on to make sure your driver code is getting compiled.[i.e ultimately it will be part of monolithic kernel image(uImage or whatever you call it)]. In this context, You've to work on your Makefile for your driver. You might have to introduce some CONFIG flags to compile your driver code. There are tons of Makefiles' and driver code lying in the source tree. Roam around and you will get a good reference of how it is being done.
c.) Make sure that your driver code is independent of any other
loadable kernel module(i.e such modules which are not part of the
"monolithic" kernel image). Because if you invoke your driver
code(which is monolithic now and is in memory) which depends on
loadable module code then it may cause some kernel
panic/segmentation fault kind of error.
d.) Make sure that your driver is registered with a higher level of
subsystem which will be initializing all the registered drivers
during boot-up time.(for example: an i2c driver once registered
with i2c driver framework will be loaded automatically when i2c subsystem is initialized during system startup). This step might not be really required if you can figure out another way of invoking your driver's __init and __exit functions.
e.) Now, Your Driver _init and (_exit sections) "should" be called
if it is getting loaded by any device driver framework or directly(i.e. while
kernel is booting up ).
f.) In case of h/w drivers, we have .probe implementation in driver
which will be invoked once the kernel finds a corresponding device.
In case of s/w drivers, I guess __init and __exit is all you have.
g.) Once it is loaded, you can use it like you were using it earlier as a loadable kernel module
h.) I'll recommend reading source code of similar device drivers in the linux kernel tree and see how they are operating.
Hope this helps.
I am new to linux kernel and Try to understand booting of Linux kernel from the point it loaded into RAM,I would like to know after Linux image loaded into RAM ,How control is passed to this image ,what all are necessary parameter needs to pass to kernel and can we pass control to linux image without passing any parameter,
I am looking into the UBOOT code with "bootm.c" but unable to understand where control is passed to Linux image,which function is responsible for it.
Is load_zimage() is responsible for passing the control/
Can anybody lead me to right direction or suggest some good tutorials on this particular part
of linux booting from x86 archetectiure.
I think it depends. Different kinds of CPU architecture, they use different ways to pass information to Linux Kernel. Of course, the Linux Kernel can boot up successfully without bootloader pass information to it, but it need to statically set up correctly in the Linux Kernel, such as root device name, console device, mem size, and also some parameters to enable/disable some features in Linux Kernel.
Why bootloader need to pass various information(parameters) to Linux Kernel, I think it's flexible consideration. Think about this case that it's possible to share one Linux Kernel on two board with same CPU but different peripheral modules.
Let me show some examples that UBoot passes information to Linux Kernel:
(1) For PowerPC cpu, nowadays they use DTB(Device Tree Blob) file to pass more information from UBoot to Linux Kernel. They consider UBoot and DTB as firmware, and in Linux Kernel, they adopt one open firmware(OF) infrastructure. You may know "bootm" command in UBoot, bootm can have three parameters, the first is uImage address, the secondary one is initrd address, and the third one is the dtb address.
(2) Earlier days, they use bootargs to pass information to Linux Kernel. Also you may know there is gd/bd structure in the UBoot, they also can pass information to Linux Kernel. But the information passed in this way is limited, not like DTB.
Hope the above information help you to understand your question.