Category Archives: FreeBSD

Netbooting ARM/MIPS devices: kinds of kernel and u-boot

U-Boot is a boot loader. Its task is to get kernel into memory and pass control to it. I will cover only parts of it related to netboot.

kernel or kernel.bin

But before we start loading something we need to know what to load. In previous post I mentioned that there are kernel, kernel.bin, and ubldr files. Let’s get into details. First of all: ubldr requires its own post. So there will be one more covering just ubldr. Now kernel and kernel.bin.

kernel is ELF executable. It means that it’s a self-contained file with all the information required to layout its bits in memory. e.g.: this data in file should be copied to address A, and N bytes at address B should be set to zero, code intry point is address X. All this auxiliary information is stored alongside to raw code and data. U-boot (or any other bootloader) reads it, lays out data/code accordingly and passes control to entry point. U-Boot’s command for it is bootelf.

Now, bootelf or ELF support in general is not always available in boot loaders. In this case we load ELF on host machine. Technically it’s called “convert to binary format” but essentially what objcopy utility does is it simulates loading of ELF file into memory and dumps memory region from the lowest address that belongs to loaded executable to the highest one into the kernel.bin file. No auxiliary information is saved – only raw code and data. Without this information it’s users responsibility to point which address this memory dump should be loaded at and where to start execution.

That’s theory in a nutshell. Back to practice.

U-Boot

Network initialization routine depends on the board you’re working with. If the ethernet card connected to board over USB (like on Raspberry Pi or Pandaboard) you might need to initialize USB first:

U-Boot> usb start
(Re)start USB...
USB0:   Core Release: 2.80a
scanning bus 0 for devices... 3 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
       scanning usb for ethernet devices... 1 Ethernet Device(s) found

At this point you can either get network settings via DHCP or set them manually.
Manual control over network is performed by setting U-Boot environment variables:

U-Boot> setenv ipaddr 192.168.10.21
U-Boot> setenv netmask 255.255.255.0
U-Boot> setenv gatewayip 192.168.10.1

DHCP also provides information about TFTP server and boot file, we can set them manually too:

U-Boot> setenv bootfile kernel
U-Boot> setenv serverip 192.168.10.1

And now load it

U-Boot> tftpboot 0x8000

and boot

U-Boot> bootelf 0x8000

By default tftpboot and bootelf would use loadaddr env variable if it’s set so you can combine last two commands to

U-Boot> setenv loadaddr 0x8000
U-Boot> tftpboot
U-Boot> bootelf

With DHCP everything above is combined into three commands:

U-Boot> setenv loadaddr 0x8000
U-Boot> dhcp
U-Boot> bootelf

If you’re booting ELF loadaddr can be any valid address because bootelf will relocate kernel to proper location. Valid range for addresses depends on the board in use.

With kernel.bin though you have to specify specific value as a loadaddr. Usually it’s KERNPHYSADDR option in kernel config file for ARM and KERNLOADADDR value for MIPS. U-Boot commands sequence would look like:

U-Boot> setenv bootfile kernel.bin
...
U-Boot> setenv loadaddr 0x00100000
U-Boot> dhcp
U-Boot> go 0x00100000

uImage, ubldr

This is basic stuff I’ve been using for several years in my development environment. There are more options though: u-boot application images and bootm command and ubldr. Former is well-documented on Internet and about latter I’ll post some information soon.

Patching screens EDID information

Quite a long time ago (September 2012), the x11/nvidia-driver port was updated to 304.43, which brought-in some major changes. The most noticeable one from my point of view was the inability to use my two Samsung SyncMaster BX2240 monitors at a resolution better than 800x600 (they have a native resolution of 1920x1080), providing a stunning 1600x600 desktop experience. With no time to dig-in this at that time, I reverted to the previous nvidia-driver and planned to have a look at it later.

I finally took the time to search for a solution. I post it here for two reasons: a) I might need this information at some point in the future and am more likely to find it that way and b) I might not be the only one here which faced this situation.

The first step was to modify my Xorg configuration to be a bit more verbose about the process of choosing a screen resolution when X starts to see if something was different with both drivers. This can be achieved by editing the Monitor section:

Section "Monitor"
    ...
    Option "ModeDebug" "TRUE"
EndSection

With the new driver, no section for Validating Mode "1920x1080", but when trying to validate other modes, the driver reported that it would be happier with EDID information from the screens:

217 (II) Feb 07 09:52:30 NVIDIA(GPU-0):   Validating Mode "640x350":
218 (II) Feb 07 09:52:30 NVIDIA(GPU-0):     640 x 350 @ 85 Hz
219 (II) Feb 07 09:52:30 NVIDIA(GPU-0):     Mode Source: X Server
220 (II) Feb 07 09:52:30 NVIDIA(GPU-0):       Pixel Clock      : 31.50 MHz
221 (II) Feb 07 09:52:30 NVIDIA(GPU-0):       HRes, HSyncStart :  640,  672
222 (II) Feb 07 09:52:30 NVIDIA(GPU-0):       HSyncEnd, HTotal :  736,  832
223 (II) Feb 07 09:52:30 NVIDIA(GPU-0):       VRes, VSyncStart :  350,  382
224 (II) Feb 07 09:52:30 NVIDIA(GPU-0):       VSyncEnd, VTotal :  385,  445
225 (II) Feb 07 09:52:30 NVIDIA(GPU-0):       H/V Polarity     : +/-
226 (WW) Feb 07 09:52:30 NVIDIA(GPU-0):     Mode is rejected: Only EDID-provided modes are allowed on
227 (WW) Feb 07 09:52:30 NVIDIA(GPU-0):     DFP-0.

I enabled EDID which was previously disabled because the screen reported invalid information:

Section "Device"
    ...
    #Option "IgnoreEDIDChecksum" "DFP-0, DFP-1"
EndSection

With the new driver, a Validating Mode "1920x1080" section appeared but with the very same Mode is rejected: Only EDID-provided modes are allowed on DFP-0. The old driver provided a bit more of information actually:

