Analysis of the Broadcom GNSS driver

Hardware

There are several devices in the Broadcom GPS range, all of which share common functional blocks and interfaces:

Software

Samsung PDAs containing the Broadcom BCM475xx family of chip-sets use a Broadcom GNSS driver that contains an MEIF parser. The same silicon is in some Windows 8 tablet PCs. The exact same source code is used to build the Linux/Android and Windows 8 driver for the BCM47511 Stand-alone GNSS chip. Windows drivers are distributed by Dell: BCM47511 Standalone GPS Solution and Lenovo: Broadcom GNSS Geolocation Driver for Windows 8.

The MEIF parser C++ source-code file is:

glmeaseng/glchovyctrl/acqmgr/glme_meif_parser.cpp

(which translates to Global Locate Measurement Engine / Global Locate Channel Overlay Control / Acquisition Manager / Global Locate Measurement Engine Measurement Engine InterFace Parser !)

It is Broadcom code from their Global Locate Library (GLL) {archive.org}. This came from Global Locate Inc., when it was bought by Broadcom in July 2007 for US$143 million. This reinforces the technical impression that Nokia and Broadcom have worked together closely on MEIF; probably as a continuation of the Global Locate Inc. relationship with Nokia pre-2007.

Programmers and Engineers

Involved in developing the Global Locate hardware (GL-16000, GL-20000, GL-32000, PMB2520, PMB 2525), firmware and API library were:

Keith Evans

"I was part of a small team that worked on the following GPS chips - GL-16000, GL-20000, GL-32000/Marlin, PMB2520/Hammerhead, and BCM4750/Barracuda."

Miro Samek {PDF Resumé}.

"Developed software architectures, designs and implementations of embedded software for the Global Locate In- door-GPS® chipsets. Led the complete re-design of the firmware using UML state machines and an event-driven framework"

Patrick Berny (pberny)

Ed Zeng

History of A-GPS Devices from Global Locate

Global Locate Inc. developed the technology for the World Wide Reference Network (WWRN), Long Term Orbits (LTO) and other A-GPS technologies {archive.org} as part of their "Indoor GPS {archive.org PDF}" portfolio. Nokia Growth Partners invested venture capital in Global Locate Inc.

In February 2007 Global Locate announced an A-GPS reference design based on a Freescale Semiconductor iMX31 applications processor and Global Locate Hammerhead A-GPS chip {Freescape PDF}.

"The Freescale reference design is available for Linux and Microsoft Windows operating systems, and is designed to optimize high performance and low power navigation in the most challenging conditions ... An easy-to-use API supports standard interfaces such as NMEA and extended NMEA, which is designed to allow portable electronic manufacturers to quickly load a range of mapping and navigation applications on top of the pre-integrated software drivers."

In March 2007 SiRF Technology sued Global Locate Inc., and Broadcom Inc., at the U.S.A. International Trade Commission (ITC) for importing GPS devices allegedly infringing on SiRF Technology patents. See ITC case 337-TA-596. A hearing was held 13th-19th March 2008. The case was determined in March 2010 as there being no infringement in ITC Publication 4133 {PDF} which provides confirmation that Global Locate and later Broadcom supply the Global Locate Library (GLL) and API to customers (page 102). In that document Complainants Exhibit 19C (CX-19C) is said to be the "document that describes the GLL APIs". So far I've been unable to locate the court's case notes to determine a Global Locate/Broadcom reference number or title for that document.

Fujitsu/Global Locate GL-16000 GPS Baseband Processor {Fujitsu PDF}

Global Locate GL-20000 GPS Baseband Processor {Internet Archive 2006-10-16}

Early devices known to contain the silicon and GLL driver are HTC Sable a.k.a. Compaq iPaq 6915 and OpenMoko Neo 1973 (GTA01) which is specified as the Global Locate Hammerhead PMB 2520 {Internet Archive 2007-03-25} which provides a PMB 2520 Product Brief {Internet Archive PDF}.

Open Moko GTA1 GLLin utility

Open Moko provided gllin, a userspace driver for the A-GPS which interfaces with the A-GPS chip-set and outputs NMEA. The binary packages can be extracted easily on an Debian-based system since the ".ipk" files are Debian binary archives (better known as ".deb"):

