Jun 01 2026

¡GEOS v1.0.0: Emacs como PID 1, con soporte completo GNU/Hurd!

Tag: advanced,internals/hackingadmin @ 2:53 pm

Hace unos meses publiqué la v0.1 de GEOS (GNU/Emacs Operating System), un sistema operativo donde Emacs es a la vez el userland y el PID 1. Hoy etiqueto la v1.0.0. La novedad es que ya no hace falta hablar en condicional sobre GNU/Hurd: Emacs es PID 1 también ahí, con sesión multi-usuario EXWM de extremo a extremo sobre Debian GNU/Hurd 0.9 canónico.

Tésis

Emacs no es un editor que corre sobre un sistema operativo. Emacs ES el sistema operativo. El kernel da abstracción del hardware. Todo lo que hay por encima (supervisión de procesos, shell, gestor de ventanas, visor de logs, gestor de paquetes, configurador de red, asistente de instalación) vive en buffers, escrito en Elisp, evaluable en caliente, introspectable con C-h f.

El primer proceso de userspace que arranca el kernel es un binario en C diminuto que monta los pseudo-filesystems, recoge zombis, lee /etc/hostname, y hace execve a Emacs. El mismo código C se compila una segunda vez como módulo dinámico de Emacs y se carga desde early-init.el, así que el supervisor vive dentro del proceso supervisado. No hay Shepherd. No hay systemd. No hay /etc/init.d. Si esa frase incomoda, bien, debería.

¿Por qué GNU/Hurd?

Porque la pieza que falta del puzzle GNU es la que tiene casi cuarenta años y la gente sigue asumiendo que no se puede usar en serio. Porque «Emacs como PID 1 sobre Linux» tiene su gracia, pero «Emacs como PID 1 sobre el Hurd» cierra el círculo que Stallman dibujó en una nota al pie hace mucho tiempo. Y porque si funciona en los dos kernels, el código está obligado a respetar una capa de abstracción honesta entre lo específico del kernel y lo que no, lo cual mejora la calidad de todo lo demás.

¿Qué funciona en Debian GNU/Hurd 0.9?

  • pid1 arranca a Hurd, hace setup de los traductores correctos, ejecuta execve a emacs y carga el módulo dinámico que expone los primitives del supervisor.
  • Sesión multi-usuario con login, audit, throttle, lockout y footer de último acceso. El handshake de peer-cred usa auth_server_authenticate sobre Hurd (en Linux es SO_PEERCRED).
  • EXWM 0.33 sobre Xvfb. Las ventanas X11 son buffers de Emacs igual que en Linux. Xorg nativo con DRM sobre Hurd queda como trabajo upstream.
  • SSH de extremo a extremo: ssh -p 2266 root@127.0.0.1 abre una sesión interactiva contra el emacs supervisado.
  • Asistente de instalación: el wizard M-x install formatea con mkfs.ext4 e instala GRUB sobre un segundo disco, todo a través de los wrappers Elisp.
  • M-x geos-poweroff y M-x geos-reboot usan host_reboot vía get_privileged_ports en Hurd, y reboot(2) en Linux. No hay /sbin/poweroff al que llamar; el supervisor ES Emacs y la respuesta a «apaga» vive en Elisp.
  • Buffers de sistema: *processes*, *network*, *journal*, *services*, *disks*, *packages*, *users*, *audio*, *install*. Todos vivos con timer de refresco.

Seam port_caps

Cada syscall específico de Linux dentro de pid1/ pasa por un struct de punteros a función. La implementación Linux vive en port_linux.c y la de Hurd en port_hurd.c (esta última en la rama lateral hurd, rebase semanal sobre main). El Elisp por encima nunca sabe sobre qué kernel está corriendo; consulta geos-kernel sólo si necesita decidir algo concreto.

El build STATIC=1 compila el binario emacs-init de Hurd como ejecutable estático puro: cero dependencias dinámicas, alrededor de 1.5 MiB. Eso es lo que se hornea dentro de la imagen derivada cuando ejecuto iso-build/hurd-image-reroll.sh.

Upstream gaps

