Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: i386 boot1.c peculiarity while studying code



On Wed, Jan 07, 2015 at 02:39:11PM -0500, William D. Jones wrote:
> Hello all,
> 
> Just for the sake of studying the source code, I'm looking over NetBSD's 
> boot process for i386 (in sys/arch/i386/stand). So far I'm not having too 
> much trouble, but one thing that is bothering me is the code that attempts 
> to open() the boot directory.
> 
> >From what I understand, pbr.S, label.S, bootxx.S, and boot1.c all get 
> >linked 
> into a filesystem-dependent binary file that becomes the bootsector of a 
> hard disk or a floppy drive; Sector 0 belongs to pbr.S (what the MBR code 
> jumps to), Sector 1 belongs to label.S, and Sectors 2-15 belong to 
> everything else. On line 59 of boot1.c, there is an open "system call". 
> From what I can gather, this open function actually calls a dummy label in 
> bootxx.S, after initial setup, that JMPs unconditionally to file system 
> driver code in libsa. The filesystem driver actually loaded is based on 
> Makefile defines, so multiple bootloaders are created based upon the 
> kernel's destination filesystem.

Not quite.
mbr.S ends up in sector 0 of the disk, it is loaded by the bios.
pbr.S ends up in the first sector of the mbr partition and is all
  that the mbr.S (or equiv) loads.
Both the above get loaded to the same address IIRC 0x7c00, so the
  pbr code had to relocats itself somewhere else.
The first thing the pbr code does it to (hopefully) determine
to partition it was loaded from and read the full 8k partition boot area.
It can then jump past the label into the code thst sets up the 32bit
environment for the C code.

> However, boot1.c proper calls a wrapper function for open ob() three times: 
> line 80, 90, and 106. The ob() wrapper takes no arguments, does not access 
> global state, and hence open() always receives constant parameters "boot". 
> Between the calls, some static (keyword!) data structures are manipulated 
> to increment the sector at which to open the file. But since these data 
> structures are static, I'm having trouble visualizing how the filesystem 
> code eventually called by open() knows what region of the boot media to try 
> next. It seems like all three calls are redundant, since there's no state 
> changes that I'm aware of. So, does each call to open() actually check a 
> different region (sector) of the boot media? Am I missing a piece of 
> information or global state that libsa's filesystem drivers are aware of? 
> I'm a bit hung up on this, and I'd appreciate any help someone who has 
> worked with the i386 bootstrap code can give me!

It should check for a disklabel and look for the offset of the root fs.
However sysinst might have a non-obvious restriction that the root fs
has to be at the start of the partition.
If there isn't a valid label it assumes the root fs is at the start
of ths mbr partition.

There is a hack for raidframe where it look for a valid filesystem
64 sectors further down the disk.
I don't remember a 2nd fallback.
This does mean that it doesn't look at the 'inner label' of RF partitions.

> Also, can someone confirm I understand the following correctly: libsa's 
> file system code, at least for ufs/ffs, just blindly scans the disk after 
> the bootsector until the superblock is found, and then assumes the first 
> instance of a "boot" directory is the correct location to find the next 
> code to load?

There is no scan, but it does try an offset.

	David

-- 
David Laight: david%l8s.co.uk@localhost


Home | Main Index | Thread Index | Old Index