Solaris GRUB Enhancements

This is a summary of enhancements for GRUB shipped with Solaris.

Solaris VTOC The fdisk id's for Solaris partition are 130 and 191. 130 is the old tag, which also happens to conflict with Linux swap parition, so 191 is used starting from Solaris 10. GRUB is enhanced to understand both id's.
Within the Solaris fdisk partition, the disk is further divided into 16 slices and the table (VTOC) is located on the 2nd and 3rd sector (1st sector contains parition boot program). The table format is described by:
struct dk_vtoc {
        uint32_t v_bootinfo[3];         /\* info for mboot (unsupported) \*/
        uint32_t v_sanity;              /\* to verify vtoc sanity \*/
        uint32_t v_version;             /\* layout version \*/
        char    v_volume[8];            /\* volume name \*/
        uint16_t v_sectorsz;            /\* sector size in bytes \*/
        uint16_t v_nparts;              /\* number of partitions \*/
        uint32_t v_reserved[10];        /\* free space \*/
        struct dkl_partition v_part[16]; /\* partition headers \*/
        time32_t timestamp[16];         /\* partition timestamp (unsupported) \*/
        char    v_asciilabel[128];      /\* for compatibility    \*/
};
Each partition entry is described by
struct dkl_partition    {
        uint16_t        p_tag;          /\* ID tag of partition \*/
        uint16_t        p_flag;         /\* permision flags \*/
        daddr32_t       p_start;        /\* start sector no of partition \*/
        int32_t         p_size;         /\* # of blocks in partition \*/
};
Following the BSD slice naming convention, Solaris partitions are named a, b, c, etc. For details, see source code pc_slice.h and disk_io.c .

Ufs support Solaris ufs supported is provided via fsys_ufs.c and ufs.h . The ufs superblock is 8k in size, starting at 8k (16 sectors) from the beginning of the Solaris slice. It supports 3 levels of block indirection (see sbmap()). It is possible for sbmap() to return a block number 0 or negative. This indicates a hole in the file that contains zero or undefined values. The ufs_read() implementation fills buffer with zeros whenever a hole is encountered.

Solaris ufs also supports logging and a multi-terabyte extension. Grub ufs implementation does not contain code to handle either feature. Booting from multi-terabyte ufs is currently not supported. To ensure successful boot, the ufs log is always rolled when creating the boot_archive (see /boot/solaris/bin/create_ramdisk).

Netboot Netboot support in GRUB 0.95 uses native drivers compiled into the pxegrub binary. The approach fails to meet Solaris needs in two aspects. Solaris deployment model requires a single binary booting all machines, it is not possible to have a working pxegrub with all native drivers compiled in. The second problem is the lack of standard mechanism to pass network information to the kernel (really an issue with Multiboot Specification).

To address the one-binary issue, we took an UNDI driver implementation (see grub patch ) and enhance it. The main change is to inherit the network stack established by the BIOS instead of creating a new stack with low-level UNDI primitives. While some UNDI implementations are several times slower than the native drivers, the overall boot performance is acceptable in most cases.

Passing netboot information to boot involves some Solaris specific treatment, under #ifdef SOLARIS_NETBOOT. If the network is configured via DHCP, the dhcp response is pass to the kernel via the disk drive info field (mbi.drives_addr & mbi.drivers_length) in the multiboot info structure. If the network is configured via ifconfig, the following structure is passed to kernel via the drive info field:
 struct sol_netinfo {
        uint8_t sn_infotype;
        uint8_t sn_mactype;
        uint8_t sn_maclen;
        uint8_t sn_padding;
        unsigned long sn_ciaddr;
        unsigned long sn_siaddr;
        unsigned long sn_giaddr;
        unsigned long sn_netmask;
        uint8_t sn_macaddr[1];
}
The information allows the Solaris kernel to configure network interface for installing over the network as well as running as diskless clients.

GRUB Installation Finally, a few words on where GRUB is installed on Solaris. The first cylinder of the Solaris fdisk parition is reserved for boot programs. This is partition 8 in the Solaris partition table. GRUB stage1 is in sector 0; sectors 1 & 2 contains Solaris partitition table; sectors 3 to 49 are intentionally left empty (may contain old Solaris boot blocks). GRUB stage2 starts at sector 51. See installgrub.c for implementation.

The standard installation procedure does not put GRUB stage1 in the master boot sector. Users may do so manually by executing installgrub(1M) with the -m option.
Comments:

Post a Comment:
Comments are closed for this entry.
About

szhou

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today