Dos filas de la matriz de docs/HURD_PORT.md siguen marcadas como «deferred-upstream»:

  • Audio en hardware real sobre Hurd. Debian GNU/Hurd 0.9 canónico no trae /hurd/audio* ni superficie ALSA/OSS. El flavor FLAVOR=apt-image de la imagen derivada empaqueta el userland de PulseAudio para que el lado Elisp tenga con qué hablar; el sink real es trabajo upstream.
  • Contadores por interfaz de pfinet. El arm Elisp pinta ceros hasta que la superficie del traductor exponga los contadores.

Hay ocho hilos abiertos en bug-hurd, debian-hurd y bug-gnu-emacs documentando estos y otros temas: entre ellos un assertion fail de ext2fs file_pager_write_pages bajo apt-install, un comportamiento sospechoso de SO_RCVTIMEO en pflocal, y la ausencia de la integración evdev/libinput en el Xorg de Hurd. Ninguno bloquea GEOS hoy.

¿Cómo probarlo?

Camino fácil, en un host Linux con KVM:

git clone https://github.com/borjatarraso/gnu-emacs-os.git
cd gnu-emacs-os
./iso-build/dev-vm.sh

El primer build descarga unos 8 GiB en /gnu/store; los siguientes tardan segundos. El boot hasta un frame EXWM utilizable son unos once segundos.

Para Hurd, partiendo de una instalación limpia de Debian GNU/Hurd 0.9, basta con ejecutar install/hurd-bootstrap.sh como root y reiniciar. La receta completa (paquetes apt, build, formato de init.args, ruta de rollback) está en docs/HURD_BOOT.md. La ruta alternativa es iso-build/hurd-image-reroll.sh, que hornea una imagen derivada de la canónica con pid1 estático, árbol de supervisor, GRUB serial y authorized_keys ya dentro; se arranca bajo QEMU y se entra por SSH.

Si alguien quiere comparar con la canónica vainilla, GEOS_BYPASS=1 ./iso-build/hurd-image-reroll.sh produce una imagen con /sbin/init stock (bash, sysvinit, getty) en lugar del PID 1 de Emacs, manteniendo las conveniencias del bake (consola serial, claves SSH ya inyectadas).

Limitaciones aceptadas

Emacs es de un solo hilo. Un regex atascado bloquea el OS. Una llamada de red lenta bloquea el OS. Un (while t) bloquea el OS. El buffer *panic* mitiga el caso de los errores Elisp que pasan por condition-case, pero no salva del loop apretado en código C ni de la llamada de red sin timeout. Es una restricción de diseño asumida, no un bug. Pierdo aproximadamente una sesión a la semana por un freeze que tengo que recuperar desde QEMU. Me parece un ratio aceptable. Puede que a ti no, y esa es una razón legítima para no usar este OS.

Demo

Enlaces

Licencia: GPLv3-or-later. Maintainer: borja.tarraso@member.fsf.org.


Sep 01 2024

Configuración de org-mode: TODO + agenda + imágenes + notificaciones

Tag: advancedadmin @ 8:08 am

Con esta configuración de org-mode para emacs podremos movernos de manera más conveniente en org-mode. Definimos algunos keybidings típicos así como activamos el sistema de logs para guardar el accountability de las tareas así como su timestamp. Además guardaremos el estado de las mismas conectándolo con el fichero en tasks.org y activando un sistema de checklist de org-mode. Por último incluiremos los diccionarios de babel, que nos permitirán mostrar imágenes inline, y sintaxis para interpretar los múltiples lenguajes:

;; ---------------------------------------------------------------------------
;; Org-mode configuration
;; ---------------------------------------------------------------------------