1822 (II) Feb 07 09:54:10 NVIDIA(GPU-0):   Validating Mode "1920x1080":
1823 (II) Feb 07 09:54:10 NVIDIA(GPU-0):     1920 x 1080 @ 50 Hz
1824 (II) Feb 07 09:54:10 NVIDIA(GPU-0):     Mode Source: EDID
1825 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       Pixel Clock      : 148.50 MHz
1826 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       HRes, HSyncStart : 1920, 2448
1827 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       HSyncEnd, HTotal : 2492, 2640
1828 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       VRes, VSyncStart : 1080, 1084
1829 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       VSyncEnd, VTotal : 1089, 1125
1830 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       H/V Polarity     : +/+
1831 (WW) Feb 07 09:54:10 NVIDIA(GPU-0): The EDID for Samsung SMBX2240 (DFP-1) contradicts itself: mode
1832 (WW) Feb 07 09:54:10 NVIDIA(GPU-0):     "1920x1080" is specified in the EDID; however, the EDID's
1833 (WW) Feb 07 09:54:10 NVIDIA(GPU-0):     valid VertRefresh range (56.000-75.000 Hz) would exclude
1834 (WW) Feb 07 09:54:10 NVIDIA(GPU-0):     this mode's VertRefresh (50.0 Hz); ignoring VertRefresh
1835 (WW) Feb 07 09:54:10 NVIDIA(GPU-0):     check for mode "1920x1080".
1836 (II) Feb 07 09:54:10 NVIDIA(GPU-0):     Viewport                 1920x1080+360+22
1837 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       Horizontal Taps        0
1838 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       Vertical Taps          0
1839 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       Base SuperSample       x4
1840 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       Base Depth             32
1841 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       Distributed Rendering  1
1842 (II) Feb 07 09:54:10 NVIDIA(GPU-0):       Overlay Depth          32
1843 (II) Feb 07 09:54:10 NVIDIA(GPU-0):     Mode is valid.

Okay, since all this seems to be related to EDID, and because some major changes where introduced in version 302.xx of the NVidia driver, let's try to patch it! I could not find a tool to dump the EDID directly from FreeBSD, however when Xorg starts, it prints a hex dump of it so it is actually quite trivial to get it from the log file (don't want to code? Clone!).

sysutils/edid-decode can be used to easily locate relevant information from the EDID dump (monitor range), and spot inconsistencies:

Extracted contents:
header:          00 ff ff ff ff ff ff 00
serial number:   4c 2d 84 06 32 32 42 43 0e 15
version:         01 03
basic params:    80 30 1b 78 2a
chroma info:     78 f1 a6 55 48 9b 26 12 50 54
established:     bf ef 80
standard:        71 4f 81 00 81 40 81 80 95 00 b3 00 a9 40 95 0f
descriptor 1:    02 3a 80 18 71 38 2d 40 58 2c 45 00 dd 0c 11 00 00 1e
descriptor 2:    00 00 00 fd 00 38 4b 1e 51 11 00 0a 20 20 20 20 20 20
descriptor 3:    00 00 00 fc 00 53 4d 42 58 32 32 34 30 0a 20 20 20 20
descriptor 4:    00 00 00 ff 00 48 39 58 42 34 30 31 30 32 34 0a 20 20
extensions:      01
checksum:        b0

Manufacturer: SAM Model 684 Serial Number 1128411698
Made week 14 of 2011
EDID version: 1.3
Digital display
Maximum image size: 48 cm x 27 cm
Gamma: 2.20
DPMS levels: Off
Supported color formats: RGB 4:4:4, YCrCb 4:2:2
First detailed timing is preferred timing
Established timings supported:
720x400@70Hz
640x480@60Hz
640x480@67Hz
640x480@72Hz
640x480@75Hz
800x600@56Hz
800x600@60Hz
800x600@72Hz
800x600@75Hz
832x624@75Hz
1024x768@60Hz
1024x768@70Hz
1024x768@75Hz
1280x1024@75Hz
1152x870@75Hz
Standard timings supported:
1152x864@75Hz
1280x800@60Hz
1280x960@60Hz
1280x1024@60Hz
1440x900@60Hz
1680x1050@60Hz
1600x1200@60Hz
1440x900@75Hz
Detailed mode: Clock 148.500 MHz, 477 mm x 268 mm
1920 2008 2052 2200 hborder 0
1080 1084 1089 1125 vborder 0
+hsync +vsync
Monitor ranges (GTF): 56-75Hz V, 30-81kHz H, max dotclock 170MHz
Monitor name: SMBX2240
Serial number: H9XB401024
Has 1 extension blocks
Checksum: 0xb0 (valid)

CEA extension block
Extension version: 1
0 8-byte timing descriptors
Detailed mode: Clock 148.500 MHz, 477 mm x 268 mm
1920 2448 2492 2640 hborder 0
1080 1084 1089 1125 vborder 0
+hsync +vsync
Detailed mode: Clock 74.250 MHz, 477 mm x 268 mm
1280 1390 1430 1650 hborder 0
720  725  730  750 vborder 0
+hsync +vsync
Detailed mode: Clock 74.250 MHz, 277 mm x 286 mm
1280 1720 1760 1980 hborder 0
720  725  730  750 vborder 0
+hsync +vsync
Detailed mode: Clock 27.000 MHz, 477 mm x 286 mm
720  732  796  864 hborder 0
576  581  586  625 vborder 0
-hsync -vsync
Detailed mode: Clock 27.000 MHz, 477 mm x 286 mm
720  736  798  858 hborder 0
480  489  495  525 vborder 0
-hsync -vsync
Checksum: 0x0 (should be 0x99)

EDID block does not conform at all!
Block has broken checksum

After changing the lower limit of the vertical refresh rate from 56 Hz (0x38) to 50 Hz (0x32) and adjusting the checksums, it's time to see if the situation is improved. Once more we have to tweak xorg.conf to tell Xorg to use our dumps instead of querying the screens for EDID information:

Section "Device"
    ...
    Option "CustomEDID" "DFP-0:/usr/local/etc/X11/EDID-BX2240-FIXED; DFP-1:/usr/local/etc/X11/EDID-BX2240-FIXED"
EndSection

And suddenly, it worked!

February 11th, 2013 edit

I wrote an e-mail to the screen manufacturer (Samsung) asking for assistance. I will publish their response on this blog as soon as I get one. The sent message is basically:

Hi,

