---
title: "HAL vs G-Code Pins in LinuxCNC: Two Layers, Not One"
description: "HAL wires the machine's hardware; G-code commands its motion. They meet at named signals, and confusing the two layers is the classic LinuxCNC beginner trap."
url: https://gcodepractice.com/journal/hal-to-g-code-pins-linuxcnc-explained/
canonical: https://gcodepractice.com/journal/hal-to-g-code-pins-linuxcnc-explained/
author: "Lawrence Arya"
authorUrl: https://www.linkedin.com/in/vibecoding/
published: 2026-06-07
updated: 2026-06-07
category: "Code reference"
tags: ["linuxcnc", "hal", "configuration", "concepts"]
lang: en
---

# HAL vs G-Code Pins in LinuxCNC: Two Layers, Not One

> **TL;DR** LinuxCNC splits into two layers that beginners constantly conflate: HAL, the Hardware Abstraction Layer, wires the machine's real signals (step generators, limit switches, spindle control, I/O) by connecting named pins, while G-code is the part program that commands motion and operations. They are not the same vocabulary and not edited in the same place: HAL lives in .hal configuration files and defines what the machine physically is, G-code lives in .ngc programs and defines what a job does. The bridge is that some G-code actions (M-codes, spindle, custom outputs) ultimately drive HAL pins, but you write parts in one layer and wire the machine in the other.

The fastest way to stay confused about LinuxCNC is to treat HAL and G-code as one topic, and the fastest way to understand it is to see them as two layers that touch in exactly one place. G-code is the part program, what to cut. HAL is the machine's wiring, how the machine is built. A person can be fluent in one and never open the other, which is the clearest sign they were never the same thing.

## Why LinuxCNC even has two layers

Closed controls hide this split because the builder did the wiring at the factory and welded it shut: a Fanuc operator never thinks about HAL-equivalent plumbing because Fanuc, the machine builder, and the dealer settled it before the machine shipped. LinuxCNC exposes the split because it is the control for machines nobody pre-built for you, retrofits, homebuilt mills, one-off configurations, where the person running the machine is often the person who wired it. The two-layer design is the price and the power of that openness: you get to define what the machine is, which means you have to, and keeping that job mentally separate from writing part programs is what this whole topic is about.

## The two layers, placed

| Layer | What it defines | Where it lives | When you touch it |
| --- | --- | --- | --- |
| G-code | What a job does: motion, operations | .ngc program files | Every part, every program |
| HAL | What the machine is: signal wiring | .hal configuration files | Setup, retrofit, hardware changes |

[HAL](https://linuxcnc.org/docs/html/hal/intro.html), the Hardware Abstraction Layer, is LinuxCNC's answer to a real problem: the same control software has to drive wildly different hardware, step-and-direction drives, servo interfaces, whatever sensors and outputs a builder bolted on, and [hardware abstraction](https://en.wikipedia.org/wiki/Hardware_abstraction) is the standard computing solution, a layer of named connection points (pins) wired together with signals so the software does not care what physical device sits behind each one. The [Mesa-card explainer](/journal/mesa-card-linuxcnc-g-code-practice/) covers the hardware end of that wiring; this is the concept underneath it.

[G-code](https://linuxcnc.org/docs/html/gcode/g-code.html) is the other layer entirely: the part program, the same standard language this whole site drills, defining the motion and operations of a job. It does not know or care how the machine is wired, which is the entire point of the abstraction below it.

## Where the layers actually meet

They connect at the bridge between intent and hardware. G-code motion becomes commanded positions that HAL routes to whatever drives are wired in; discrete G-code actions, spindle on with M03, coolant with M08, a [custom M-code](/journal/custom-m-codes-in-linuxcnc-setup/), ultimately toggle HAL pins connected to that hardware. So when you write M08 and coolant flows, the path is: G-code action, to the motion controller, to a HAL pin, to a wired output, to a relay. You authored the first link; HAL configuration, done once, built the rest.

This is why the same M-code does different physical things on different LinuxCNC machines: the G-code is identical, the HAL wiring behind it is per-build, exactly the [configuration layer that DIY troubleshooting](/journal/printnc-diy-machine-g-code-troubleshooting/) treats as its own suspect.

## The trap, and who falls into it

The beginner trap is trying to learn them together, or worse, editing HAL to change a part. The clean separation: a machinist running a configured LinuxCNC machine writes G-code and may never open a .hal file, while a builder or retrofitter lives in HAL during setup, adding a probe, remapping an output, routing a new sensor, and then leaves it alone to write parts in G-code like everyone else. The two roles, operator and machine-builder, map exactly onto the two layers, and on a [retrofit you wear both hats](/journal/retrofit-bridgeport-mill-basic-g-code-programming/), which is precisely when keeping the layers mentally separate matters most.

## The learning order

G-code first, always: it is the portable skill that reads on every machine ever built, and the free 60-second rounds on the [G-code practice page](/g-code-practice/) drill exactly that core. HAL comes when the machine itself needs attention, building one, fixing one, changing one, and at that point it is a focused configuration topic with its own documentation, not a prerequisite for programming. The mental model that prevents months of confusion fits in one line: G-code is what you cut, HAL is how the machine is wired, and the only place they touch is where your intent reaches a physical pin.

## Sources

- [LinuxCNC: HAL introduction](https://linuxcnc.org/docs/html/hal/intro.html)
- [LinuxCNC: G-code reference](https://linuxcnc.org/docs/html/gcode/g-code.html)
- [Wikipedia: Hardware abstraction](https://en.wikipedia.org/wiki/Hardware_abstraction)

## Frequently asked questions

### What is the difference between HAL and G-code in LinuxCNC?

Two layers: HAL wires the machine's physical signals by connecting named pins, defining what the machine is, while G-code is the part program defining what a job does. HAL lives in .hal config files set up once per machine; G-code lives in .ngc programs that change per part.

### Do I edit HAL to write a CNC program?

No, and confusing the two is the classic beginner trap: you write programs in G-code and touch HAL only when configuring or modifying the machine itself. An operator on a configured machine may never open a HAL file.

### What are HAL pins?

Named connection points on HAL components, step generator outputs, driver inputs, switch signals, wired together with signals so the right outputs reach the right hardware. It is like patching a panel in software, a separate skill from writing part programs.

### How does G-code connect to HAL pins in practice?

G-code motion becomes commanded positions HAL routes to the drives, and actions like M03 or M08 toggle HAL pins wired to that hardware. You program intent in standard G-code; HAL determines which physical pin it reaches.

---

Source: https://gcodepractice.com/journal/hal-to-g-code-pins-linuxcnc-explained/
Author: Lawrence Arya — https://www.linkedin.com/in/vibecoding/
