$30 off During Our Annual Pro Sale. View Details »

Josh Triplett - Networking without an OS

Josh Triplett - Networking without an OS

Many Python modules, such as socket and select, wrap low-level functionality written in C and provided by the OS. But what if you don't have an OS, and don't want any C code? We implemented client and server networking in Python itself, for a bare-metal environment running without an OS.

Our socket and select implementations support Python HTTP server and client modules, which we'll demo live.

https://us.pycon.org/2016/schedule/presentation/1945/

PyCon 2016

May 29, 2016
Tweet

More Decks by PyCon 2016

Other Decks in Programming

Transcript

  1. Networking without an OS
    Josh Triplett
    [email protected]
    PyCon 2016

    View Slide

  2. View Slide

  3. View Slide

  4. Porting Python to run without an OS

    View Slide

  5. PyCon 2015
    BIOS Implementation Test Suite (BITS)
    Python in GRUB and EFI, without an OS
    Explore and test hardware and firmware

    View Slide

  6. View Slide

  7. View Slide

  8. BITS Capabilities
    Interactive Python interpreter (with line editing and tab completion)

    View Slide

  9. BITS Capabilities
    Interactive Python interpreter (with line editing and tab completion)
    Direct access to hardware and physical memory

    View Slide

  10. BITS Capabilities
    Interactive Python interpreter (with line editing and tab completion)
    Direct access to hardware and physical memory
    Python can call EFI firmware protocols via ctypes

    View Slide

  11. BITS Capabilities
    Interactive Python interpreter (with line editing and tab completion)
    Direct access to hardware and physical memory
    Python can call EFI firmware protocols via ctypes
    Most of the Python standard library

    View Slide

  12. Most of the Python standard library

    View Slide

  13. Most of the Python standard library
    Some modules don’t make sense
    without an OS

    View Slide

  14. os.execve
    os.fork

    View Slide

  15. os.execve
    os.fork
    multiprocessing
    popen2
    subprocess

    View Slide

  16. os.execve
    os.fork
    multiprocessing
    popen2
    subprocess
    webbrowser

    View Slide

  17. import antigravity

    View Slide

  18. socket
    select

    View Slide

  19. socket
    select
    urllib2
    httplib
    SocketServer
    BaseHTTPServer

    View Slide

  20. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    EFI_TCP4_PROTOCOL

    View Slide

  21. Why networking in firmware?
    Send scripts or test data into the machine

    View Slide

  22. Why networking in firmware?
    Send scripts or test data into the machine
    Read test data or logs from the machine

    View Slide

  23. Why networking in firmware?
    Send scripts or test data into the machine
    Read test data or logs from the machine
    Avoid relying on a writable filesystem

    View Slide

  24. Why networking in firmware?
    Send scripts or test data into the machine
    Read test data or logs from the machine
    Avoid relying on a writable filesystem
    Speed up edit/compile/boot/run cycle

    View Slide

  25. Demo

    View Slide

  26. Bridging EFI networking and Python sockets
    Could call EFI network protocols directly
    Want compatibility with existing Python networking code
    Python modules import socket and select
    socket (Python) imports _socket (C)

    View Slide

  27. Sockets overview
    “Berkeley” sockets

    View Slide

  28. Sockets overview
    “Berkeley” sockets
    Standard on UNIX/POSIX systems, and on Windows via WinSock

    View Slide

  29. Sockets overview
    “Berkeley” sockets
    Standard on UNIX/POSIX systems, and on Windows via WinSock
    Focusing exclusively on TCP/IP connections

    View Slide

  30. Creating a socket
    int s = socket(AF_INET, SOCK_STREAM, 0);

    View Slide

  31. Creating a socket
    int s = socket(AF_INET, SOCK_STREAM, 0);
    AF_INET - IP

    View Slide

  32. Creating a socket
    int s = socket(AF_INET, SOCK_STREAM, 0);
    AF_INET - IP
    SOCK_STREAM - TCP

    View Slide

  33. Creating a socket
    int s = socket(AF_INET, SOCK_STREAM, 0);
    AF_INET - IP
    SOCK_STREAM - TCP
    Can use s as either client or server socket

    View Slide

  34. Client socket
    socket

    View Slide

  35. Client socket
    socket
    connect

    View Slide

  36. Client socket
    socket
    connect
    struct sockaddr

    View Slide

  37. Client socket
    socket
    connect
    struct sockaddr
    send/recv

    View Slide

  38. Client socket
    socket
    connect
    struct sockaddr
    send/recv
    close

    View Slide

  39. Server socket
    socket

    View Slide

  40. Server socket
    socket
    bind

    View Slide

  41. Server socket
    socket
    bind
    struct sockaddr

    View Slide

  42. Server socket
    socket
    bind
    struct sockaddr
    listen

    View Slide

  43. Server socket
    socket
    bind
    struct sockaddr
    listen
    accept - returns a new connected socket

    View Slide

  44. Server socket
    socket
    bind
    struct sockaddr
    listen
    accept - returns a new connected socket
    send/recv

    View Slide

  45. Server socket
    socket
    bind
    struct sockaddr
    listen
    accept - returns a new connected socket
    send/recv
    close

    View Slide

  46. select - waiting for activity
    Pass sets of file descriptors to monitor for reading and for writing

    View Slide

  47. select - waiting for activity
    Pass sets of file descriptors to monitor for reading and for writing
    And for exceptions, but ignoring that here

    View Slide

  48. select - waiting for activity
    Pass sets of file descriptors to monitor for reading and for writing
    And for exceptions, but ignoring that here
    Pass a timeout

    View Slide

  49. select - waiting for activity
    Pass sets of file descriptors to monitor for reading and for writing
    And for exceptions, but ignoring that here
    Pass a timeout
    Waits for a connected socket to have data to recv or send

    View Slide

  50. select - waiting for activity
    Pass sets of file descriptors to monitor for reading and for writing
    And for exceptions, but ignoring that here
    Pass a timeout
    Waits for a connected socket to have data to recv or send
    Waits for a listening socket to have a connection

    View Slide

  51. select - waiting for activity
    Pass sets of file descriptors to monitor for reading and for writing
    And for exceptions, but ignoring that here
    Pass a timeout
    Waits for a connected socket to have data to recv or send
    Waits for a listening socket to have a connection
    Core of the main loop in most network servers

    View Slide

  52. select - waiting for activity
    Pass sets of file descriptors to monitor for reading and for writing
    And for exceptions, but ignoring that here
    Pass a timeout
    Waits for a connected socket to have data to recv or send
    Waits for a listening socket to have a connection
    Core of the main loop in most network servers
    Many OS-specific replacements for scalability and performance

    View Slide

  53. Python bindings
    import socket, select

    View Slide

  54. Python bindings
    import socket, select
    s = socket.socket() - defaults to TCP/IP

    View Slide

  55. Python bindings
    import socket, select
    s = socket.socket() - defaults to TCP/IP
    s.connect

    View Slide

  56. Python bindings
    import socket, select
    s = socket.socket() - defaults to TCP/IP
    s.connect
    s.bind, s.listen, s.accept

    View Slide

  57. Python bindings
    import socket, select
    s = socket.socket() - defaults to TCP/IP
    s.connect
    s.bind, s.listen, s.accept
    s.sendall, s.recv

    View Slide

  58. Python bindings
    import socket, select
    s = socket.socket() - defaults to TCP/IP
    s.connect
    s.bind, s.listen, s.accept
    s.sendall, s.recv
    rl,wl,xl = select.select([s],[],[])
    if s in rl:

    View Slide

  59. CPython implementation
    socketmodule.c and selectmodule.c

    View Slide

  60. CPython implementation
    socketmodule.c and selectmodule.c
    Extensive dependencies on POSIX and on C sockets API

    View Slide

  61. CPython implementation
    socketmodule.c and selectmodule.c
    Extensive dependencies on POSIX and on C sockets API
    Would have to implement those APIs in C

    View Slide

  62. CPython implementation
    socketmodule.c and selectmodule.c
    Extensive dependencies on POSIX and on C sockets API
    Would have to implement those APIs in C
    Handle C arguments, addresses, buffer management

    View Slide

  63. CPython implementation
    socketmodule.c and selectmodule.c
    Extensive dependencies on POSIX and on C sockets API
    Would have to implement those APIs in C
    Handle C arguments, addresses, buffer management
    Would have to call EFI protocols from C

    View Slide

  64. CPython implementation
    socketmodule.c and selectmodule.c
    Extensive dependencies on POSIX and on C sockets API
    Would have to implement those APIs in C
    Handle C arguments, addresses, buffer management
    Would have to call EFI protocols from C
    Or, have many callbacks from C to Python

    View Slide

  65. BITS implementation
    C helper for safe asynchronous event handling
    Otherwise entirely Python
    Python makes all EFI protocol calls

    View Slide

  66. Calling EFI from Python via ctypes

    View Slide

  67. Behind the scenes
    efi.system_table is a data structure

    View Slide

  68. Behind the scenes
    efi.system_table is a data structure
    efi.system_table.ConOut is a pointer to a protocol

    View Slide

  69. Behind the scenes
    efi.system_table is a data structure
    efi.system_table.ConOut is a pointer to a protocol
    .contents dereferences a ctypes pointer

    View Slide

  70. Behind the scenes
    efi.system_table is a data structure
    efi.system_table.ConOut is a pointer to a protocol
    .contents dereferences a ctypes pointer
    Most EFI calls expect a “this” pointer

    View Slide

  71. Behind the scenes
    efi.system_table is a data structure
    efi.system_table.ConOut is a pointer to a protocol
    .contents dereferences a ctypes pointer
    Most EFI calls expect a “this” pointer
    ctypes converts "Hello world\r\n" to a Unicode string

    View Slide

  72. Behind the scenes
    efi.system_table is a data structure
    efi.system_table.ConOut is a pointer to a protocol
    .contents dereferences a ctypes pointer
    Most EFI calls expect a “this” pointer
    ctypes converts "Hello world\r\n" to a Unicode string
    ctypes returns the error code from EFI

    View Slide

  73. Resource management
    EFI uses manual memory management

    View Slide

  74. Resource management
    EFI uses manual memory management
    Python uses garbage collection

    View Slide

  75. Resource management
    EFI uses manual memory management
    Python uses garbage collection
    Python GC doesn’t know about references from EFI

    View Slide

  76. Resource management
    EFI uses manual memory management
    Python uses garbage collection
    Python GC doesn’t know about references from EFI
    Must keep Python object alive as long as EFI references it

    View Slide

  77. Resource management
    EFI uses manual memory management
    Python uses garbage collection
    Python GC doesn’t know about references from EFI
    Must keep Python object alive as long as EFI references it
    Must explicitly free EFI resources when no longer referenced from
    Python

    View Slide

  78. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL

    View Slide

  79. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    Read current IP configuration, or start IP configuration

    View Slide

  80. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    Read current IP configuration, or start IP configuration
    EFI_TCP4_SERVICE_BINDING_PROTOCOL

    View Slide

  81. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    Read current IP configuration, or start IP configuration
    EFI_TCP4_SERVICE_BINDING_PROTOCOL
    Create a new EFI_TCP4_PROTOCOL, like socket()

    View Slide

  82. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    Read current IP configuration, or start IP configuration
    EFI_TCP4_SERVICE_BINDING_PROTOCOL
    Create a new EFI_TCP4_PROTOCOL, like socket()
    EFI_TCP4_PROTOCOL

    View Slide

  83. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    Read current IP configuration, or start IP configuration
    EFI_TCP4_SERVICE_BINDING_PROTOCOL
    Create a new EFI_TCP4_PROTOCOL, like socket()
    EFI_TCP4_PROTOCOL
    EFI socket API: Configure, Connect, Accept, Transmit, Receive, Close

    View Slide

  84. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    Read current IP configuration, or start IP configuration
    EFI_TCP4_SERVICE_BINDING_PROTOCOL
    Create a new EFI_TCP4_PROTOCOL, like socket()
    EFI_TCP4_PROTOCOL
    EFI socket API: Configure, Connect, Accept, Transmit, Receive, Close

    View Slide

  85. EFI networking protocols
    EFI_IP4_CONFIG2_PROTOCOL
    Read current IP configuration, or start IP configuration
    EFI_TCP4_SERVICE_BINDING_PROTOCOL
    Create a new EFI_TCP4_PROTOCOL, like socket()
    EFI_TCP4_PROTOCOL
    EFI socket API: Configure, Connect, Accept, Transmit, Receive, Close
    Glossing over quirks, bugs, error handling, workarounds,
    and compatibility with older versions

    View Slide

  86. Impedance mismatch: select versus Receive/Accept
    select checks for pending data or connections

    View Slide

  87. Impedance mismatch: select versus Receive/Accept
    select checks for pending data or connections
    Does not read data or accept connection

    View Slide

  88. Impedance mismatch: select versus Receive/Accept
    select checks for pending data or connections
    Does not read data or accept connection
    EFI can only check for data by calling Receive with a valid buffer

    View Slide

  89. Impedance mismatch: select versus Receive/Accept
    select checks for pending data or connections
    Does not read data or accept connection
    EFI can only check for data by calling Receive with a valid buffer
    Solution: buffer received data, call Receive when buffer empty

    View Slide

  90. Impedance mismatch: select versus Receive/Accept
    select checks for pending data or connections
    Does not read data or accept connection
    EFI can only check for data by calling Receive with a valid buffer
    Solution: buffer received data, call Receive when buffer empty
    Likewise for Accept

    View Slide

  91. Impedance mismatch: select versus Receive/Accept
    select checks for pending data or connections
    Does not read data or accept connection
    EFI can only check for data by calling Receive with a valid buffer
    Solution: buffer received data, call Receive when buffer empty
    Likewise for Accept
    Similar to the implementation of sockets in an OS kernel

    View Slide

  92. Impedance mismatch: Poll
    EFI_TCP4_PROTOCOL not updated directly from low-level interrupts

    View Slide

  93. Impedance mismatch: Poll
    EFI_TCP4_PROTOCOL not updated directly from low-level interrupts
    Data processed infrequently, even with asynchronous call running

    View Slide

  94. Impedance mismatch: Poll
    EFI_TCP4_PROTOCOL not updated directly from low-level interrupts
    Data processed infrequently, even with asynchronous call running
    Caller expected to call Poll periodically if waiting

    View Slide

  95. Impedance mismatch: Poll
    EFI_TCP4_PROTOCOL not updated directly from low-level interrupts
    Data processed infrequently, even with asynchronous call running
    Caller expected to call Poll periodically if waiting
    Improves performance by orders of magnitude

    View Slide

  96. Impedance mismatch: Poll
    EFI_TCP4_PROTOCOL not updated directly from low-level interrupts
    Data processed infrequently, even with asynchronous call running
    Caller expected to call Poll periodically if waiting
    Improves performance by orders of magnitude
    Solution: call Poll inside helpers for select

    View Slide

  97. Impedance mismatch: asynchronous callbacks
    All EFI socket calls asynchronous

    View Slide

  98. Impedance mismatch: asynchronous callbacks
    All EFI socket calls asynchronous
    Calls take a “completion token” with EFI_EVENT to signal when done

    View Slide

  99. Impedance mismatch: asynchronous callbacks
    All EFI socket calls asynchronous
    Calls take a “completion token” with EFI_EVENT to signal when done
    For sockets, EFI_EVENT must have a callback function

    View Slide

  100. Impedance mismatch: asynchronous callbacks
    All EFI socket calls asynchronous
    Calls take a “completion token” with EFI_EVENT to signal when done
    For sockets, EFI_EVENT must have a callback function
    Need to handle callback safely from Python

    View Slide

  101. Python concurrency model
    Python expects bytecode ops and C calls to run to completion

    View Slide

  102. Python concurrency model
    Python expects bytecode ops and C calls to run to completion
    Global Interpreter Lock (GIL)

    View Slide

  103. Python concurrency model
    Python expects bytecode ops and C calls to run to completion
    Global Interpreter Lock (GIL)
    Data may have inconsistent state when callback occurs

    View Slide

  104. Python concurrency model
    Python expects bytecode ops and C calls to run to completion
    Global Interpreter Lock (GIL)
    Data may have inconsistent state when callback occurs
    Almost all CPython functions prohibited

    View Slide

  105. Python concurrency model
    Python expects bytecode ops and C calls to run to completion
    Global Interpreter Lock (GIL)
    Data may have inconsistent state when callback occurs
    Almost all CPython functions prohibited
    Same problem arises with Ctrl-C and signals

    View Slide

  106. Py_AddPendingCall
    Register a callback (with context)

    View Slide

  107. Py_AddPendingCall
    Register a callback (with context)
    Python calls it at the next safe point

    View Slide

  108. Py_AddPendingCall
    Register a callback (with context)
    Python calls it at the next safe point
    Can call arbitrary CPython functions from the callback

    View Slide

  109. Handling events
    C module provides event callback function pointer

    View Slide

  110. Handling events
    C module provides event callback function pointer
    Python code creates EFI_EVENT with C callback

    View Slide

  111. Handling events
    C module provides event callback function pointer
    Python code creates EFI_EVENT with C callback
    C callback invokes universal Python callback

    View Slide

  112. Handling events
    C module provides event callback function pointer
    Python code creates EFI_EVENT with C callback
    C callback invokes universal Python callback
    Python callback dispatches to event-specific callback via dict

    View Slide

  113. Handling events
    C module provides event callback function pointer
    Python code creates EFI_EVENT with C callback
    C callback invokes universal Python callback
    Python callback dispatches to event-specific callback via dict
    dict keeps Python objects live while EFI_EVENT references them

    View Slide

  114. Implementing select
    Takes read and write lists of sockets

    View Slide

  115. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict

    View Slide

  116. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires

    View Slide

  117. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires
    Call _read_ready or _write_ready

    View Slide

  118. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires
    Call _read_ready or _write_ready
    _read_ready checks queue, calls Receive or Accept

    View Slide

  119. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires
    Call _read_ready or _write_ready
    _read_ready checks queue, calls Receive or Accept
    If already running from previous call, call Poll

    View Slide

  120. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires
    Call _read_ready or _write_ready
    _read_ready checks queue, calls Receive or Accept
    If already running from previous call, call Poll
    Handle connection closure to provide EOF from recv

    View Slide

  121. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires
    Call _read_ready or _write_ready
    _read_ready checks queue, calls Receive or Accept
    If already running from previous call, call Poll
    Handle connection closure to provide EOF from recv
    Queues data or error when callback called

    View Slide

  122. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires
    Call _read_ready or _write_ready
    _read_ready checks queue, calls Receive or Accept
    If already running from previous call, call Poll
    Handle connection closure to provide EOF from recv
    Queues data or error when callback called
    _write_ready returns true if connected

    View Slide

  123. Implementing select
    Takes read and write lists of sockets
    Or file descriptors; map to sockets via dict
    Loop over sockets until timeout expires
    Call _read_ready or _write_ready
    _read_ready checks queue, calls Receive or Accept
    If already running from previous call, call Poll
    Handle connection closure to provide EOF from recv
    Queues data or error when callback called
    _write_ready returns true if connected
    Always calls Poll if connected

    View Slide

  124. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol

    View Slide

  125. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks

    View Slide

  126. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect

    View Slide

  127. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect
    recv: Return data from queue

    View Slide

  128. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect
    recv: Return data from queue
    Spin on _read_ready if queue empty; this starts a Receive

    View Slide

  129. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect
    recv: Return data from queue
    Spin on _read_ready if queue empty; this starts a Receive
    sendall: Call Transmit; save status for

    View Slide

  130. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect
    recv: Return data from queue
    Spin on _read_ready if queue empty; this starts a Receive
    sendall: Call Transmit; save status for
    bind: Save provided address and port for later calls

    View Slide

  131. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect
    recv: Return data from queue
    Spin on _read_ready if queue empty; this starts a Receive
    sendall: Call Transmit; save status for
    bind: Save provided address and port for later calls
    listen: Call Configure for listening socket

    View Slide

  132. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect
    recv: Return data from queue
    Spin on _read_ready if queue empty; this starts a Receive
    sendall: Call Transmit; save status for
    bind: Save provided address and port for later calls
    listen: Call Configure for listening socket
    accept: Return queued connection if any

    View Slide

  133. class socket
    __init__: Create EFI_TCP4_PROTOCOL from binding protocol
    __del__/close: Cancel all outstanding callbacks
    connect: Call Configure and Connect
    recv: Return data from queue
    Spin on _read_ready if queue empty; this starts a Receive
    sendall: Call Transmit; save status for
    bind: Save provided address and port for later calls
    listen: Call Configure for listening socket
    accept: Return queued connection if any
    Spin on _read_ready if queue empty; this starts an Accept

    View Slide

  134. Socket demo and walkthrough

    View Slide

  135. High-level client demo

    View Slide

  136. High-level server demo

    View Slide

  137. Try it out yourself
    BITS: https://biosbits.org/

    View Slide

  138. Try it out yourself
    BITS: https://biosbits.org/
    QEMU/KVM

    View Slide

  139. Try it out yourself
    BITS: https://biosbits.org/
    QEMU/KVM
    Client works automatically

    View Slide

  140. Try it out yourself
    BITS: https://biosbits.org/
    QEMU/KVM
    Client works automatically
    For server, use hostfwd option to forward ports inside

    View Slide

  141. Try it out yourself
    BITS: https://biosbits.org/
    QEMU/KVM
    Client works automatically
    For server, use hostfwd option to forward ports inside
    OVMF: Open Virtual Machine Firmware, EFI for QEMU

    View Slide

  142. Try it out yourself
    BITS: https://biosbits.org/
    QEMU/KVM
    Client works automatically
    For server, use hostfwd option to forward ports inside
    OVMF: Open Virtual Machine Firmware, EFI for QEMU
    Or try it on physical hardware

    View Slide

  143. Try it out yourself
    BITS: https://biosbits.org/
    QEMU/KVM
    Client works automatically
    For server, use hostfwd option to forward ports inside
    OVMF: Open Virtual Machine Firmware, EFI for QEMU
    Or try it on physical hardware
    Check BIOS settings to enable EFI network stack

    View Slide

  144. Try it out yourself
    BITS: https://biosbits.org/
    QEMU/KVM
    Client works automatically
    For server, use hostfwd option to forward ports inside
    OVMF: Open Virtual Machine Firmware, EFI for QEMU
    Or try it on physical hardware
    Check BIOS settings to enable EFI network stack
    Use wired Ethernet

    View Slide

  145. BIOS Implementation Test Suite (BITS)
    http://biosbits.org/
    Questions?

    View Slide

  146. Networking without an OS
    Demo Backup
    Josh Triplett
    [email protected]
    PyCon 2016

    View Slide

  147. View Slide

  148. View Slide

  149. View Slide

  150. View Slide

  151. View Slide

  152. View Slide

  153. View Slide

  154. View Slide

  155. View Slide

  156. View Slide

  157. View Slide

  158. View Slide

  159. View Slide

  160. View Slide

  161. View Slide

  162. View Slide

  163. View Slide

  164. View Slide

  165. View Slide

  166. View Slide

  167. View Slide

  168. View Slide

  169. View Slide

  170. View Slide

  171. View Slide

  172. View Slide

  173. View Slide

  174. View Slide

  175. View Slide

  176. View Slide

  177. View Slide

  178. View Slide

  179. View Slide

  180. View Slide

  181. View Slide

  182. View Slide

  183. View Slide

  184. View Slide

  185. View Slide