Add chainloader test

closes #101
pull/112/head
Andre Richter 3 years ago
parent 07fb63ae5f
commit 8982682d47
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -70,6 +70,7 @@ DOCKER_ARG_DIR_UTILS = -v $(shell pwd)/../utils:/work/utils
DOCKER_ARG_DEV = --privileged -v /dev:/dev
DOCKER_QEMU = $(DOCKER_CMD_INTERACT) $(DOCKER_IMAGE)
DOCKER_TEST = $(DOCKER_CMD_INTERACT) $(DOCKER_ARG_DIR_UTILS) $(DOCKER_IMAGE)
DOCKER_TOOLS = $(DOCKER_CMD) $(DOCKER_IMAGE)
# Dockerize commands that require USB device passthrough only on Linux
@ -79,8 +80,9 @@ ifeq ($(UNAME_S),Linux)
DOCKER_CHAINBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_UTILS) $(DOCKER_IMAGE)
endif
EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
EXEC_MINIPUSH = ruby ../utils/minipush.rb
EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
EXEC_MINIPUSH = ruby ../utils/minipush.rb
EXEC_QEMU_MINIPUSH = ruby tests/qemu_minipush.rb
.PHONY: all $(KERNEL_ELF) $(KERNEL_BIN) doc qemu qemuasm chainboot clippy clean readelf objdump nm \
check
@ -99,7 +101,7 @@ doc:
@$(DOC_CMD) --document-private-items --open
ifeq ($(QEMU_MACHINE_TYPE),)
qemu:
qemu test:
$(call colorecho, "\n$(QEMU_MISSING_STRING)")
else
qemu: $(KERNEL_BIN)
@ -109,6 +111,12 @@ qemu: $(KERNEL_BIN)
qemuasm: $(KERNEL_BIN)
$(call colorecho, "\nLaunching QEMU with ASM output")
@$(DOCKER_QEMU) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) -kernel $(KERNEL_BIN) -d in_asm
test: $(KERNEL_BIN)
$(call colorecho, "\nTesting chainloading - $(BSP)")
@$(DOCKER_TEST) $(EXEC_QEMU_MINIPUSH) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) \
-kernel $(KERNEL_BIN) $(CHAINBOOT_DEMO_PAYLOAD)
endif
chainboot:

@ -153,7 +153,14 @@ diff -uNr 05_drivers_gpio_uart/Makefile 06_uart_chainloader/Makefile
endif
# Export for build.rs
@@ -74,13 +76,14 @@
@@ -68,19 +70,22 @@
DOCKER_ARG_DEV = --privileged -v /dev:/dev
DOCKER_QEMU = $(DOCKER_CMD_INTERACT) $(DOCKER_IMAGE)
+DOCKER_TEST = $(DOCKER_CMD_INTERACT) $(DOCKER_ARG_DIR_UTILS) $(DOCKER_IMAGE)
DOCKER_TOOLS = $(DOCKER_CMD) $(DOCKER_IMAGE)
# Dockerize commands that require USB device passthrough only on Linux
ifeq ($(UNAME_S),Linux)
DOCKER_CMD_DEV = $(DOCKER_CMD_INTERACT) $(DOCKER_ARG_DEV)
@ -161,9 +168,11 @@ diff -uNr 05_drivers_gpio_uart/Makefile 06_uart_chainloader/Makefile
+ DOCKER_CHAINBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_UTILS) $(DOCKER_IMAGE)
endif
EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
-EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
-EXEC_MINITERM = ruby ../utils/miniterm.rb
+EXEC_MINIPUSH = ruby ../utils/minipush.rb
+EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
+EXEC_MINIPUSH = ruby ../utils/minipush.rb
+EXEC_QEMU_MINIPUSH = ruby tests/qemu_minipush.rb
-.PHONY: all $(KERNEL_ELF) $(KERNEL_BIN) doc qemu miniterm clippy clean readelf objdump nm check
+.PHONY: all $(KERNEL_ELF) $(KERNEL_BIN) doc qemu qemuasm chainboot clippy clean readelf objdump nm \
@ -171,7 +180,14 @@ diff -uNr 05_drivers_gpio_uart/Makefile 06_uart_chainloader/Makefile
all: $(KERNEL_BIN)
@@ -102,10 +105,14 @@
@@ -96,16 +101,26 @@
@$(DOC_CMD) --document-private-items --open
ifeq ($(QEMU_MACHINE_TYPE),)
-qemu:
+qemu test:
$(call colorecho, "\n$(QEMU_MISSING_STRING)")
else
qemu: $(KERNEL_BIN)
$(call colorecho, "\nLaunching QEMU")
@$(DOCKER_QEMU) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) -kernel $(KERNEL_BIN)
@ -179,6 +195,12 @@ diff -uNr 05_drivers_gpio_uart/Makefile 06_uart_chainloader/Makefile
+qemuasm: $(KERNEL_BIN)
+ $(call colorecho, "\nLaunching QEMU with ASM output")
+ @$(DOCKER_QEMU) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) -kernel $(KERNEL_BIN) -d in_asm
+
+test: $(KERNEL_BIN)
+ $(call colorecho, "\nTesting chainloading - $(BSP)")
+ @$(DOCKER_TEST) $(EXEC_QEMU_MINIPUSH) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) \
+ -kernel $(KERNEL_BIN) $(CHAINBOOT_DEMO_PAYLOAD)
+
endif
-miniterm:
@ -470,6 +492,93 @@ diff -uNr 05_drivers_gpio_uart/src/main.rs 06_uart_chainloader/src/main.rs
+ kernel()
}
diff -uNr 05_drivers_gpio_uart/tests/qemu_minipush.rb 06_uart_chainloader/tests/qemu_minipush.rb
--- 05_drivers_gpio_uart/tests/qemu_minipush.rb
+++ 06_uart_chainloader/tests/qemu_minipush.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+# SPDX-License-Identifier: MIT OR Apache-2.0
+#
+# Copyright (c) 2020-2021 Andre Richter <andre.o.richter@gmail.com>
+
+require_relative '../../utils/minipush'
+require 'expect'
+require 'timeout'
+
+# Match for the last print that 'demo_payload_rpiX.img' produces.
+EXPECTED_PRINT = 'Echoing input now'
+
+# The main class
+class QEMUMiniPush < MiniPush
+ TIMEOUT_SECS = 3
+
+ # override
+ def initialize(qemu_cmd, binary_image_path)
+ super(nil, binary_image_path)
+
+ @qemu_cmd = qemu_cmd
+ end
+
+ private
+
+ def quit_qemu_graceful
+ Timeout.timeout(5) do
+ pid = @target_serial.pid
+ Process.kill('TERM', pid)
+ Process.wait(pid)
+ end
+ end
+
+ # override
+ def open_serial
+ @target_serial = IO.popen(@qemu_cmd, 'r+', err: '/dev/null')
+
+ # Ensure all output is immediately flushed to the device.
+ @target_serial.sync = true
+
+ puts "[#{@name_short}] ✅ Serial connected"
+ end
+
+ # override
+ def terminal
+ result = @target_serial.expect(EXPECTED_PRINT, TIMEOUT_SECS)
+ exit(1) if result.nil?
+
+ puts result
+
+ quit_qemu_graceful
+ end
+
+ public
+
+ # override
+ def connetion_reset; end
+
+ # override
+ def handle_reconnect(error)
+ handle_unexpected(error)
+ end
+end
+
+##--------------------------------------------------------------------------------------------------
+## Execution starts here
+##--------------------------------------------------------------------------------------------------
+puts
+puts 'QEMUMiniPush 1.0'.cyan
+puts
+
+# CTRL + C handler. Only here to suppress Ruby's default exception print.
+trap('INT') do
+ # The `ensure` block from `QEMUMiniPush::run` will run after exit, restoring console state.
+ exit
+end
+
+binary_image_path = ARGV.pop
+qemu_cmd = ARGV.join(' ')
+
+QEMUMiniPush.new(qemu_cmd, binary_image_path).run
diff -uNr 05_drivers_gpio_uart/update.sh 06_uart_chainloader/update.sh
--- 05_drivers_gpio_uart/update.sh
+++ 06_uart_chainloader/update.sh