$ dpkg-deb -R gllin_1.1+r931-r0_om-gta01.ipk gllin_1.1
$ cd gllin_1.1

This is a minimal driver but appears to contain the essential code for talking to the chip-set. Function names, constants, and text strings within the binary indicate the source code used to build it (circa 2007) is a direct predecessor of the current (2013) Linux/Android and Windows drivers.

Sphyrna Hammerhead (MEIF) Protocol Reverse Engineering project

Some Open Moko hackers (Mike Montour, Philipp Zabel, 'Elvenlord Elrond') began reverse engineering the Hammerhead communications protocol in 2007. The project was called "Sphyrna - Hammerhead Reverse Engineering" but unfortunately its project web-site went off-line in 2012. However, thanks to the Internet Archive a version of Sphyrna from 2010-07-14 is readable. Even more fortunately, that site has an SCM page (Source Code Management) that instructs on how developers should checkout the code using SVN. The SVN repository still exists. To get the code:

$ pwd
/home/all/Library/Projects/Replicant/GPS/meif_protocol
$ cd ..
$ git svn clone svn://projects.linuxtogo.org/svn/sphyrna sphyrna
$ cd meif_protocol
$ git submodule add $(pwd)/../sphyrna research/sphyrna
$ git commit -m 'research: add Sphyrna Hammerhead protocol reverse engineering project as a sub-module'

I've included that SVN repository (as a git sub-module repository) in the research/sphyrna/ directory so that all F/OSS research is kept together.

Within the sphyrna repository is the file doc/packet-format.txt which details the structure of packets to and from the device. The values match what we see with the Android Samsung gpsd log files and strace captures.

Comparing GLLin and Hammerhead Protocol with GNSS GLL and MEIF

One hacker, "Christian", captured an strace log which is still available {archive.org}. Line 256 of the strace log seems to confirm that the Hammerhead chips use the same protocol as the current Broadcom silicon; at least the communications look very similar including starting with the auto-baud-rate detection sequence (albeit sending 22 0x80 not 20 as now):

