# Installing 9.0-RELEASE on a Thinkpad x220 (SSD) with proper sector alignment



## jrm@ (Jun 13, 2012)

The system doesn't boot when I use a gpt partition scheme, so I've tried the code below with different parameter values.  However, what I think is proper alignment isn't happening.  Please excuse me (and feel free to correct me) if anything I say is nonsense; I've relied on sysinstall over the years to do all the "decision making".

`# gpart create -s MBR ada0; gpart add -t freebsd -b 64 ada0`

I thought starting at the 64th sector would be a good idea because if the sector size is either 512 or 4k the alignment would still be OK (64*512/4096 = 8).

After the commands above I see:

`# gpart show`

```
=> 63  312581745 ada0 MBR     (149G)
   63  63             -free - (31k)
   126 312581682 1    freebsd (149G).
```

Why does the partition start on sector 126 and not 64?  This a problem because 126*512/4096 = 15.75, right?  I get exactly the same result if I use `# gpart add -t freebsd -a 4k ada0.`

I've also read different suggestions about aligning with the erase block size as well.  Is this important?

For completeness here is the entire install procedure I'm using (thank you @wblock , @vermaden and @aragon for your useful posts).


```
gpart create -s MBR ada0
gpart add -t freebsd -b 64 ada0 # ??
gpart create -s BSD ada0s1
gpart add -t freebsd-ufs  -a 4k -s 145g ada0s1
gpart add -t freebsd-swap -a 4k -s 4g ada0s1
gpart bootcode -b /boot/mbr ada0
gpart set -a active -i 1 ada0
gpart bootcode -b /boot/boot ada0s1
newfs -Ut /dev/ada0s1a
mount /dev/ada0s1a /mnt
cd /usr/freebsd-dist/
tar --unlink -xvpJf base.txz -C /mnt
tar --unlink -xvpJf doc.txz -C /mnt
tar --unlink -xvpJf games.txz -C /mnt
tar --unlink -xvpJf kernel.txz -C /mnt
tar --unlink -xvpJf lib32.txz -C /mnt
```

Anyone finding themselves struggling with a similar problem might find these posts helpful:
http://forums.freebsd.org/showthread.php?t=28526&highlight=align
http://forums.freebsd.org/showthread.php?t=19093&highlight=align
http://forums.freebsd.org/showthread.php?t=12594.


----------



## wblock@ (Jun 13, 2012)

The boot block and partition tables are not something that will be affected by alignment.  Better to keep them in the normal location for compatibility; just leave out the -b.

Creating the bsdlabel with -a4k will do the right thing, or should.  There are (AFAIR) two sectors at the start of the bsdlabel.  The filesystem that comes immediately after that should land on an aligned block.


----------



## kpa (Jun 13, 2012)

There are 16 512-byte sectors at the beginning of the slice reserved for the label data and the embedded /boot/boot code (if the disk is bootable). Interestingly bsdlabel(8) gets this right but if you create the partitions with gpart(8) the first a partition defaults to start offset 0.


```
# mdconfig -f testdisk 
md0

# gpart create -s MBR md0
md0 created

# gpart add -t freebsd md0
md0s1 added

# gpart create -s BSD md0s1
md0s1 created

# gpart add -t freebsd-ufs md0s1
md0s1a added

# gpart show md0s1
=>    0  65535  md0s1  BSD  (32M)
      0  65535      1  freebsd-ufs  (32M)
```

The correct way would be then

```
gpart add -b 16 -t freebsd-ufs md0s1
```



If the beginning of the slice is 4k aligned (in my example it starts from 0) then the a partition will be as well.

@jrm, I think there's something special about how BIOS drives are handled, the 126 is a multiple of 63 which is the sectors/track number that BIOSes use. Find the next multiple of 63 that is also a multiple of 8, that is 504 and you have a suitable start sector for the slice ada0s1 that makes it 4k aligned.


```
# gpart add -b 504 -t freebsd-ufs ada0
```

Also remember to use -b 16 when creating the first partition of ada0s1


```
# gpart add -b 16 -s 145g -t freebsd-ufs ada0s1
```


----------



## wblock@ (Jun 13, 2012)

Should also add that gpart(8) is still changing, the most recent being the fix to keep -a from overriding -b.  Recent changes like that one are not in 9.0-RELEASE, just in -STABLE at present.  They will be in 9.1-RELEASE.


----------



## jrm@ (Jun 13, 2012)

If I'm understanding, the procedure is:


```
gpart create -s MBR ada0
gpart add -b 504 -t freebsd ada0
gpart create -s BSD ada0s1
gpart add -t freebsd-ufs  -b 16 -s 145g ada0s1
gpart add -t freebsd-swap -a 4k -s 4g ada0s1
```

which gives this result:

