I'm reading source code of FreeBSD and found that they have 2 files which may be used to create MBR - sys/boot/i386/boot0/boot0.S and sys/boot/i386/mbr/mbr.S.
From current my understanding boot0.S is the code in MBR (first sector of boot disk drive which is loaded by BIOS) in FreeBSD.
Then what is the mbr.S? What is the relationship between them?
I'm reading source code from FreeBSD 8.2.0.
boot0.S contains the MBR for the Boot Easy boot manager, that allows selecting an OS to boot. mbr.S contains a generic MBR that just boots the active partition.
You should take a look at the FreeBSD handbook.
Related
I'm coming from the Windows world and trying understand how exactly partitions, file systems and the kernel in Linux work together. If someone can tell me if my understanding is correct, that would be awesome:
A partition can contain one or no Linux kernel, but never multiple kernels
The bootloader decides which kernel from which partition will be loaded and what will be the root file system (= partition mounted at "/")
Now lets assume we have a PC with one disk, containing two partitions (partition A and partition B). Each partition stores another Linux kernel (kernel A and kernel B), and each partition uses another file system (file system A and file system B):
After loading one kernel, Linux can always see and access both partitions (e.g. by using fdisk -l).
If kernel A is loaded, file system A will be the root file system, if kernel B is loaded, file system B will be the root file system.
If kernel A is loaded with root file system A, it is possible to mount partition B with file system B into file system A.
Additional questions:
What actually tells the kernel which file system is the root fs? Is this information stored in the bootloader section of the disk, or even the kernel itself?
Generally spoken, how does Linux know which file system belongs to which partition on the disk?
Thanks for your help!
I'm working on an embedded system where the rootfs is constructed in a tmpfs partition by the init process. After the rootfs is complete, it will do a pivot-root and start spawning processes located in the rootfs.
But it seems like XIP is not working for our tmpfs, and all the applications is therefore loaded into ram twice (in the tmpfs and again into ram when loaded).
Can this really be true?
I found an old discussion thread at https://ez.analog.com/thread/45262 which describe the same issue as I'm seeing.
How can I achieve XIP for a file-system located in memory?
What you are attempting to do should be indeed possible (though I haven't tried it myself). The problem is simply you are not going about it the correct way. If you use the block RAM device ("brd") you can create a block device that is actually RAM presented as a block device. To enable this on your kernel (sorry you do not say which kernel you have so I will just go with the kernel 4.14), you need to enable CONFIG_BLK_DEV_RAM as well as CONFIG_BLK_DEV_RAM_DAX in your kernel configuration. They are both under "Device Drivers" -> "Block Devices". Then you create such a RAM backed block device and then create for example an ext2 or ext4 or XFS file system on it and then prepare your rootfs into that file system and then pivot-root into it. Now you are executing in a RAM backed file system which has XIP (now replaced by DAX) functionality thus executing applications should now at least in theory work correctly without creating a copy of the data and simply running it out of the RAM pages of the block RAM device.
Please do beware that such approach has limitation such as for example that kernel modules themselves will still be copied into RAM, get_user_pages() may not work, O_DIRECT may not work, and neither might RDMA, sendfile() and splice().
Some relevant things to look at include:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/block/Kconfig?h=v3.19#n359
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/block/Kconfig?h=v3.19#n396
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/blockdev/ramdisk.txt?h=v3.19
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/xip.txt?h=v3.19
Note XIP was replaced by DAX since 4.0 kernel so there see:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/dax.txt?h=4.14
Also note that support for DAX was removed from block RAM driver with kernel 4.15 so you will no longer be able to do this once you move to kernel 4.15 and later... See commit 7a862fbbdec665190c5ef298c0c6ec9f3915cf45 for the reasoning behind removing the functionality.
I hope this is enough to set you on the right track and sorry about the bad news that the functionality has been removed since 4.15 kernel...
I'm studying boot steps on a Pandaboard. According to this how-to, they have multiple boot steps (Boot rom > X-loader or SPL > U-boot > Linux kernel). Actually, I do not understand why they have such steps inefficiently. Can't I just load u-boot instead of using file called "MLO"? What does "MLO" actually do? Are there any important reasons that they have to put "MLO" instead of loading u-boot directly?
From eLinux.org:
http://elinux.org/Panda_How_to_MLO_%26_u-boot
The first-stage bootloader runs directly on the board from power-up. I
don't know the name of this bootloader(From TI official wiki, it
called Boot Rom). This bootloader initializes a minimal amount of CPU
and board hardware, then accesses the first partition of the SD card
(which must be in FAT format), and loads a file called "MLO", and
executes it. "MLO" is the second-stage bootloader.
The second-stage bootloader can apparently be one of either the
X-loader or SPL. This bootloader apparently also just reads the first
partition of the SD card, and loads a file called "u-boot.bin", and
executes it. "u-boot.bin" is the third-stage bootloader.
The third-stage bootloader is U-boot, which is a popular bootloader
for many different embedded boards and products. This bootloader has
lots of different features, including an interactive shell, variables,
ability to access the SD card and show its contents, etc. What happens
next depends on the version of U-boot you have for the Panda board,
and how it is configured. In a very simple configuration, U-Boot will
look for the file "uImage" in the root of the first partition of the
SD card (which, again, must be formatted as a FAT partition), and
execute that. This is the Linux kernel. U-Boot passes the kernel a
command line argument. Depending on how the kernel is configured it
may accept the command line from U-Boot, or use one that was compiled
into it when it was built.
This is a "Panda Board thing", not necessarily true of Linux in general.
However, most all systems have some kind of "multi-stage" boot like the one above. For example, booting a PC running Windows, you see:
BIOS startup
Boot sector is loaded from disk or USB; or a PXE boot record is read from the network
The windows kernel starts (the stuff you see before/during the "splash screen")
Finally, "Windows" itself starts
So it's neither "inefficient", nor unusual.
PS:
This link also has a good description of the boot load sequence:
http://omappedia.org/wiki/Bootloader_Project
PPS:
"MLO" stands for "Mmc LOader"
When the board comes up, the Memory Management Unit (MMU) still needs to be setup before the CPU can start using the SDRAM. The SoC has 56KB of SRAM which can be used at that point, but it is too small for u-boot to run from. The extra step is code running from SRAM will load and start u-boot.
I recently installed Linux Mint Debian Edition - it was installed into a logical partition (formatted to ext4) under a 40 GB extended partition that was previously used as a backup/recovery disk in Windows 7.
It works quite well - the only problem is when I boot to Windows, then next time, Linux won't boot. I then need to use a recovery distro and run fsck.ext4 which detects some problems with group descriptors, fixes them and it's all good again.
My feeling is that Windows tries to mount (and fix / defrag / whatever) that partition which messes it up - I suspect that, because 1) it only happens after I boot to Windows, 2) Windows still displays the old recovery/backup disk D: (although you cannot access it and it doesn't show a free/total space etc.).
Any idea how to fix it?
Just a shot in the dark, it could possibly be the listed partition type.
Check the disk with your favorite partition table editor (fdisk, cfdisk, parted, whatever), and check to see if your linux partitions are listed as Windows ones or if they are correctly listed as Linux. If they are listed wrong, you should safely be able to change this, and it could stop Windows from harassing you.
Let's say I'd like to start a small linux distro before my ordinary operating system start.
BIOS load MBR and execute MBR.
MBR locates the active partition which is my linux partition.
Linux start and I perform what I need to do.
Linux shut down and I switch to Real Mode again.
The original partition boot sector is loaded and my ordinary OS start.
AFAIK, step 4 will be the difficult task, restore the state on all devices prior to linux, will INT13h be functional? Do I need to restore the Interrupt Vector Table? To mention a few.
Has this been done in any existing project perhaps?
Linux does not normally support this, particularly since it reinitializes hardware in a way that the BIOS and DOS programs may not expect. However, there is some infrastructure to switch back to real mode in specific cases - particularly, for a reboot (see machine_real_restart in arch/x86/kernel/reboot.c) - and has code to reinitialize hardware for kexec or suspend. I suspect you might be able to do something with a combination of these - but I don't know if the result will truly match what DOS or Windows would expect to see on reboot.
A much easier plan would be to use a chainloading bootloader that can be set to boot in a particular configuration once, like GRUB. You could invoke grub-set-default, then reboot. When GRUB comes up, it would then pass control off to Windows. By then setting the fallback OS to the Linux partition, control would return to Linux on the next boot.
Yet another option may be to use Coreboot, but I'm not sure if this is production-ready for booting windows yet.
i haven't tried this so I don't know if it would work, but here goes:
There is an option in the header of a bzImage format kernel file that specifies the address of real mode code to execute before the protected mode code starts. You could create a minimal bzImage-compliant file which has no actual kernel, but which has real mode code to load your MBR using INT 0x13 to 0x7c00 and jmp into it like the BIOS does.
If you use kexec to load the bzImage using the "-t bzImage-x86 --real-mode" options, it should reset the PE bit in CR0 to drop to realmode (as bdonlan above mentioned) and execute the code pointed to by the bzImage header option.
The bzImage header option is called realmode_swtch and is documented in /usr/src/linux/Documentation/x86/boot.txt , the header format code is in /usr/src/linux/arch/x86/boot/header.S
Have you looked into kexec?