@ -0,0 +1,82 @@
# frozen_string_literal: true
# SPDX-License-Identifier: MIT OR Apache-2.0
#
# Copyright (c) 2020-2021 Andre Richter <andre.o.richter@gmail.com>
require_relative '../../utils/minipush'
require 'expect'
require 'timeout'
# Match for the last print that 'demo_payload_rpiX.img' produces.
EXPECTED_PRINT = 'Echoing input now'
# The main class
class QEMUMiniPush < MiniPush
TIMEOUT_SECS = 3
# override
def initialize(qemu_cmd, binary_image_path)
super(nil, binary_image_path)
@qemu_cmd = qemu_cmd
end
private
def quit_qemu_graceful
Timeout.timeout(5) do
pid = @target_serial.pid
Process.kill('TERM', pid)
Process.wait(pid)
end
end
# override
def open_serial
@target_serial = IO.popen(@qemu_cmd, 'r+', err: '/dev/null')
# Ensure all output is immediately flushed to the device.
@target_serial.sync = true
puts "[#{@name_short}] ✅ Serial connected"
end
# override
def terminal
result = @target_serial.expect(EXPECTED_PRINT, TIMEOUT_SECS)
exit(1) if result.nil?
puts result
quit_qemu_graceful
end
public
# override
def connetion_reset; end
# override
def handle_reconnect(error)
handle_unexpected(error)
end
end
##--------------------------------------------------------------------------------------------------
## Execution starts here
##--------------------------------------------------------------------------------------------------
puts
puts 'QEMUMiniPush 1.0'.cyan
puts
# CTRL + C handler. Only here to suppress Ruby's default exception print.
trap('INT') do
# The `ensure` block from `QEMUMiniPush::run` will run after exit, restoring console state.
exit
end
binary_image_path = ARGV.pop
qemu_cmd = ARGV.join(' ')
QEMUMiniPush.new(qemu_cmd, binary_image_path).run