(setq org-log-done 'time)
(define-key global-map "\C-cl" 'org-store-link)
(define-key global-map "\C-ca" 'org-agenda)
(setq org-log-done t)

;; Connect agenda with org files
(setq org-agenda-files (list "~/zsync/tasks.org"))

(add-to-list 'load-path (expand-file-name "~/.emacs.d/ch/"))
(require 'org-checklist)

;; Show images inline when opening an org file
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
(add-hook 'org-mode-hook 'org-display-inline-images)

Keybindings para manejar tareas:

  • C-c C-c para finalizar una tarea simple
  • C-c C-t para finalizar un set complejo de tareas
  • C-c a t para marcar como tarea a realizar y marcarla como ‘TODO’

Keybindings para manejar prioridades en las tareas:

  • C-c , to set tasks priority (priority must be on the top of org file)
  • C-c , + para incrementar la prioridad de una tarea
  • C-c , – para decrementar la prioridad de una tarea

Keybindings clave para la agenda:

  • C-c C-d para insertar una fecha limite para un set de tareas (deadline)
  • C-c C-s para añadir al backlog o hacer schedule de un set de tareas (schedule)
  • Una vez haya sido seleccionado la tarea deseada, presiona enter acto seguido C-c a a para org-agenda Now pres ‘l‘ (lower case L) to set log mode on

Keybindings para tiempos sobre tareas:

  • C-c / d para comprobar tareas con una fecha limite (deadlines)
  • C-c / b para comprobar tareas pendientes y deadlines (backlog)
  • C-c / a para comprobar tareas pasadas deadlines (after)

Keybindings para cambiar formas de visualización en tareas:

  • C-c – Cambia la numeración (se debe evitar usarlo sobre los títulos, ya que aquí se ignoraría el TODO)

Después de esto podemos añadir más funcionalidades, como limpiar todos los reminders de la agenda para el día de hoy y volver a construirlos de cero y activar todas las notificaciones de nuevo. Además podemos hacer que esta tarea se ejecute automaticamente después de medianoche.

;; ---------------------------------------------------------------------------
;; Reminders
;; ---------------------------------------------------------------------------

; Erase all reminders and rebuilt reminders for today from the agenda
(defun bh/org-agenda-to-appt ()
(interactive)
(setq appt-time-msg-list nil)
(org-agenda-to-appt))

; Rebuild the reminders everytime the agenda is displayed
(add-hook 'org-finalize-agenda-hook 'bh/org-agenda-to-appt 'append)

; This is at the end of my .emacs - so appointments are set up when Emacs starts
; This line is currently failing, need more investigation
;(bh/org-agenda-to-appt)

; Activate appointments so we get notifications
(appt-activate t)

; If we leave Emacs running overnight - reset the appointments one minute after midnight
(run-at-time "24:01" nil 'bh/org-agenda-to-appt)

Por último podemos cambiar el ciclo de tareas por defecto para tener un TODO-INPROGRESS-WAITING(opcional)-DONE y poder emplear atajos o shortcuts de teclado para ello.

(setq org-todo-keywords
'((sequence "TODO(t!)" "INPROGRESS(i!)" "WAITING(w!/!)" "|" "DONE(d!)")
))

Dic 13 2015

Simbolos

Tag: advancedoverdrive @ 10:39 pm

Es posible, que dependiendo del tipo de escritura que realicemos en GNU/Emacs necesitemos escribir distintos grupos de simbolos. Es obvio que para escribir formulas matematicas usemos por ejemplo LaTeX o simplemente TeX. Sin embargo, cuando escribimos notas en org-mode o directamente en texto plano, quiza deseemos anadir formulas quimicas, el cual necesitaremos anadir simbolos como subindices o superindices, o letras como alfa, beta o delta. Tambien puede ser que nos interese escribir simbolos como copyright, trademark, registered, etc. En otros casos es posible que queramos escribir en otros idiomas directamente o poder usar todo el superset de UTF8.

Empezaremos a mostrar las distintas formas de incluir simbolos segun el interes que tengamos, por ejemplo, para la parte quimica de indices, superindices, y simbolos basicos como alfa, beta o delta (usados tambien en quimica):

  • C-x 8 _ <numero o letra> : inserta como subindice la letra o simbolo dado.
  • C-x 8 ^ <numero o letra> : inserta como superindice la letra o simbolo dado

Para incluir la letras como alfa, beta o delta, existen distintas formas, la primera y no mas facil seria:

  • C-x 8 <RET> <CODIGO UNICODE o HEXADECIMAL> : introduce un simbolo en UTF-8 por su nombre o dado su codigo hexadecimal:
    • <TAB> mostrara todas las posibles opciones
    • GREEK CAPITAL LETTER ALPHA <RET> : insertara la letra alpha griega en mayusculas.
    • GREEK SMALL LETTER ALPHA <RET> : insertara la letra alpha griega en minusculas.
    • ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE <RET> :
    • OLD PERSIAN NUMBER HUNDRED <RET> :

Existen al menos unas 40.000 letras distintas disponibles que se pueden insertar, ya sea por su nombre o por su codigo.

Selection_002

  • M-g <letra en griego> : Insertara directamente letras griegas o definidas en nuestro .emacs. De esta forma podremos por ejemplo insertar rapidamente letras en griego:

;; Greek letters
;; by default can be done with C-c C-x \ GREEK_LETTER (use TAB)
(global-set-key (kbd «M-g a») «α»)
(global-set-key (kbd «M-g b») «β»)
(global-set-key (kbd «M-g g») «γ»)
(global-set-key (kbd «M-g d») «δ»)
(global-set-key (kbd «M-g e») «ε»)
(global-set-key (kbd «M-g z») «ζ»)
(global-set-key (kbd «M-g h») «η»)
(global-set-key (kbd «M-g q») «θ»)
(global-set-key (kbd «M-g i») «ι»)
(global-set-key (kbd «M-g k») «κ»)
(global-set-key (kbd «M-g l») «λ»)
(global-set-key (kbd «M-g m») «μ»)
(global-set-key (kbd «M-g n») «ν»)
(global-set-key (kbd «M-g x») «ξ»)
(global-set-key (kbd «M-g o») «ο»)
(global-set-key (kbd «M-g p») «π»)
(global-set-key (kbd «M-g r») «ρ»)
(global-set-key (kbd «M-g s») «σ»)
(global-set-key (kbd «M-g t») «τ»)
(global-set-key (kbd «M-g u») «υ»)
(global-set-key (kbd «M-g f») «ϕ»)
(global-set-key (kbd «M-g j») «φ»)
(global-set-key (kbd «M-g c») «χ»)
(global-set-key (kbd «M-g y») «ψ»)
(global-set-key (kbd «M-g w») «ω»)
(global-set-key (kbd «M-g A») «Α»)
(global-set-key (kbd «M-g B») «Β»)
(global-set-key (kbd «M-g G») «Γ»)
(global-set-key (kbd «M-g D») «Δ»)
(global-set-key (kbd «M-g E») «Ε»)
(global-set-key (kbd «M-g Z») «Ζ»)
(global-set-key (kbd «M-g H») «Η»)
(global-set-key (kbd «M-g Q») «Θ»)
(global-set-key (kbd «M-g I») «Ι»)
(global-set-key (kbd «M-g K») «Κ»)
(global-set-key (kbd «M-g L») «Λ»)
(global-set-key (kbd «M-g M») «Μ»)
(global-set-key (kbd «M-g N») «Ν»)
(global-set-key (kbd «M-g X») «Ξ»)
(global-set-key (kbd «M-g O») «Ο»)
(global-set-key (kbd «M-g P») «Π»)
(global-set-key (kbd «M-g R») «Ρ»)
(global-set-key (kbd «M-g S») «Σ»)
(global-set-key (kbd «M-g T») «Τ»)
(global-set-key (kbd «M-g U») «Υ»)
(global-set-key (kbd «M-g F») «Φ»)
(global-set-key (kbd «M-g J») «Φ»)
(global-set-key (kbd «M-g C») «Χ»)
(global-set-key (kbd «M-g Y») «Ψ»)
(global-set-key (kbd «M-g W») «Ω»)

  • C-c C-x \ <TAB> : Dentro de org-mode, si lo activamos, podremos escribir directamente simbolos usando una contrabarra seguido de su nombre, por ejemplo:
    • \alpha : escribe la letra griega alfa.
    • \beta : escribe la letra griega beta.
    • \delta : escribe la letra griega delta.
    • \omega : escribe la letra griega omega.
    • \leftarrow : escribe una flecha a la izquierda.
    • \rightarrow : escribe una flecha hacia la derecha.
    • ^numero : escribe el numero elevado o en superscript.
    • _numero : escribe el numero subscript.
    • \copy : pone copyright.
    • \reg : pone registered.
    • \trade : pone trademark.
    • \check : pone un tick o check.

Esta es una lista mas extensa de las distintas opciones de simbolos que podemos anadir: http://orgmode.org/worg/org-symbols.html

  • M-x set-input-method <TAB> : muestra la lista de lenguajes o idiomas en el que podemos poner el layour, pudiendo asi escribir en cualquier idioma, por ejemplo:
    • russian-computer
    • russian-typewriter
    • belarusian
    • chinese-sw
    • farsi-transliterate-banan
    • japanese-hankaku-kana
    • japanese-hiragana
    • greek
    • hebrew

Existen opciones para escoger entre unos 200 idiomas o distintos layouts.

Selection_001


Página siguiente »