I own two BX2240 screens. These screens provide invalid EDID information (I wrote an article [1] about that) that makes them unusable with the prorietary NVidia driver version 302.xx and up. It is possible to workaround the problem at the OS level (I provide some instructions in my article) however it would be better to put valid information back into the screen so that they work out of the box.

However, you don't provide any information about this on your website. Can you please send me a technical notice providing information on flashing EDID information if it's possible, and if not, the location of the EEPROM containing the wrong EDID information so that I can replace it and continue to use my screens in proper conditions?

Please find attached to this message the fixed EDID information I use at the moment and want to flash back into my screens.

Kind regards,
Romain Tartière

References:

  1. http://romain.blogreen.org/blog/2013/02/patching-screens-edid-information/

brd’s notes » FreeBSD 2013-01-16 15:18:56

I have long been a huge fan of having serial console on my servers–it can really save the day when a mistake is made. Yesterday, one of my coworkers botched the sshd_config in an upgrade of a server, so the server came up fine, but without sshd. As a result, the system was not accessible for remote login via the network.

Over the years, I have done serial console in many ways. I began with a single null modem cable between the back of two servers. Next, I utilized a RocketPort multi-port serial card with 8 serial ports on it. These days, I have moved on to employing big serial console servers such as those made by OpenGear, providing up to 48 ports. They also have ancillary features such as providing a Nagios platform and Environmental monitoring.

No matter your physical connectivity, I recommend using Conserver. This helps by logging what is happening on the console, which can be very handy if you need to see what happened in the past whether it be a function of the system, or to see who did what. It also provides multi-user access, so you can watch while someone else is working and both of you can collaborate on fixing a problem.

In order for the previous technologies to be useful, the servers require configuration as well. The first step is to configure the BIOS for serial console redirection. Once this has been performed, the OS will need to be configured to present a console login via the serial port. The FreeBSD Handbook explains how to do this Here.

Alexander Leidinger » FreeBSD 2013-01-15 17:24:30

I wrote in a previous blog post that I want to switch to crypto cards for use with ssh and GnuPG. After some research I settled on the OpenPGP cryto cards. I ordered them from kernelconcepts. As soon as they arrive (and I have some free time), I will start to use them and write down how to work with them with FreeBSD.

Share

VCHIQ drivers work again

I synced both vchiq-freebsd and userland to latest and greatest.

As I mentioned earlier – OS compatibility shim was removed from upstream sources so I had to create Linux KPI implementation layer which turned out not that awful task because I managed to reuse a lot of code from Max Khon’s DAHDI port. I had to implement (in somewhat hackish fashion) kthread API, re-implement semaphores support using condvar and mutex in order to get _interruptible part of API working properly and create dumb implementation of rather small subset of Linux list.h API.

With latest code I got pretty much all demos in hello_pi working except hello_jpeg(crashes system) and hello_encode(didn’t test). The most exciting bit for me was watching H.264 video playing on Raspberry Pi in hello_video demo. Network throughput still sucks so I had to copy file to tmpfs partition in order to get smooth playback though.

If you want to test VCHIQ – in addition to sources you’ll need latest firmware files. For demos you’ll also have to install freetype2 and manually hack Makefile.include in hello_pi. I’m planning to create ports/packages for both drivers and userland some time next week.

On the related note: Aleksandr Rybalko got XOrg working on Efika MX Smartbook so FreeBSD/Pi will get graphic interface soon :)

The Ports Management Team 2013-01-12 04:43:57

As announced in September the ports tree will no longer be exported to CVS after February 28th 2013. All users who still use CVS, CVSup or csup to update the ports tree are encouraged to switch to portsnap(8) or for users which need more control over their ports collection to use Subversion directly.

Read more at http://lists.freebsd.org/pipermail/freebsd-ports-announce/2013-January/000049.html

FreeBSD Development Snapshots – Testers Wanted

I am pleased to announce the re-availability of FreeBSD development snapshots provided by the FreeBSD Project.

As with any development branch, these snapshots are not intended for use on production systems. However, we do encourage testing on non-production systems as much as possible.

Users interested in testing the development branches are also encouraged to subscribe to the freebsd-snapshots@ mailing list, where new snapshot availability, including corresponding installation image checksums, and any additional noteworthy information about the images will be announced.

The list subscription URL is: http://lists.freebsd.org/mailman/listinfo/freebsd-snapshots

Snapshots may be downloaded from the corresponding architecture subdirectory over FTP: ftp://ftp.freebsd.org/pub/FreeBSD/snapshots/

Problems, bug reports, or regression reports should be reported through the GNATS PR system or the appropriate mailing list, such as -current@ or -stable@ .

This directory contains FreeBSD installation snapshots for the head/ and stable/ branches. The snapshot installation media are organized in the same hierarchy as the FreeBSD release installers, for example:

snapshots/i386/i386/ISO-IMAGES/
snapshots/amd64/amd64/ISO-IMAGES/

The FTP structure is also available for bootonly.iso installers.

These snapshots do not include a package distribution, and do not include the release notes documentation.

Snapshots are expected to be generated weekly. Snapshot retention is expected to be the current week and three prior weeks. The FTP directory will always contain the distribution sets for the most recent snapshot.

Snapshots are named as:

FreeBSD-{BRANCH}-{ARCH}-{DATE}-{SVNREV}

where BRANCH is the official branch name (such as 10.0-CURRENT, or 9.2-STABLE), ARCH is the target architecure the release was built, DATE is the day the snapshot was built in YYYYMMDD format, and SVNREV is the svn revision number at the point in time the snapshot was generated.

The CHECKSUM.MD5 and CHECKSUM.SHA256 files are suffixed with the date the snapshots were generated.

In general, it can be expected that all snapshots will be built with the same subversion revision, as to avoid inconsistencies between images built on the same day.

Be sure to check the mailing lists for those architectures (e.g., freebsd-sparc64 mailing list for the sparc64 architecure) before taking one of those snapshots. The specific testing purpose that snapshot was generated for should be mentioned there. The snapshot ISOs in those architecture directories may not be suitable for general use.

Those who wish to keep up-to-date on the latest snapshot availability are advised to subscribe to the freebsd-snapshots@ mailing list, where new snapshots will be announced, including the image checksums and any notable information regarding a particular snapshot set.