@ -78,9 +78,23 @@ diff -uNr 06_uart_chainloader/Makefile 07_timestamps/Makefile
endif
# Export for build.rs
@@ -82,8 +80,7 @@
EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
EXEC_MINIPUSH = ruby ../utils/minipush.rb
@@ -70,7 +68,6 @@
DOCKER_ARG_DEV = --privileged -v /dev:/dev
DOCKER_QEMU = $(DOCKER_CMD_INTERACT) $(DOCKER_IMAGE)
-DOCKER_TEST = $(DOCKER_CMD_INTERACT) $(DOCKER_ARG_DIR_UTILS) $(DOCKER_IMAGE)
DOCKER_TOOLS = $(DOCKER_CMD) $(DOCKER_IMAGE)
# Dockerize commands that require USB device passthrough only on Linux
@@ -80,12 +77,10 @@
DOCKER_CHAINBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_UTILS) $(DOCKER_IMAGE)
endif
-EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
-EXEC_MINIPUSH = ruby ../utils/minipush.rb
-EXEC_QEMU_MINIPUSH = ruby tests/qemu_minipush.rb
+EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE)
+EXEC_MINIPUSH = ruby ../utils/minipush.rb
-.PHONY: all $(KERNEL_ELF) $(KERNEL_BIN) doc qemu qemuasm chainboot clippy clean readelf objdump nm \
- check
@ -88,7 +102,14 @@ diff -uNr 06_uart_chainloader/Makefile 07_timestamps/Makefile
all: $(KERNEL_BIN)
@@ -105,14 +102,10 @@
@@ -101,26 +96,16 @@
@$(DOC_CMD) --document-private-items --open
ifeq ($(QEMU_MACHINE_TYPE),)
-qemu test:
+qemu:
$(call colorecho, "\n$(QEMU_MISSING_STRING)")
else
qemu: $(KERNEL_BIN)
$(call colorecho, "\nLaunching QEMU")
@$(DOCKER_QEMU) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) -kernel $(KERNEL_BIN)
@ -96,6 +117,12 @@ diff -uNr 06_uart_chainloader/Makefile 07_timestamps/Makefile
-qemuasm: $(KERNEL_BIN)
- $(call colorecho, "\nLaunching QEMU with ASM output")
- @$(DOCKER_QEMU) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) -kernel $(KERNEL_BIN) -d in_asm
-
-test: $(KERNEL_BIN)
- $(call colorecho, "\nTesting chainloading - $(BSP)")
- @$(DOCKER_TEST) $(EXEC_QEMU_MINIPUSH) $(EXEC_QEMU) $(QEMU_RELEASE_ARGS) \
- -kernel $(KERNEL_BIN) $(CHAINBOOT_DEMO_PAYLOAD)
-
endif
-chainboot:
@ -692,6 +719,93 @@ diff -uNr 06_uart_chainloader/src/time.rs 07_timestamps/src/time.rs
+ }
+}
diff -uNr 06_uart_chainloader/tests/qemu_minipush.rb 07_timestamps/tests/qemu_minipush.rb
--- 06_uart_chainloader/tests/qemu_minipush.rb
+++ 07_timestamps/tests/qemu_minipush.rb
@@ -1,82 +0,0 @@
-# frozen_string_literal: true
-
-# SPDX-License-Identifier: MIT OR Apache-2.0
-#
-# Copyright (c) 2020-2021 Andre Richter <andre.o.richter@gmail.com>
-
-require_relative '../../utils/minipush'
-require 'expect'
-require 'timeout'
-
-# Match for the last print that 'demo_payload_rpiX.img' produces.
-EXPECTED_PRINT = 'Echoing input now'
-
-# The main class
-class QEMUMiniPush < MiniPush
- TIMEOUT_SECS = 3
-
- # override
- def initialize(qemu_cmd, binary_image_path)
- super(nil, binary_image_path)
-
- @qemu_cmd = qemu_cmd
- end
-
- private
-
- def quit_qemu_graceful
- Timeout.timeout(5) do
- pid = @target_serial.pid
- Process.kill('TERM', pid)
- Process.wait(pid)
- end
- end
-
- # override
- def open_serial
- @target_serial = IO.popen(@qemu_cmd, 'r+', err: '/dev/null')
-
- # Ensure all output is immediately flushed to the device.
- @target_serial.sync = true
-
- puts "[#{@name_short}] ✅ Serial connected"
- end
-
- # override
- def terminal
- result = @target_serial.expect(EXPECTED_PRINT, TIMEOUT_SECS)
- exit(1) if result.nil?
-
- puts result
-
- quit_qemu_graceful
- end
-
- public
-
- # override
- def connetion_reset; end
-
- # override
- def handle_reconnect(error)
- handle_unexpected(error)
- end
-end
-
-##--------------------------------------------------------------------------------------------------
-## Execution starts here
-##--------------------------------------------------------------------------------------------------
-puts
-puts 'QEMUMiniPush 1.0'.cyan
-puts
-
-# CTRL + C handler. Only here to suppress Ruby's default exception print.
-trap('INT') do
- # The `ensure` block from `QEMUMiniPush::run` will run after exit, restoring console state.
- exit
-end
-
-binary_image_path = ARGV.pop
-qemu_cmd = ARGV.join(' ')
-
-QEMUMiniPush.new(qemu_cmd, binary_image_path).run
diff -uNr 06_uart_chainloader/update.sh 07_timestamps/update.sh
--- 06_uart_chainloader/update.sh
+++ 07_timestamps/update.sh