```
# gpart show
=>      63  312581745   ada0   MBR              (149G)
        63        441          - free -         (220k)
       504  312581304      1   freebsd [active] (149G)

=>       0  312581304   ada0s1 BSD              (149G)
         0         16          - free -         (8.0k)
        16  304087040      1   freebsd-ufs      (145G)
 304087056    8388608      2   freebsd-swap     (4.0G)
 312475664     105640          - free -         (51M).
```


----------



## wblock@ (Jun 13, 2012)

That's 4k aligned, yes.  Some people like to get the alignment in higher increments for SSDs, like 128K.  Use -b 2032 for the beginning of the bsdlabel and the root partition should end up right at 1M, an even multiple of both 4k and 128k.


----------



## kpa (Jun 14, 2012)

I believe that should be 

```
gpart add -b 2016 -t freebsd ada0
```

because the slice has to start from a block number that is a multiple of 63, enforced by gpart(8). 2032 would be rounded up to 2079 (63*33). 32*63 = 2016 is before the sector number 2048 and leaves enough space for the label

And then 


```
gpart add -b 32 -t freebsd-ufs  ada0s1
```

should place the beginning of ada0s1 at sector 2048.

Trickier than it should be


----------



## jrm@ (Jun 14, 2012)

wblock@ said:
			
		

> Some people like to get the alignment in higher increments for SSDs, like 128K.  Use -b 2032 for the beginning of the bsdlabel and the root partition should end up right at 1M, an even multiple of both 4k and 128k.



Did you mean 2048 or am I confused?

2032*512/1024/1024 = 0.9921875
2048*512/1024/1024 = 1

Regardless, -b 2032 and -b 2048 (and -a1M) give the same result, because what @kpa said (I'm guessing): they're not also multiples of 63 which is the number of sectors per track.

`# gpart add -b 2032 -t freebsd ada0`
`# gpart show`

```
=>  63   312581745  ada0   MBR      (149G)
    63   2016              - free - (1M)
  2079   312579729     1   freebsd  (149G)
```

To get 128k alignment, we need a value that is a common multiple of 63 and 128k.  LCM(63,1024*128) = 8257536.  So, we should supply 8257536/512 = 16128.  I've just realized that this is the value that @aragon's scripts gives. 

`# gpart add -b 16128 -t freebsd ada0`
`# gpart show`

```
=>  63   312581745  ada0   MBR       (149G)
    63       16065         - free -  (7.9M)
 16128   312565680     1   freebsd   (149G)
```

I followed @kpa's advice and left room for the label data and the embedded /boot/boot code at the beginning of the slice.  I added more room so the partition starts on a 1M boundary.  I have no idea if that's helpful or not.
`# gpart show ada0s1`

```
=>      0   312581745  ada0s1   MBR          (149G)
        0        2048           - free -     (7.9M)
     2048   304087040     1     freebsd      (149G)  
304089088	  8476592     2     freebsd-swap (4.0G)
```

Here's the full, updated (and hopefully final) procedure:


```
gpart create -s MBR ada0 # create the MBR partition table scheme

# create the first slice (MBR partition) so that it starts at the beginning of
# a sector and is 128k aligned, i.e. use lcm(63,1024*128)/512 = 16128
gpart add -b 16128 -t freebsd ada0 

gpart create -s BSD ada0s1 # create the bsdlabel in the first slice

# create the first partition for / (ad0s1a) and leave room for the 16
# 512-byte sectors at the beginning of the slice reserved for the label data and
# the embedded /boot/boot code (if the disk is bootable)
# I added even more space to maintain 1M alignment
gpart add -t freebsd-ufs  -b 2048 -s 145g ada0s1 

gpart add -t freebsd-swap -a 4k -s 4g ada0s1 # create a swap partition

gpart bootcode -b /boot/mbr ada0
gpart set -a active -i 1 ada0
gpart bootcode -b /boot/boot ada0s1

newfs -Ut /dev/ada0s1a # use softupdates and turn TRIM on

mount /dev/ada0s1a /mnt
cd /usr/freebsd-dist/
tar --unlink -xvpJf base.txz -C /mnt
tar --unlink -xvpJf doc.txz -C /mnt
tar --unlink -xvpJf games.txz -C /mnt
tar --unlink -xvpJf kernel.txz -C /mnt
tar --unlink -xvpJf lib32.txz -C /mnt
```


----------



## wblock@ (Jun 14, 2012)

I hope that everyone with a Lenovo that doesn't boot correctly from a GPT disk is calling them or at least sending email asking for a BIOS update.


----------



## jrm@ (Jun 14, 2012)

When I contact them I'll

1. Ask about the BIOS.
2. Ask if I can have the money back for the MS Windows tax.  I really did wipe it.  When they say no, I'll submit a comment to the Department of Justice link @drhowarddrfine posted.


----------