FreeBSD/armv6: what’s new and exciting?

It’s been a while since last update on the project status so it might seem as there was no progress in this area. The reality is: there is a bunch of activities happening with various levels of success. So I decided to give kind of end-of-the-year round-up of ongoing projects, plans and obstacles ARM hackers face.

First of all we tried switching default cache type from write-through to write-back type. It should have increased performance but instead opened a can of worms. Memory corruption debugging led to L2 cache driver on Pandaboard, EHCI driver code and subsequently to busdma code. Whole process took quite a few days full of hair-pulling and nagging various people and ended up in committing USB fixes and Ian Lepore’s busdma patches. PL310 (L2 cache controller) driver is being tested at this very moment. Original issue (WB caches) still stands and postponed till next year.

Then there are two projects by Andrew Turner aimed at modernizing FreeBSD/armv6 subsystem: switching to EABI and clang support for ARM. Daisuke Aoyama took both of them and produced working image for Raspberry Pi. He also fixed two issues with event timers on Raspberry Pi so now the platform is much more stable. I ran buildkernel in a loop overnight and by the morning Pi had survived 7 cycles and still was alive and kicking. I also managed to get python built and working on it. Didn’t have 100% success with perl 5.14/5.16, ports were built but failed at install stage segfaulting in do_clean_objs function.

My Pandaboard survived overnight buildkernel loop with L2 cache disabled, but acting up if I enable it. Investigating.

Then there are also several platform bring-ups in progress. Alexander Rybalko works on getting FreeBSD running on Efika MX Smartbook. Ganbold Tsagaankhuu hacks on Allwinner 10. Alexander Dutkowski’s hardware of choice is BeagleBoard-xM.
Ruslan Bukin experiments with Exynos4412 and Thomas Skibo reported about FreeBSD running on Zedboard (Xilinx Zynq-7000).

But what about devices/platform we have in tree? I have limited knowledge about some platforms so here is summary of the ones I’m aware of. If you have more information on any of these targets (or any other ARM-related projects) – let me know, I’ll update post.

  • BCM2835 Raspberry Pi the most accessible and therefore the one that gets the most exposure and testing. Pretty stable, considering. Supported devices: USB, network, MMC, GPIO, framebuffer, GPU. The rest is on ToDo list. VCHIQ driver is BSD-licensed now and I’m planning on getting it to sys/contrib. Userland bits of OpenGL ES should be added as a port though.
  • (update) LPC32x0 No first hand experience but judging by the code it supports MMC, FB, GPIO and USB
  • Marvel Armada XP I don’t have information about this one, sorry
  • Nvidia Tegra2 Just barebone boot stuff.
  • TI AM335x Examples: BeagleBone, TI Sitara EVM. Network was reported working but unstable on BeagleBone. USB is not supported. Haven’t tested GPIO yet.
  • TI OMAP3 Example: BeagleBoard-xM. See Alexander Dutkowski’s project
  • TI OMAP4 The hw I have – Pandaboard ES. Supported devices: USB, network, MMC, GPIO. Some issues with L2 cache
  • Versatile Platform Board Exists only as emulation target for QEMU. Supported hardware: PCI, network, framebuffer. Seems to be fairly stable, no extensive testing performed.

BeagleBone, PandaBoard ad Raspberry Pi images can be built using Tim Kientzle’s scripts.

Not really stellar list of supported peripherals I’d say. I tend to blame several things.

First – experimental and unstable state of FreeBSD/armv6 in general. It’s no fun adding new hardware support when you’re not confident in underlying subsystems stability. “I flush cache for this TX descriptor but is it really gets flushed?”. Been there, no fun at all. That’s why I believe task #1 for nearest future is maximum performance and rock-solid stability of what we have.

Then there is the case of syscons. It’s old, it’s inflexible and it’s mostly i386-centric. Just until recently most of our so-called embedded targets were headless so there were no pressure from this side to reorganize things. My experience with coding two framebuffer drivers or trying to add PS/2 keyboard support on non-i386 platform was not very pleasant. It’s messy and there is a lot of code duplication. newsyscons project may be the way to go, I haven’t looked at it yet. We just need someone(tm) to finish it and get into the tree.

Fix these two issues should make bring-up process easier. It leaves us with question of GPU support. But it’s different story for different post…

Happy New Year, everybody!

Alexander Leidinger » FreeBSD 2012-12-23 18:22:43

From time to time I convert videos to H264. When I do this I want to get the best quality out of a give filesize. This means I create VBR videos. The question here is, how big the target video file shall be.

After searching around a little bit in the net I found a formula which is supposed to give a hint about the target filesize. Naturally this depends on the encoder (or even the encoder-version), the encoder settings and even the video.

The formula is at least a good hint for my use, so I wrote a script which calculates several filesize values for a given video (based upon the output of mediainfo, which the scripts expects in a file with the filename as an argument to the script). It calculates a CBR and a VBR value for a given video based upon the width, height and duration. It should work on all system with a POSIX compatible shell.

Example output for a video from my HD-ready cam, original filesize 1.8 GB:

Width: 1280, Height: 720, FPS: 50.000, Time: 1424, Motion: 2
Per second: 6451200.000 bps / 6300 Kibps
Total CBR: 1148313600 bytes / 1121400 KiB / 1095 MiB
Total VBR: 861235200 bytes / 841050 KiB / 821 MiB
Width: 1280, Height: 720, FPS: 50.000, Time: 1424, Motion: 3
Per second: 9676800.000 bps / 9450 Kibps
Total CBR: 1722470400 bytes / 1682100 KiB / 1642 MiB
Total VBR: 1291852800 bytes / 1261575 KiB / 1232 MiB
Width: 1280, Height: 720, FPS: 50.000, Time: 1424, Motion: 4
Per second: 12902400.000 bps / 12600 Kibps
Total CBR: 2296627200 bytes / 2242800 KiB / 2190 MiB
Total VBR: 1722470400 bytes / 1682100 KiB / 1642 MiB

There are 3 sections, the difference is the “motion� value. It is a kind of multiplicator depending on the amount of motion in the video. For the videos I made myself (family videos, and even some videos of volley ball games), the first section seems to be just fine. So I reduced the original MP4 file to about 50% (not visible here is the audio size, normally I copy the original audio unmodified).