@ -1,3 +1,3 @@
#!/usr/bin/env bash
complete -W "clean clippy copyright diff fmt fmt_check make make_xtra misspell ready_for_publish ready_for_publish_no_rust rubocop test_integration test_unit update" devtool
complete -W "clean clippy copyright diff fmt fmt_check make make_xtra misspell ready_for_publish ready_for_publish_no_rust rubocop test_integration test_unit test_xtra update" devtool

@ -52,7 +52,7 @@ class TutorialCrate
end
def test_unit
return unless testable?
return unless kernel_tests?
puts "Unit Tests #{@folder}".light_blue
@ -60,7 +60,7 @@ class TutorialCrate
end
def test_integration
return unless testable?
return unless kernel_tests?
puts "Integration Tests #{@folder}".light_blue
@ -74,8 +74,8 @@ class TutorialCrate
private
def testable?
Dir.exist?("#{@folder}/tests")
def kernel_tests?
File.exist?("#{@folder}/tests/runner.rb")
end
end
@ -147,6 +147,13 @@ class DevTool
system('cd X1_JTAG_boot && bash update.sh')
end
def test_xtra
return if @user_has_supplied_crates
puts 'Test Xtra stuff'.light_blue
exit(1) unless system('cd *_uart_chainloader && make test')
end
def test_unit
@crates.each(&:test_unit)
end
@ -166,8 +173,6 @@ class DevTool
def rubocop
puts 'Rubocop'.light_blue
system('which bundle')
system('bundle --version')
exit(1) unless system('bundle exec rubocop')
end

@ -80,7 +80,7 @@ class MiniPush < MiniTerm
end
# override
def handle_reconnect
def handle_reconnect(_error)
connetion_reset
puts
@ -100,8 +100,8 @@ class MiniPush < MiniTerm
send_size
send_binary
terminal
rescue ConnectionError, EOFError, Errno::EIO, ProtocolError, Timeout::Error
handle_reconnect
rescue ConnectionError, EOFError, Errno::EIO, ProtocolError, Timeout::Error => e
handle_reconnect(e)
retry
rescue StandardError => e
handle_unexpected(e)
@ -112,14 +112,19 @@ class MiniPush < MiniTerm
end
end
puts
puts 'Minipush 1.0'.cyan
puts
##--------------------------------------------------------------------------------------------------
## Execution starts here
##--------------------------------------------------------------------------------------------------
if __FILE__ == $PROGRAM_NAME
puts
puts 'Minipush 1.0'.cyan
puts
# CTRL + C handler. Only here to suppress Ruby's default exception print.
trap('INT') do
# The `ensure` block from `MiniPush::run` will run after exit, restoring console state.
exit
end
# CTRL + C handler. Only here to suppress Ruby's default exception print.
trap('INT') do
# The `ensure` block from `MiniPush::run` will run after exit, restoring console state.
exit
MiniPush.new(ARGV[0], ARGV[1]).run
end
MiniPush.new(ARGV[0], ARGV[1]).run

@ -94,7 +94,7 @@ class MiniTerm
end
# When the serial lost power or was removed during R/W operation.
def handle_reconnect
def handle_reconnect(_error)
connetion_reset
puts
@ -113,8 +113,8 @@ class MiniTerm
def run
open_serial
terminal
rescue ConnectionError, EOFError, Errno::EIO
handle_reconnect
rescue ConnectionError, EOFError, Errno::EIO => e
handle_reconnect(e)
retry
rescue StandardError => e
handle_unexpected(e)
@ -125,6 +125,9 @@ class MiniTerm
end
end
##--------------------------------------------------------------------------------------------------
## Execution starts here
##--------------------------------------------------------------------------------------------------
if __FILE__ == $PROGRAM_NAME
puts
puts 'Miniterm 1.0'.cyan

Loading…
Cancel
Save