256   write(3, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80", 16) = 16

The source code filenames shown in the debug info in gllin look similar to that in the Broadcom GNSS driver, too:

$ strings ../OpenMoko/gllin_1.1/usr/share/gllin/bin/gllin | grep cpp | sort -u
acqmgr/acqmgr_act.cpp
acqmgr/acqmgr_auto.cpp
acqmgr/acqmgr.cpp
acqmgr/acqmgr_space.cpp
acqmgr/timemgr.cpp
api/glapifreq.cpp
api/glapitime.cpp
api/glctrl_buffer.cpp
api/glctrl.cpp
api/glltodnld.cpp
api/GlNetworkInitiatedRequest.cpp
api/glnmea.cpp
api/GlPeriodicRequest.cpp
api/glpwr.cpp
api/glrequest.cpp
api/glsetaidacq.cpp
api/glsettings.cpp
api/GlSingleShotRequest.cpp
api/GlTestModeRequest.cpp
api/incomingdata.cpp
api/storage.cpp
arithmetics/glmatrix.cpp
asicmgr/asiccom.cpp
asicmgr/asicmgr.cpp
asicmgr/asicmgrifc.cpp
asicmgr/bbpll.cpp
asicmgr/channel.cpp
asicmgr/cop.cpp
asicmgr/estsigstr.cpp
asicmgr/m1mgr.cpp
asicmgr/m1peak.cpp
asicmgr/m3mgr.cpp
asicmgr/platformtest.cpp
asicmgr/pwrmgr.cpp
asicmgr/rfpll.cpp
dsp/m3hsscop.cpp
dsp/m3lsscop.cpp
dsp/m3mixcop.cpp
dsp/m3navcop.cpp
dsp/m3splx.cpp
dsp/m3towcop.cpp
glframe/glactive.cpp
glframe/glframe.cpp
glframe/glqueue.cpp
glframe/gltimer.cpp
glframe/qhsm.cpp
glframe/qhsm_dyn.cpp
navdata/frmmgr.cpp
navdata/sfrmmgr.cpp
navdata/strmgr.cpp
navmodel/almmgr.cpp
navmodel/ephmgr.cpp
navmodel/ltomgr.cpp
navmodel/msmtmgr.cpp
navmodel/navengine.cpp
navmodel/navengineskf.cpp
navmodel/navengineskf_qa.cpp
navmodel/navmodel.cpp
navmodel/rcvrmodel.cpp
navmodel/sviter.cpp
navmodel/timerefiner.cpp
navmodel/windmgr.cpp
srchobj/srchobjbit.cpp
srchobj/srchobj.cpp
srchobj/srchobjdly.cpp
srchobj/srchobjnav.cpp
srchobj/srchobjtow.cpp

Generate a list of class::method and function names from an IDA Pro code listing (File > Produce File > Create LST file...) using:

$ utils/ida_pro_functionnames_from_lst_file.gawk ../OpenMoko/gllin_1.1/usr/share/gllin/bin/gllin.lst | sort | egrep -v '^_ZN' > research/gllin_functions.md

$ utils/gen_html.sh research/gllin_functions.md research/gllin_functions.html

After generating HTML from the Markdown the listing is in gllin_functions.html

Common Driver observations

Both Linux/Android and Windows drivers are built from the same source code. Both sets of binaries contain debug data including the paths and names of each source file. Both contain identical strings (char arrays), data structures, tables, and hardware references.

Windows-specific Driver observations

Functionality is spread over several system dynamic link libraries.

The Position Engine with the MEIF and SLOG functionality is contained in BcmGnss.dll. The driver includes a standard C library from Dinkumware:

$ strings BcmGnss.dll | grep Dinkum
Copyright (c) 1992-2004 by P.J. Plauger, licensed by Dinkumware, Ltd. ALL RIGHTS RESERVED.

Dell BCM4571 Standalone GPS driver:

$ ls -al *.dll | while read a b c d size month date year filename; do echo "$a $b $c $d $size $month $date $year $(md5sum $filename)"; done
-rw-rw-r-- 1 tj tj 428616 Oct 4 2012 3a4f26a70edbad92eb0e75e97535f3ee  BcmGnssAtRil.dll
-rw-rw-r-- 1 tj tj 4510792 Oct 4 2012 2e322faf7f715200bcaa7db5aac6ec9c  BcmGnss.dll
-rw-rw-r-- 1 tj tj 54344 Oct 4 2012 240e282e087554d8c3847d8fcd1fab93  BcmGnssGpioAcpi.dll
-rw-rw-r-- 1 tj tj 205384 Oct 4 2012 85ba83e8c604dd779fabed510f295a42  BcmGnssLocationSensor.dll

Lenovo Broadcom GNSS Gelocation driver

$ ls -al *.dll | while read a b c d size month date year filename; do echo "$a $b $c $d $size $month $date $year $(md5sum $filename)"; done
-rw-rw-r-- 1 tj tj 429128 Oct 30 2012 0e0487930734ee6a913e274a5aaab462  BcmGnssAtRil.dll
-rw-rw-r-- 1 tj tj 4510792 Oct 30 2012 e84f9c7a36b5fe6e46dfb9c5d8ae93b4  BcmGnss.dll
-rw-rw-r-- 1 tj tj 54344 Oct 30 2012 1d49168fba08e7e5c997a857aac90b4b  BcmGnssGpioAcpi.dll
-rw-rw-r-- 1 tj tj 214600 Oct 30 2012 3dc7ab62f80978d10a89696b8f4009d3  BcmGnssLocationSensor.dll

The Lenovo driver also contains several Windows portable debug (PDB) files for the DLLs.

$ ls -al *.pdb | while read a b c d size month date year filename; do echo "$a $b $c $d $size $month $date $year $(md5sum $filename)"; done
-rw-rw-r-- 1 tj tj 4205568 Oct 30 2012 448fa2d81a5e44274e9b0faa0be52779  BcmGnssAtRil.pdb
-rw-rw-r-- 1 tj tj 1436672 Oct 30 2012 8dbc9fd3c93ba2995a6b1f522c07caa9  BcmGnssBus.pdb
-rw-rw-r-- 1 tj tj 1093632 Oct 30 2012 bff90eee5726e12dc44237e151b2a524  bcmgnssgpioacpi.pdb
-rw-rw-r-- 1 tj tj 5327872 Oct 30 2012 4a7ac6a88ebf9cf6bb2efb68796014ce  BcmGnssLocationSensor.pdb

Acer Tablet Iconia W W510P

See the page Acer Tablet Iconia W510P GPS Driver for a long listing of the UTF-8 and ASCII strings in these files. That was auto-generating using:

$ pwd
/home/all/Library/Projects/Replicant/GPS/meif_protocol
$ cd ..
$ mkdir Acer_Tablet_IconiaW_W510P
$ cd Acer_Tablet_IconiaW_W510P
$ unzip ../Acer_Tablet_IconiaW_W510P_W8_32bit_Driver-Package.zip 
# ...
# the following commands pipe finds all files in the GPS/ section and for each one,
# generates a Markdown <h2> with just the filename followed by a code block
# containing the UTF-8 and ASCII strings stripped of all duplicate lines
# (but not of garbage lines that strings selected wrongly) and then pipes
# everything to a Markdown text file in the project directory.
#
$ find Driver_Acer_2.12_W8x86/MI/Drivers/GPS -type f | while read f; do echo; echo "## ${f##*/} ##"; echo '```'; strings -e l $f | awk '!x[$0]++'; echo; strings $f | awk '!x[$0]++'; echo '```'; done  > ../meif_protocol/research/Acer_Tablet_IconiaW_W510P_W8_Driver.md

Here's the list of GPS-related files.

$ find . -wholename './Driver_Acer_2.12_W8x86/MI/Drivers/GPS/*' | sort
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssAtRil.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/bcmgnssbus.cat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssBus.inf
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssBus.pdb
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssBus.sys
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssConfig.xml
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnss.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssGpioAcpi.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/bcmgnsslocationsensor.cat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssLocationSensor.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssLocationSensor.inf
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BcmGnssLocationSensor.pdb
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/BinscopeReport.xml
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Bringup.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/install_47511.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/install_4751.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/install.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/install_pdb.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/BCM2076.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/BCM4750.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/BCM47511.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/BCM4751.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/BCM4752.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Check_Position_Report.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Check_Signal_Reception.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Cold_Starts.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/CollectAlmanac.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/CollectEphemeris.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/CollectEphemerisOff.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/CollectEphemerisOn.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Delete_STO.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Factory_High_SNR.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Far.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Hot_Starts.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LOG_All.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LOG_DEBUG.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LOG_Default.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LOG_NMEA.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LogOff.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LogOn.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Log_Path.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LogRawByteStreamOff.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/LogRawByteStreamOn.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Lost_Starts.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/NetworkIoOff.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/NetworkIoOn.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/OS_Type.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/rflog.py
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Sensor
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Sensor/DetectCrash.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Sensor/Enable_Driver_Open_Close_Client_Disable_Driver.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Sensor/No_Client_Disable_Enable_Driver.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Sensor/Open_Client_Enable_Disable_Driver.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Sensor/Open_Close_Client.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/SerialLog.py
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Serial_Stress_Need_Satellites.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Serial_Stress_No_Satellites.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Serial_Validate.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Serial_Validate_Endless.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Serial_Validate_Offline.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/SUPL_ATT.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/SUPL_IOT.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/SUPL_Off.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/SUPL_ULTS.reg
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Utilities
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Utilities/KernelDebug.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Utilities/KernelDebugOff.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Utilities/PrepareDriverInstallation.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Utilities/Reboot.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Utilities/Shutdown.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tests/Warm_Starts.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/devcon.exe
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/GlgpsRunDll.exe
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/ProcessHacker.Common.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/ProcessHacker.Native.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/SensorDiagnosticTool.exe
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/ShellBasics.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/Start_IRM_Single.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/Stop_IRM.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/traceview.exe
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/udpclient.exe
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/Tools/Windows7.SensorAndLocation.dll
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/uninstall.bat
./Driver_Acer_2.12_W8x86/MI/Drivers/GPS/uninstall.reg

Linux/Android-specific Driver observations