For the curious ones, the formula is

width_in_pixels * height_in_pixels * fps * motion_value * 0.07

for the bps value. The CBR value is

bps * playtime_in_seconds / 8

and the VBR value is

3 / 4 * CBR_value.

Share

Personal story of a ports committer

You all know that sometimes you end up dealing with all the ugly stuff instead of doing useful work. Over the last few months I was kept busy at $dayjob got assimilated by portmgr and had to look after redports. All of those new challenges are nice on it's own and I really enjoyed being part of the FreeBSD community and ecosystem but then 11/11 happened.

At that day quite a lot has changed for me since redports was isolated as a precaution and all ports building clusters of portmgr were effectively shut down. That situation was quite a mess since all automated systems and clusters were gone. No INDEX builds, no QAT, no pointyhat so also no exp-runs anymore. Whenever someone broke the ports tree we didn't even knew. It proved to be quite hard to get back on track again after that incident. INDEX checks and a very very limited QAT are already running again but pointyhat and redports are still dead. :(

The daily frustration and dealing with all that strange decisions that are taken because of the need to get stuff done is hard sometimes. But It's almost Christmas and without redports I have much more spare time so I try to calm down and focus on stuff that I can hack on my own. And that worked out quite nice so far ...

tvheadend:
I've noticed in the XBMC 12.0 release notes that they have included the PVR branch and thus support DVB-S2/C/T in XBMC. Well actually they only provide some backend configuration interfaces and rely on a backend like mythtv or tvheadend to handle the DVB stuff. Mythtv would be okay for that task but It's huge for such a small job. Tvheadend is a nice and small TV streaming server that suites perfectly and only does the bare minimum without a lot of dependencies. Configuration is done in a web based GUI or can be done in XBMC. So I started working on a tvheadend port. A few weeks later I'm at the point now where tvheadend compiles fine and also starts. I've just ripped out all that epoll stuff and linuxisms that I stumbled accross so it doesn't run properly yet. Adding kqueue support is the next step now.

virtualbox:
Due to redports being unavailable the vbox work has also frozen. I tried to collect all that patches and complains in my inbox so that they don't get lost. Since the situation did not improve I temporary created a github repository for the virtualbox ports and committed all the accumulated patches there: https://github.com/decke/freebsd-vbox

This includes almost all patches that were flying around on mailinglists and updates vbox to 4.2.6 / 4.1.24 but testing was very limited so take care if you give them a try. Testing will show us if we can commit it to the portstree by New Year's Eve.

Cross-compilation hiccups

Good news and bad news. Let’s start with good ones.

Daisuke Aoyama tracked down what causes “Unrecognized filesystem type” error with some SD cards. It is U-Boot using High Speed mode. Root cause is still unknown but as a workaround I just disabled HS mode for SD card in u-boot and updated freebsd-uboot-20121129.tar.gz. Or alternatively you can get uboot-nohs.img and use it to replace uboot.img on your SD card.

Bad news are: installworld for cross-compiled FreeBSD is broken unless you’re doing it on the latest HEAD. The reason is utility called mtree(8). It is used to ensure that target filesystem permissions and owners/groups are correct. Owners and groups are described as usernames and group names, not as numeric UIDs/GUIDs and mtree uses getpwXXX family of routines to convert names to numeric values. See the problem already? If new system user is added to latest HEAD and you use old trusty FreeBSD 9.0, there is no way mtree would know about this user. NetBSD solved this problem by introducing -N command-line option that lets you point mtree to the target system’s master.passwd and groups. So we need to port this feature to FreeBSD in order to get proper cross-compilation environment. And that’s my plan for next few days.

So if you see something like this:

mtree -eU  -f /src/FreeBSD/head/etc/mtree/BSD.var.dist -p /mnt/var
mtree: line 22: unknown user auditdistd
*** [distrib-dirs] Error code 1

Either update to latest HEAD, use mergemaster -p or wait couple of days.

Be careful of adding debugging, as microseconds count..

.. after tinkering with the TDMA code a bit more, I discovered why I was seeing larger swings in the TDMA slot timings.

Two words: Debug Code.

Well, to be more specific - I added some debugging code that by default didn't do anything. But it was still there; it checked a debug flag and didn't log anything if it was disabled. But that would take time to execute. Since that debugging code sat _between_ the routines doing math with the RX timestamp and the nexttbtt register, it would calculate a slightly larger TSF offset.

Once I moved the debug code out from where it is and grouped all that register access and math together, the slot timing swings dropped by a few microseconds and everything went back to smooth.

Tsk. I should've known better.

At least now the TDMA code is working well on the 802.11n chips. Yes, it's still only 802.11abg rates, but it works. I've also found the PCU MISC_MODE bit to enforce packets don't transmit outside of the burst window and that is working quite fine with TDMA.

So, I think I can say "mission accomplished." I'll tidy up a few more things and make sure TX only occurs in one data queue (as mentioned in my previous post, they all burst independently at the moment..) and then patiently wait for someone to implement 802.11n adhoc negotiation so 802.11n MCS rates and aggregation magically begins to work. Once that's done, 802.11n TDMA will become a reality.

FreeBSD on Pi: more stuff

Long overdue update on how the things are going with FreeBSD on Raspberry Pi. We've made some good progress so far:

  • Hans Petter Selasky fixed low-speed interrupt endpoints problem which means we have working USB keyboard now
  • GPIO driver by Luiz Otavio O Souza. So now you can blink OK LED (gpioctl -f /dev/gpioc0 -t 16). Not the most productive activity though.
  • Kernel now obtains information about display resolution, memory layout, MAC address from firmware
  • Framebuffer/syscons support added
  • Some stability fixes for SDHCI/li>
  • Initial port of VCHIQ interface (vchiq-freebsd)
  • Port of userland libraries (userland)

Overall stability and performance is still a problem, but it's what we're going to work on next.

And if you missed previous post: freebsd-pi is no more, use HEAD from FreeBSD subversion repository.

Boot process has been changed and now it looks like: firmware → uboot → ubldr → kernel. So old script for building image is no longer relevant. Here is new one. Tim Kientzle's scripts collection for building images for BeagleBone, Pandaboard and RPi uses more systematic approach but RPi part hasn't caught up to latest boot chain changes yet. Once it is up to date I suggest using Tim's scripts.

