Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
14e2c1c
commit baa7cbd
Showing
19 changed files
with
1,092 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: CI | ||
|
||
on: [push] | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: install software | ||
run: | | ||
sudo apt-get -qq install llvm | ||
ls -lt /usr/bin/llvm-objcopy* | ||
wget --quiet --output-document=- https://github.com/github/hub/releases/download/v2.12.3/hub-linux-amd64-2.12.3.tgz | tar zx | ||
mv hub-linux-* hub | ||
./hub/bin/hub --version | ||
ZIG=$(wget --quiet --output-document=- https://ziglang.org/download/index.json | jq --raw-output '.master."x86_64-linux".tarball') | ||
wget --quiet --output-document=- $ZIG | tar Jx | ||
mv zig-linux-x86_64-* zig | ||
echo zig version $(./zig/zig version) | ||
- name: build | ||
run: | | ||
REPO=$(basename $GITHUB_REPOSITORY) | ||
./zig/zig build -Darmv6 | ||
cp -a $REPO-armv6.img boot/ | ||
./zig/zig build -Darmv7 | ||
cp -a $REPO-armv7.img boot/ | ||
- name: release draft | ||
env: | ||
GITHUB_USER: $GITHUB_ACTOR | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
run: | | ||
REPO=$(basename $GITHUB_REPOSITORY) | ||
RELEASE_TAG=$(grep '^const release_tag =' src/main.zig | sed 's/";//' | sed 's/^.*"//') | ||
RELEASE_ASSET=$REPO-$RELEASE_TAG.zip | ||
pushd boot | ||
echo $RELEASE_TAG > RELEASE.md | ||
echo >> RELEASE.md | ||
cat ../release-message.md >> RELEASE.md | ||
zip -r $RELEASE_ASSET . | ||
../hub/bin/hub release create --draft --prerelease --file RELEASE.md --attach $RELEASE_ASSET $RELEASE_TAG | ||
popd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.bin | ||
*.dat | ||
*.elf | ||
*.img | ||
*.zip | ||
zig-cache/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
zig logo is displayed | ||
|
||
Successfully tested on rpi3b, rpi3b+ | ||
|
||
Not yet working on armv6 raspberry pi models |
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# https://www.raspberrypi.org/documentation/configuration/config-txt/ | ||
|
||
disable_commandline_tags=1 | ||
kernel_old=1 | ||
dtparam=audio=on | ||
disable_splash=1 | ||
boot_delay=0 | ||
cec_osd_name=Zig! | ||
|
||
[rpi0] | ||
kernel=zig-bare-metal-raspberry-pi-armv6.img | ||
[rpi1] | ||
kernel=zig-bare-metal-raspberry-pi-armv6.img | ||
[rpi2] | ||
kernel=zig-bare-metal-raspberry-pi-armv7.img | ||
[rpi3] | ||
kernel=zig-bare-metal-raspberry-pi-armv7.img | ||
[rpi4] | ||
kernel=zig-bare-metal-raspberry-pi-armv7.img |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
const std = @import("std"); | ||
const Builder = std.build.Builder; | ||
const builtin = @import("builtin"); | ||
|
||
pub fn build(b: *Builder) void { | ||
const mode = b.standardReleaseOptions(); | ||
const want_armv6 = b.option(bool, "armv6", "Build armv6 instead of armv7 (armv7 is default)") orelse false; | ||
const want_armv7 = b.option(bool, "armv7", "Build armv7 instead of armv6 (armv7 is default)") orelse false; | ||
|
||
const exec_name = "zig-bare-metal-raspberry-pi"; | ||
const exe = b.addExecutable(exec_name, "src/main.zig"); | ||
exe.setOutputDir("zig-cache"); | ||
exe.setBuildMode(mode); | ||
|
||
var arch: builtin.Arch = undefined; | ||
var subarch: u32 = undefined; | ||
var kernel_name: []const u8 = undefined; | ||
if (want_armv6) { | ||
arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v6 }; | ||
subarch = 6; | ||
kernel_name = exec_name ++ "-armv6.img"; | ||
} else { | ||
arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v7 }; | ||
subarch = 7; | ||
kernel_name = exec_name ++ "-armv7.img"; | ||
} | ||
const os = builtin.Os.freestanding; | ||
const environ = builtin.Abi.eabihf; | ||
exe.setTarget(arch, builtin.Os.freestanding, environ); | ||
exe.addBuildOption(u32, "subarch", subarch); | ||
|
||
const linker_script = "src/linker.ld"; | ||
exe.setLinkerScriptPath(linker_script); | ||
|
||
const run_objcopy = b.addSystemCommand([_][]const u8{ | ||
"llvm-objcopy-6.0", exe.getOutputPath(), | ||
"-O", "binary", | ||
kernel_name, | ||
}); | ||
run_objcopy.step.dependOn(&exe.step); | ||
|
||
b.default_step.dependOn(&run_objcopy.step); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Requires: | ||
* a raspberry pi model 3b or 3b+ with a power supply | ||
* a computer that can write an sd card | ||
* an sd card that you can erase - its contents will be destroyed | ||
* an hdmi tv and an hdmi cable | ||
|
||
# Steps: | ||
* with the computer | ||
* format the sd card as FAT32 | ||
* this destroys the current contents of the sd card | ||
* download the zip file | ||
* unzip it to the sd card | ||
* insert the sd card into the pi | ||
* connect the pi to the tv using the hdmi cable | ||
* turn on the tv | ||
* apply power to the pi | ||
* you should see the zig logo displayed along a changing banner of colored lines |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
pub const PERIPHERAL_BASE = if (build_options.subarch >= 7) 0x3F000000 else 0x20000000; | ||
|
||
var already_panicking: bool = false; | ||
pub fn panicf(comptime fmt: []const u8, args: ...) noreturn { | ||
@setCold(true); | ||
if (already_panicking) { | ||
hang("\npanicked during kernel panic"); | ||
} | ||
already_panicking = true; | ||
|
||
serial.log("panic: " ++ fmt, args); | ||
hang("panic completed"); | ||
} | ||
|
||
pub fn io(offset: u32) *volatile u32 { | ||
return @intToPtr(*volatile u32, PERIPHERAL_BASE + offset); | ||
} | ||
|
||
pub fn ioStruct(comptime StructType: type, offset: u32) *volatile StructType { | ||
return @intToPtr(*volatile StructType, PERIPHERAL_BASE + offset); | ||
} | ||
|
||
// Loop count times in a way that the compiler won't optimize away. | ||
pub fn delay(count: usize) void { | ||
var i: usize = 0; | ||
while (i < count) : (i += 1) { | ||
asm volatile("mov r0, r0"); | ||
} | ||
} | ||
|
||
pub fn hang(comptime format: []const u8, args: ...) noreturn { | ||
serial.log(format, args); | ||
while (true) { | ||
if (build_options.subarch >= 7) { | ||
v7.wfe(); | ||
} | ||
} | ||
} | ||
|
||
pub const v7 = struct { | ||
pub inline fn mpidr() u32 { | ||
var word = asm("mrc p15, 0, %[word], c0, c0, 5" | ||
: [word] "=r" (-> usize)); | ||
return word; | ||
} | ||
|
||
pub inline fn wfe() void { | ||
asm volatile("wfe"); | ||
} | ||
}; | ||
|
||
pub fn sp() u32 { | ||
var word = asm("mov %[word], sp" | ||
: [word] "=r" (-> usize)); | ||
return word; | ||
} | ||
|
||
pub fn cpsr() u32 { | ||
var word = asm("mrs %[word], cpsr" | ||
: [word] "=r" (-> usize)); | ||
return word; | ||
} | ||
|
||
pub fn spsr() u32 { | ||
var word = asm("mrs %[word], spsr" | ||
: [word] "=r" (-> usize)); | ||
return word; | ||
} | ||
|
||
pub fn sctlr() u32 { | ||
var word = asm("mrc p15, 0, %[word], c1, c0, 0" | ||
: [word] "=r" (-> usize)); | ||
return word; | ||
} | ||
|
||
pub fn scr() u32 { | ||
var word = asm("mrc p15, 0, %[word], c1, c1, 0" | ||
: [word] "=r" (-> usize)); | ||
return word; | ||
} | ||
|
||
pub fn dsbSt() void { | ||
if (build_options.subarch >= 7) { | ||
asm volatile("dsb st"); | ||
} else { | ||
asm volatile("mcr p15, 0, r0, c7, c10, 4" | ||
: | ||
: | ||
: "r0"); | ||
} | ||
} | ||
|
||
pub fn setVectorBaseAddressRegister(address: u32) void { | ||
asm volatile("mcr p15, #0, %[address], cr12, cr0, 0" | ||
: | ||
: [address] "{r0}" (address) | ||
); | ||
} | ||
|
||
// The linker will make the address of these global variables equal | ||
// to the value we are interested in. The memory at the address | ||
// could alias any uninitialized global variable in the kernel. | ||
extern var __bss_start: u8; | ||
extern var __bss_end: u8; | ||
extern var __end_init: u8; | ||
|
||
pub fn setBssToZero() void { | ||
@memset((*volatile [1]u8)(&__bss_start), 0, @ptrToInt(&__bss_end) - @ptrToInt(&__bss_start)); | ||
} | ||
|
||
const build_options = @import("build_options"); | ||
const serial = @import("serial.zig"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
pub fn setAlt5(pin_number: u32) void { | ||
setPinPull(pin_number, Pull.None); | ||
setPinFunction(pin_number, GPIO_FUNCTION_ALT5); | ||
} | ||
|
||
pub fn initOutputPinWithPullNone(pin_number: u32) void { | ||
setPinPull(pin_number, Pull.None); | ||
setPinFunction(pin_number, GPIO_FUNCTION_OUT); | ||
} | ||
|
||
pub fn setPinOutputBool(pin_number: u32, onOrOff: bool) void { | ||
if (onOrOff) { | ||
pins_set.write(pin_number, 1); | ||
} else { | ||
pins_clear.write(pin_number, 1); | ||
} | ||
} | ||
|
||
fn setPinPull(pin_number: u32, pull: Pull) void { | ||
GPPUD.* = @enumToInt(pull); | ||
arm.delay(150); | ||
pins_pull.write(pin_number, 1); | ||
arm.delay(150); | ||
GPPUD.* = @enumToInt(Pull.None); | ||
pins_pull.write(pin_number, 0); | ||
} | ||
|
||
fn setPinFunction(pin_number: u32, function: u32) void { | ||
pins_function.write(pin_number, function); | ||
} | ||
|
||
pub fn ioArrayOf(base: u32, field_size: u32, length: u32) type { | ||
var IoArray = struct { | ||
const Self = @This(); | ||
|
||
fn write(self: Self, index: u32, value: u32) void { | ||
const field_mask = u32(1) << @intCast(u5, field_size - 1); | ||
rangeCheck(index, length - 1); | ||
rangeCheck(value, field_mask); | ||
const fields_per_word = 32 / field_size; | ||
const register = @intToPtr(*volatile u32, base + (index / fields_per_word) * 4); | ||
const shift = @intCast(u5, (index % fields_per_word) * field_size); | ||
var word = register.*; | ||
word &= ~(field_mask << shift); | ||
word |= value << shift; | ||
register.* = word; | ||
} | ||
}; | ||
return IoArray; | ||
} | ||
|
||
fn rangeCheck(x: u32, max: u32) void { | ||
if (x > max) { | ||
panicf("{} exceeds max {}", x, max); | ||
} | ||
} | ||
|
||
const pins_set: ioArrayOf(GPSET0, 1, GPIO_MAX_PIN) = undefined; | ||
const pins_clear: ioArrayOf(GPCLR0, 1, GPIO_MAX_PIN) = undefined; | ||
const pins_pull: ioArrayOf(GPPUDCLK0, 1, GPIO_MAX_PIN) = undefined; | ||
const pins_function: ioArrayOf(GPFSEL0, 3, GPIO_MAX_PIN) = undefined; | ||
|
||
const GPIO_MAX_PIN = 53; | ||
|
||
const GPFSEL0 = PERIPHERAL_BASE + 0x200000; | ||
const GPSET0 = PERIPHERAL_BASE + 0x20001C; | ||
const GPCLR0 = PERIPHERAL_BASE + 0x200028; | ||
const GPPUD = arm.io(0x200094); | ||
const GPPUDCLK0 = PERIPHERAL_BASE + 0x200098; | ||
|
||
const Pull = enum { | ||
None, | ||
Down, | ||
Up, | ||
}; | ||
|
||
const GPIO_FUNCTION_FIELD_SIZE: u32 = 3; | ||
const GPIO_FUNCTION_OUT: u32 = 1; | ||
const GPIO_FUNCTION_ALT5: u32 = 2; | ||
|
||
const arm = @import("arm_assembly_code.zig"); | ||
const panicf = arm.panicf; | ||
const PERIPHERAL_BASE = arm.PERIPHERAL_BASE; |
Oops, something went wrong.