Cross compile the elna frontend
This commit is contained in:
88
Rakefile
88
Rakefile
@ -9,7 +9,6 @@ require 'uri'
|
||||
require 'net/http'
|
||||
require 'open3'
|
||||
require 'etc'
|
||||
require 'fileutils'
|
||||
require 'pathname'
|
||||
require 'rake/clean'
|
||||
|
||||
@ -57,10 +56,12 @@ class BuildTarget
|
||||
.split(' ').last.strip
|
||||
end
|
||||
|
||||
def configuration
|
||||
def configuration(prefix)
|
||||
case @architecture
|
||||
when :rv32
|
||||
['--with-arch=rv32imafdc', '--with-abi=ilp32d', '--with-tune=rocket', '--with-isa-spec=20191213']
|
||||
['arch=rv32imafdc', 'abi=ilp32d', 'tune=rocket', 'isa-spec=20191213'].map do |option|
|
||||
"-#{prefix}#{option}"
|
||||
end
|
||||
else
|
||||
[]
|
||||
end
|
||||
@ -109,9 +110,9 @@ end
|
||||
|
||||
def configure_make_install(source_directory, configure_options, env, cwd)
|
||||
configure = source_directory.relative_path_from(cwd) + 'configure'
|
||||
system env, configure.to_path, *configure_options, chdir: cwd.to_path, exception: true
|
||||
system 'make', '-j', Etc.nprocessors.to_s, chdir: cwd.to_path, exception: true
|
||||
system env, 'make', 'install', chdir: cwd.to_path, exception: true
|
||||
sh env, configure.to_path, *configure_options, chdir: cwd.to_path
|
||||
sh 'make', '-j', Etc.nprocessors.to_s, chdir: cwd.to_path
|
||||
sh env, 'make', 'install', chdir: cwd.to_path
|
||||
end
|
||||
|
||||
directory(TMP + 'tools')
|
||||
@ -168,8 +169,8 @@ namespace :cross do
|
||||
options.rootfs.mkpath
|
||||
options.sysroot.mkpath
|
||||
|
||||
system 'contrib/download_prerequisites', chdir: source_directory.to_path, exception: true
|
||||
configure_options = options.configuration + [
|
||||
sh 'contrib/download_prerequisites', chdir: source_directory.to_path
|
||||
configure_options = options.configuration('-with-') + [
|
||||
"--prefix=#{options.rootfs.realpath}",
|
||||
"--with-sysroot=#{options.sysroot.realpath}",
|
||||
'--enable-languages=c,c++',
|
||||
@ -211,7 +212,7 @@ namespace :cross do
|
||||
include_directory = TMP + 'tools/include'
|
||||
|
||||
include_directory.mkpath
|
||||
FileUtils.cp (source_directory + 'elf/elf.h'), (include_directory + 'elf.h')
|
||||
cp (source_directory + 'elf/elf.h'), (include_directory + 'elf.h')
|
||||
end
|
||||
|
||||
desc 'Build linux kernel'
|
||||
@ -226,14 +227,14 @@ namespace :cross do
|
||||
'PATH' => "#{options.rootfs.realpath + 'bin'}:#{ENV['PATH']}",
|
||||
'HOSTCFLAGS' => "-D_UUID_T -D__GETHOSTUUID_H -I#{TMP + 'tools/include'}"
|
||||
}
|
||||
system env, 'make', 'rv32_defconfig', chdir: cwd.to_path, exception: true
|
||||
system env, 'make', '-j', Etc.nprocessors.to_s, chdir: cwd.to_path, exception: true
|
||||
system env, 'make', 'headers', chdir: cwd.to_path, exception: true
|
||||
sh env, 'make', 'rv32_defconfig', chdir: cwd.to_path
|
||||
sh env, 'make', '-j', Etc.nprocessors.to_s, chdir: cwd.to_path
|
||||
sh env, 'make', 'headers', chdir: cwd.to_path
|
||||
|
||||
user_directory = options.sysroot + 'usr'
|
||||
|
||||
user_directory.mkpath
|
||||
FileUtils.cp_r (cwd + 'usr/include'), (user_directory + 'include')
|
||||
cp_r (cwd + 'usr/include'), (user_directory + 'include')
|
||||
end
|
||||
|
||||
desc 'Build glibc'
|
||||
@ -275,13 +276,14 @@ namespace :cross do
|
||||
source_directory = TMP + "tools/gcc-#{GCC_VERSION}"
|
||||
cwd = TMP + 'tools/build-gcc'
|
||||
|
||||
FileUtils.rm_rf cwd
|
||||
rm_rf cwd
|
||||
cwd.mkpath
|
||||
cp_r '../elna', source_directory + 'gcc'
|
||||
|
||||
configure_options = options.configuration + [
|
||||
configure_options = options.configuration('-with-') + [
|
||||
"--prefix=#{options.rootfs.realpath}",
|
||||
"--with-sysroot=#{options.sysroot.realpath}",
|
||||
'--enable-languages=c,c++,lto',
|
||||
'--enable-languages=c,c++,lto,elna',
|
||||
'--enable-lto',
|
||||
'--enable-shared',
|
||||
'--disable-bootstrap',
|
||||
@ -308,7 +310,7 @@ end
|
||||
|
||||
task cross: TMP + 'tools'
|
||||
task :cross, :target do |t, args|
|
||||
args.with_defaults(target: 'riscv32-unknown-linux-gnu')
|
||||
args.with_defaults target: 'riscv32'
|
||||
|
||||
Rake::Task['cross:binutils'].invoke args[:target]
|
||||
Rake::Task['cross:gcc1'].invoke args[:target]
|
||||
@ -318,27 +320,55 @@ task :cross, :target do |t, args|
|
||||
Rake::Task['cross:gcc2'].invoke args[:target]
|
||||
end
|
||||
|
||||
FLAGS = ['-O2', '-g3', '-Wall', '-march=rv32imzicsr', '-mabi=ilp32', '-fno-stack-protector', '-ffreestanding', '-nostdlib', '-static']
|
||||
|
||||
CLEAN.include 'kernel.elf', 'build/riscv32'
|
||||
def relative_from_tmp(path)
|
||||
Pathname.new(path).relative_path_from(TMP).each_filename
|
||||
end
|
||||
|
||||
CLEAN.include(TMP + 'riscv32')
|
||||
directory(TMP + 'riscv32')
|
||||
|
||||
rule(/^#{TMP}\/[[:alnum:]]+\/[[:alnum:]]+\.o$/ => ->(match) {
|
||||
[Pathname.new(match).basename.sub_ext('.s'), TMP + 'riscv32']
|
||||
}) do |t|
|
||||
ENV['CC'] = 'build/rootfs/bin/riscv32-unknown-linux-gnu-gcc'
|
||||
rule '.s.o' => ->(match) {
|
||||
architecture, *path_components = relative_from_tmp(match).to_a
|
||||
path_components[-1] = path_components.last.ext('')
|
||||
|
||||
system ENV['CC'], *FLAGS, '-c', '-o', t.name, *t.prerequisites.select { |prerequisite| prerequisite.end_with? '.s' }
|
||||
[File.join(path_components), TMP + architecture]
|
||||
} do |t|
|
||||
options = BuildTarget.new relative_from_tmp(t.name).first
|
||||
compiler = options.rootfs + "bin/#{options.target}-gcc"
|
||||
flags = ['-ffreestanding'] + options.configuration('m')
|
||||
sources = t.prerequisites.select { |prerequisite| File.extname(prerequisite) == '.s' }
|
||||
|
||||
system compiler.to_s, *flags, '-c', '-o', t.name, *sources, exception: true
|
||||
end
|
||||
|
||||
file 'kernel.elf' => FileList['*.s'].map { |source| (TMP + 'riscv32' + source).sub_ext('.o') } do |t|
|
||||
ENV['CC'] = 'build/rootfs/bin/riscv32-unknown-linux-gnu-gcc'
|
||||
rule '.elna.o' => ->(match) {
|
||||
architecture, *path_components = relative_from_tmp(match).to_a
|
||||
path_components[-1] = path_components.last.ext('')
|
||||
|
||||
system ENV['CC'], *FLAGS, '-T', 'kernel.ld', '-Wl,-Map=kernel.map', '-o', 'kernel.elf', *t.prerequisites
|
||||
[File.join(path_components), TMP + architecture]
|
||||
} do |t|
|
||||
options = BuildTarget.new relative_from_tmp(t.name).first
|
||||
compiler = options.rootfs + "bin/#{options.target}-gcc"
|
||||
flags = ['-O2', '-g3', '-fno-stack-protector'] + options.configuration('m')
|
||||
sources = t.prerequisites.select { |prerequisite| File.extname(prerequisite) == '.elna' }
|
||||
|
||||
system compiler.to_s, *flags, '-c', '-o', t.name, *sources, exception: true
|
||||
end
|
||||
|
||||
task default: 'kernel.elf'
|
||||
rule 'kernel.elf' => ->(match) {
|
||||
architecture_tmp = TMP + relative_from_tmp(match).first
|
||||
|
||||
FileList['*.s', '*.elna'].map { |source| (architecture_tmp + source).to_path + '.o' } << 'kernel.ld'
|
||||
} do |t|
|
||||
options = BuildTarget.new relative_from_tmp(t.name).first
|
||||
compiler = options.rootfs + "bin/#{options.target}-gcc"
|
||||
flags = options.configuration('m')
|
||||
objects, linker_script = t.prerequisites.partition { |prerequisite| File.extname(prerequisite) == '.o' }
|
||||
|
||||
system compiler.to_s, '-nostdlib', '-T', *linker_script, '-o', t.name, *objects, exception: true
|
||||
end
|
||||
|
||||
task default: 'build/riscv32/kernel.elf'
|
||||
task :default do |t|
|
||||
QEMU = 'qemu-system-riscv32'
|
||||
|
||||
|
4
kernel.s
4
kernel.s
@ -140,13 +140,13 @@ handle_trap:
|
||||
csrr a0, scause
|
||||
call write_i
|
||||
|
||||
li a0, ','
|
||||
call separator
|
||||
call write_c
|
||||
|
||||
csrr a0, stval
|
||||
call write_i
|
||||
|
||||
li a0, ','
|
||||
call separator
|
||||
call write_c
|
||||
|
||||
csrr a0, sepc
|
||||
|
7
source.elna
Normal file
7
source.elna
Normal file
@ -0,0 +1,7 @@
|
||||
module;
|
||||
|
||||
proc separator*() -> Char;
|
||||
return ','
|
||||
end;
|
||||
|
||||
end.
|
Reference in New Issue
Block a user