Building FreeBSD does not require any additional tools but if you want VideoCore bits you'll need following packages installed:

  • devel/cmake
  • devel/git
  • devel/gmake

If you don't need VideoCore binaries, just comment build_videocore and install_videocore calls. This script will also install OpenGL ES hello_triangle demo to /root folder. To run it run perform following steps:

# cd /root
# kldload vchiq
# ./hello_triangle.bin

I tried to build Qt5 with OpenGL ES support, but build choked on compile-time assert triggered by FreeBSD using OABI. Good news though: EABI work is almost done, so there is a fat chance we'll see Qt5 with eglfs backend running on FreeBSD in near future.

You can try pre-built image (124Mb, MD5 sums). Login is "root", no password. Use dd to write it to SD card. U-Boot seems to be somewhat finicky about SD cards, so if you get "** Unrecognized filesystem type **" message try another card. First boot might take some time because sshd will generate keys. U-Boot output goes to serial port and monitor, FreeBSD console messages go only to monitor, but by the end of boot sequence you should get login prompt on serial.

This image is a snapshot of work in progress and by no means a production system.

UPDATE

** Unrecognized filesystem type ** U-Boot issue seems to be more widespread then I thought. I'm working on it.

Getting TDMA working on 802.11n chipsets

A few years ago, a bunch of clever people figured out how to implement TDMA using the Atheros 802.11abg NICs. Sam Leffler has a great write-up here. He finished that particular paper with some comments about the (then) upcoming 802.11n chipsets from Atheros and how they would be better suited to the kinds of tricks he pulled with the Atheros MAC.

But, if you tried bringing up TDMA on the Atheros 802.11n chips, it plain just didn't work. Lots of people gnashed teeth about it. I was knee deep in TX aggregation work at the time so I just pushed TDMA to the back of my mind.

How it works is pretty cute in itself. To setup a TX "slot", the beacon timer is used to gate the TX queues to be able to start transmitting. Then a "channel ready time" burst length is configured, which is the period of time the TX queue can transmit. Once that timer expires, no new TX is allowed to begin. Sam then slides the slave TX window along based on when it sees a beacon from the master, as everything is synchronised against that.

Luckily, someone did some initial investigation and discovered that a couple of things were very very wrong.

Firstly, when fetching the next target beacon transmission time ("TBTT"), the AR5212 era NICs returned it in TU, but the AR5416 and later returned it in TSF.

Secondly, the TSF from each RX frame on the AR5212 is only 15 bits; on the AR5416 and later its 32 bits. The wrong logic was used when extending the RX frame timestamp from the AR5416 from 32 bits to 64 bits, and it was causing the TSF to jump all over the place.

So with that in place, he managed to stop the NICs from spewing stuck beacons everywhere (a classic "whoa, who setup the timers wrong!" symptom) and got two 11n NICs configured in a TDMA setup. But he reported the traffic was very unstable, so he had to stop.

Fast-forward about 12 months. I've finished the TX aggregation and BAR handling; I've debugged a bunch of AP power save handling and I'm about to reimplement some things to allow me to finish of AP power save handling (legacy/ps-poll and uapsd) in a sane, correct fashion. I decide, "hey, TDMA shouldn't be that hard to fix. Hopefully there are no chip bugs, right?" So, I plug in a pair of AR5413 (pre-11n NICs) and get it up and running. Easy. Then I plug in an AR5416 as the slave node, and .. it worked. Ok, so why was he reporting such bad results?

Firstly, Sam exposed a bunch of useful TDMA stats from "athstats". Specifically, if you start tinkering with TDMA, do this:

$ athstats -i ath0 -o tdma 1


   input   output  bexmit tdmau   tdmadj crcerr  phyerr  TOR rssi noise  rate
  619817   877907   25152 25152    -4/+6    142     143    1   74   -96   24M
     492      712      20    20    -0/+7      0       0    0   74   -96   24M
     496      720      20    20    -2/+6      0       0    0   74   -96   24M
     500      723      21    21    -6/+4      0       0    0   75   -96   24M

When I was debugging the initial AR5416 TDMA stuff, the tdma adjust figures bounced everywhere between 0 and 1000uS off. That was obviously not stable.

So, I looked at what debugging was in the driver itself. There was some (check if_ath_debug.h for the TDMA and TDMA timer flags), and after a bit of digging I realised that every time the TSF was just about to converge, it would be bumped out 1000uS. Then it would slowly drift back to converge, then it'd fall out 1000uS. This kept repeating. It made no sense; every time it calculated the delta between the expected and real TSF, it would "bump" the TSF by that much. That way the TSF would actually be correct. It shouldn't be out by almost as much the next RX'ed frame.

I did some initial testing to ensure the TSF was running at the expected 1uS interval (it was) and the master side was also running at the expected 1uS interval (it also was), so it wasn't out of sync clocks. The TSF bump must not be "right".

Enter the next bug - on the AR5416 and later, the TSF writes must be done as a 64 bit write. Ie, you write TSF_L32 first, then TSF_U32. At that point it gets internally updated and everything is consistent. If you don't do that, it doesn't latch.

Ok, so that fixed the intial drift. But after about 60 seconds, the TSF adjust parameters started varying ridiculously wildly. Ok, so 60 seconds equaled around 65,535 TU (where a TU is 1.024 milliseconds) so I began to wonder if I was seeing something wrap at that point.

Enter the next bug. The math involved in calculating the expected slot time was based on the 64 bit TSF and it was converted down to a 16 bit TU value from 0 .. 65535 TU. On the AR5212 era chips, the nexttbtt timer had a 16 bit resolution. When the nexttbtt value was read from that register, it was already 16 bits. So the "TSF delta" between the expected and real slot time was calculated between these two 16 bit values. However, on the AR5416 and later, the nexttbtt value was a 32 bit TSF (microsecond) value. Even when converted to a TU (1.024 millisecond) value, it would wrap at a value much greater than 65,535 TU. So the comparison would soon be between a value from 0..65,535 TU and 0 .. much-bigger-than-65,535 TU. The tsfdelta would become very, very negative.. and things would go nuts.

Ok, so that fixed another behavioural issue. Things were looking good. The slot time sync was stable. So I started passing traffic. Everything looked good.. for about 60 seconds. Then everything went slightly nuts again. But only with traffic. The timing calculations went way, way out.

Here's an example of the beacons coming in. Note that the expected beacon interval here is 49,152uS.

[34759308] [100933] BEACON: RX TSF=67127545 Beacon TSF=3722387514 (49152)
[34759357] [100933] BEACON: RX TSF=67176714 Beacon TSF=3722436670 (49156)
[34759442] [100933] BEACON: RX TSF=67262432 Beacon TSF=3722521354 (84684)
[34759454] [100933] BEACON: RX TSF=67275216 Beacon TSF=3722533850 (12496)
[34759504] [100933] BEACON: RX TSF=67325995 Beacon TSF=3722583802 (49952)
[34759552] [100933] BEACON: RX TSF=67374479 Beacon TSF=3722632108 (48306)
[34759602] [100933] BEACON: RX TSF=67424546 Beacon TSF=3722681282 (49174)
[34759652] [100933] BEACON: RX TSF=67475842 Beacon TSF=3722731578 (50296)
[34759701] [100933] BEACON: RX TSF=67525900 Beacon TSF=3722780730 (49152)

The master beacons were not coming in stable in any way. The main reason this would happen is if the air was busy at the master target beacon transmission time. So it would delay transmitting the beacon until the air was free.

This is where I decided it was about time I inserted some tracing into the TDMA code. I had introduced some ALQ based tracing in the ath(4) driver recently, specifically to trace TX and RX descriptors. I decided to add TDMA trace points. That way I could look at the TDMA recalculation along with the TX and RX from the driver.

What I found was very .. grr-y. After about 60 seconds (surprise), the TX would burst FAR past the 2.5 milliseconds it was supposed to. Why the heck was that happening?

After a bunch of staring-at-documentation and talking with some people well-versed in how the Atheros MAC worked, we realised the only real explanation is that the beacon timer was firing after the burst time, retriggering the timer. But why would it be? I stared at the debugging output a little more, and look at what I saw:

[34759258] [100933] BEACON: RX TSF=67077388 Beacon TSF=3722338362 (49152)
[34759258] [100933] SLOTCALC: NEXTTBTT=67081216 nextslot=67081224 tsfdelta=8 avg (5/8)
[34759258] [100933] TIMERSET: bt_intval=8388616 nexttbtt=65510 nextdba=524078 nextswba=524070 nextatim=65511 flags=0x0 tdmadbaprep=2 tdmaswbaprep=10
[34759259] [100933] TSFADJUST: TSF64 was 67077561, adj=1016, now 67078577

.. everything here is fine. We're programming nexttbtt in TU, not TSF (because the HAL API specifies it in TU for the older, pre-11n chips. Ok. Suspiciously close to the 65,535 TU boundary.

Then:

[34759308] [100933] BEACON: RX TSF=67127545 Beacon TSF=3722387514 (49152)
[34759308] [100933] SLOTCALC: NEXTTBTT=22528 nextslot=67131381 tsfdelta=-11 avg (5/7)
[34759308] [100933] TSFADJUST: TSF64 was 67127704, adj=11, now 67127715

Ok, but it's just a TSF adjust, no biggie. But, then this happened:

[34759357] [100933] BEACON: RX TSF=67176714 Beacon TSF=3722436670 (49156)
[34759357] [100933] SLOTCALC: NEXTTBTT=71680 nextslot=67180550 tsfdelta=6 avg (5/7)
[34759357] [100933] TIMERSET: bt_intval=8388616 nexttbtt=71 nextdba=566 nextswba=558 nextatim=72 flags=0x0 tdmadbaprep=2 tdmaswbaprep=10
[34759357] [100933] TSFADJUST: TSF64 was 67176888, adj=1018, now 67177906

At this point, it was clear. nexttbtt was very very small. Somehow it was very very small - 71 TU is very, very much before the current TSF of somewhere around 67,127,545. At this point the Next TBTT timer would just keep continously firing. And this would keep re-gating the TX queue, allowing it to just plain keep bursting. That explains why everything was going crazy during traffic.

This again was another example of the code assuming it was an AR5212 era NIC. The nexttbtt value was being trimmed to be between 0 and 65,535 TU. After I fixed that and fixed up the math a bit, nexttbtt was being correctly programmed and suddenly everything started working. And quite well.

So, now the basics are working. I'll audit the math to ensure everything wraps consistently at the 32-bit TSF boundary (ie, 4 billion microseconds, give or take) as that doesn't take too long to occur. But the 11n chips now behave the same as the 11a chips do when doing TDMA.

So what's next?
  • The "tx time" calculation needs to be aware of the 11n rate configuration, so it can calculate the guard time correctly. Right now it uses the non-11n aware rate -> duration HAL function;
  • The TX path has to be rejiggled a bit to ensure _all_ traffic gets stuffed into one TX queue (well, besides beacons.) Management and higher priority traffic has to do this too. If not, then multiple TX queues can burst and they'll burst separately, blowing out the TX slot timing;
  • Someone needs to get 11n adhoc working, so that 11n rates are negotiated during adhoc peer establishment. Then aggregation can just magically work at that point (the TDMA code reuses a lot of adhoc mode vap behaviour code);
  • 802.11e / 802.11n delayed block-ACK support needs to be implemented;
  • Then when doing TDMA, we can just burst out an aggregate or two inside the given slot time, then wait for a delayed block ACK to come back from the remote peer in the next slot time! Yes, I'd like to try and reuse the standard stuff for doing delayed block-ack rather than implementing something specific for 802.11n aggregation + TDMA.
  • .. and yes, it'd be nice for this to support >2 slave terminals, but that's a bigger project.
Right now I think I'll tackle #1 and then make sure the 11n NICs can be configured in a static MCS rate, without aggregation. The rest will have to be up to someone else in the community. My plate is full.

So, TDMA on the 802.11n NICs is now working. Go forth and hack!

Alexander Leidinger » FreeBSD 2012-11-25 08:37:52

The recent security incident triggered a discussion how to secure ssh/gpg keys.

One way I want to focus on here (because it is the way I want to use at home), is to store the keys on a crypto card. I did some research for suitable crypto cards and found one which is called Feitian PKI Smartcard, and one which is called OpenPGP card. The OpenPGP card also exists in a USB version (basically a small version of the card is already integrated into a small USB card reader).

The Feitian card is reported to be able to handle RSA keys upto 2048 bits. They do not seem to handle DSA (or ECDSA) keys. The smartcard quick starter guide they have  (the Tuning smartcard file system part) tells how to change the parameters of the card to store upto 9 keys on it.

The spec of the OpenPGP card tells that it supports RSA keys upto 3072 bits, but there are reports that it is able to handle RSA keys upto 4096 bits (you need to have at least GPG 2.0.18 to handle that big keys on the crypto card). It looks to me like the card is not handle DSA (or ECDSA) cards. There are only slots for upto 3 keys on it.

If I go this way, I would also need a card reader. It seems a class 3 one (hardware PIN pad and display) would be the most “future-proof� way to go ahead. I found a Reiner SCT cyberJack secoder card reader, which is believed to be supported by OpenSC and seems to be a good balance between cost and features of the Reiner SCT card readers.

If anyone reading this can suggest a better crypto card (keys upto 4096 bits, more than 3 slots, and/or DSA/ECDSA  support), or a better card reader, or has any practical experience with any of those components on FreeBSD, please add a comment.

Share

Alexander Leidinger » FreeBSD 2012-11-25 07:27:45

I pull my hat to the people handling the recent security incident on the FreeBSD infrastructure.

Guys:

  • Thanks a lot for the countless hours you invested to find and close the initial attack vector.
  • Thanks a lot for the countless hours you invested to get the machines back to a well known state.
  • Thanks a lot for the countless hours you invested to verify the source repository.
  • Thanks a lot for the countless hours you invested to get back to a trusted package building environment.
  • Thanks a lot for the countless hours you invested to get the “remainingâ€? infrastructure (and everything else I forgot to mention) back into a good state.

Or in short: Thanks a lot for the countless hours you invested to get us from “we’re busted� to “we’re back�.

And last but not least, thanks for the decision to be better safe than sorry regarding our userbase (while it is the only way to handle something like this in a OSS project, I unfortunately think it has to be mentioned instead of taking it as an obvious decision).

Share

Making the AR5210 NIC work in the office..

I'm quite happy that FreeBSD's ath(4) driver supports almost all of the PCI and PCIe devices that Atheros has made. Once I find a way to open source this AR9380 HAL I've constructed, we'll actually support them all. However, there are a few little niggling things that have been bugging me. Today I addressed one of those.

The AR5210. It's their first 11a-only NIC. It does up to 54MBit OFDM 802.11a; it doesn't do QoS/WME (as it only has one data queue); it "may" go up to 72MBit if I hack on some magic extensions. And in open mode, it works great.

But it didn't work in the office or at home. All of which are 802.11n APs with WPA2 authentication and AES-CCMP encryption.

Now, the AR5210 only does open and WEP encryption. It doesn't do TKIP or AES-CCMP. So the encryption has to happen in software. The NIC was associating fine, but when wpa_supplicant went to program in the AES-CCMP encryption keys, the HAL simply refused.

What I discovered was this.

The driver keycache was also trying to allocate keycache slots for the AR5210, where it only supports the 4 WEP keys.  This is a big no-no. So once I mapped them to all be slot 0, I made a little progress.

The net80211 layer was trying to program in an AES-CCMP key, which the driver was dutifully passing to the HAL. The AR5210 HAL doesn't support anything but WEP or open, so the encryption key type was "clear". Now, "clear" means "for this MAC address, don't try decrypting anything." But the AR5210 HAL code rejected it - as I said, it doesn't do that.

Ok, so I ignored that entirely. I mapped all of the software encrypted key entries to slot 0 and just didn't program the hardware. So now the HAL didn't reject things. But it wasn't working. The received frames were being corrupted somehow and failed the CCMP MIC integrity check. I took at look at the frames being received (which should've been "clear" versus what was going on in the air - luckily, this laptop has an AR9280 inside so I could put it into monitor mode and sniff things. The packets just didn't add up. I was confused.

Then after discussing this with my flatmate, I idly wondered if the hardware was decrypting the traffic anyway. And, well, it was. Encrypted frames have the WEP bit set in the 802.11 header - whether they're WEP, TKIP, AES-CCMP. The AR5210 didn't know it wasn't WEP, so it tried decoding the frames itself. And corrupting them.

So after finding a PCU control register (hi AR_DIAG_SW) that lets me disable encryption/decryption, I was able to pass through the encrypted traffic fine and everything just plain worked. It's odd seeing an 11a, non-QoS station on my 11n AP, but that just goes to show that backwards interoperability is still useful.

And yes, I did take the AR5210 into the office and I did sit in a meeting with it and use it to work from. It let me onto the corporate wireless just fine, thankyou.

So now the FreeBSD AR5210 support doesn't do any hardware encryption. You can turn it on again if you'd like. Why? Because I don't want the headache of someone coming to me and asking why a dual-VAP AP with WEP and CCMP is failing. The hardware can only do _either_ WEP/open with hardware encryption, _or_ it can do everything without hardware encryption. So I decided to just disable it for now.

There's also a problem with how encryption is specified to net80211. It's done at startup time, when the driver attaches. Anything that isn't specified as being done in hardware is done in software. There is currently no clean way to dynamically change that configuration. So, if I have WEP encryption in hardware but CCMP/TKIP in software, I have to dynamically flip on/off the hardware encryption _AND_ I have to enforce that WEP and CCMP doesn't get configured at the same time.

The cleaner solution would be to:
  • Create a new driver attribute, which indicates the hardware can do WEP and CCMP at the same time - make sure it's off for the AR5210;
  • Add a HAL call to enable/disable hardware encryption;
  • If a user wants to do WEP or open - enable hardware encryption;
  • If a user wants to do CCMP/TKIP/etc - disable hardware encryption;
  • Complain if the user wants to create a VAP with CCMP/TKIP and WEP.
 If someone wants a mini-project - and they have an AR5210 - I'm all for it. But at the moment, this'll just have to do.