183 lines
3.3 KiB
Go
183 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"debug/elf"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"text/template"
|
|
)
|
|
|
|
const kernconfTmpl = `
|
|
#include "u.h"
|
|
#include "../port/lib.h"
|
|
#include "mem.h"
|
|
#include "dat.h"
|
|
#include "fns.h"
|
|
#include "../port/error.h"
|
|
#include "io.h"
|
|
|
|
void
|
|
rdb(void)
|
|
{
|
|
splhi();
|
|
iprint("rdb...not installed\n");
|
|
for(;;);
|
|
}
|
|
|
|
{{ range .Rootcodes }}
|
|
{{ . }}
|
|
{{ end }}
|
|
|
|
{{ range .Config.Dev }}extern Dev {{ . }}devtab;
|
|
{{ end }}
|
|
Dev *devtab[] = {
|
|
{{ range .Config.Dev }}
|
|
&{{ . }}devtab,
|
|
{{ end }}
|
|
nil,
|
|
};
|
|
|
|
{{ range .Config.Link }}extern void {{ . }}link(void);
|
|
{{ end }}
|
|
void
|
|
links(void)
|
|
{
|
|
{{ range .Rootnames }}addbootfile("{{ . }}", ramfs_{{ . }}_code, ramfs_{{ . }}_len);
|
|
{{ end }}
|
|
{{ range .Config.Link }}{{ . }}link();
|
|
{{ end }}
|
|
}
|
|
|
|
#include "../ip/ip.h"
|
|
{{ range .Config.Ip }}extern void {{ . }}init(Fs*);
|
|
{{ end }}
|
|
void (*ipprotoinit[])(Fs*) = {
|
|
{{ range .Config.Ip }} {{ . }}init,
|
|
{{ end }}
|
|
nil,
|
|
};
|
|
|
|
#include "../port/sd.h"
|
|
{{ range .Config.Sd }}extern SDifc {{ . }}ifc;
|
|
{{ end }}
|
|
SDifc* sdifc[] = {
|
|
{{ range .Config.Sd }} &{{ . }}ifc,
|
|
{{ end }}
|
|
nil,
|
|
};
|
|
|
|
{{ range .Config.Uart }}extern PhysUart {{ . }}physuart;
|
|
{{ end }}
|
|
PhysUart* physuart[] = {
|
|
{{ range .Config.Uart }} &{{ . }}physuart,
|
|
{{ end }}
|
|
nil,
|
|
};
|
|
|
|
#define Image IMAGE
|
|
#include <draw.h>
|
|
#include <memdraw.h>
|
|
#include <cursor.h>
|
|
#include "screen.h"
|
|
{{ range .Config.VGA }}extern VGAdev {{ . }}dev;
|
|
{{ end }}
|
|
VGAdev* vgadev[] = {
|
|
{{ range .Config.VGA }} &{{ . }}dev,
|
|
{{ end }}
|
|
nil,
|
|
};
|
|
|
|
{{ range .Config.VGA }}extern VGAcur {{ . }}cur;
|
|
{{ end }}
|
|
VGAcur* vgacur[] = {
|
|
{{ range .Config.VGA }} &{{ . }}cur,
|
|
{{ end }}
|
|
nil,
|
|
};
|
|
|
|
{{ range .Config.Code }}{{ . }}
|
|
{{ end }}
|
|
|
|
char* conffile = "{{ .Path }}";
|
|
|
|
`
|
|
|
|
// These are the two big code generation functions.
|
|
|
|
// data2c takes the file at path and creates a C byte array containing it.
|
|
func data2c(name string, path string) string {
|
|
var out []byte
|
|
var in []byte
|
|
|
|
if elf, err := elf.Open(path); err == nil {
|
|
elf.Close()
|
|
cwd, err := os.Getwd()
|
|
tmpf, err := ioutil.TempFile(cwd, name)
|
|
failOn(err)
|
|
|
|
run(nil, *shellhack, exec.Command(tools["strip"], "-o", tmpf.Name(), path))
|
|
|
|
in, err = ioutil.ReadAll(tmpf)
|
|
failOn(err)
|
|
|
|
tmpf.Close()
|
|
os.Remove(tmpf.Name())
|
|
} else {
|
|
var file *os.File
|
|
var err error
|
|
|
|
file, err = os.Open(path)
|
|
failOn(err)
|
|
|
|
in, err = ioutil.ReadAll(file)
|
|
failOn(err)
|
|
|
|
file.Close()
|
|
}
|
|
|
|
total := len(in)
|
|
|
|
out = []byte(fmt.Sprintf("static unsigned char ramfs_%s_code[] = {\n", name))
|
|
for len(in) > 0 {
|
|
for j := 0; j < 16 && len(in) > 0; j++ {
|
|
out = append(out, []byte(fmt.Sprintf("0x%02x, ", in[0]))...)
|
|
in = in[1:]
|
|
}
|
|
out = append(out, '\n')
|
|
}
|
|
|
|
out = append(out, []byte(fmt.Sprintf("0,\n};\nint ramfs_%s_len = %v;\n", name, total))...)
|
|
|
|
return string(out)
|
|
}
|
|
|
|
// confcode creates a kernel configuration header.
|
|
func confcode(path string, kern *kernel) []byte {
|
|
var rootcodes []string
|
|
var rootnames []string
|
|
for name, path := range kern.Ramfiles {
|
|
code := data2c(name, fromRoot(path))
|
|
rootcodes = append(rootcodes, code)
|
|
rootnames = append(rootnames, name)
|
|
}
|
|
|
|
vars := struct {
|
|
Path string
|
|
Config kernconfig
|
|
Rootnames []string
|
|
Rootcodes []string
|
|
}{
|
|
path,
|
|
kern.Config,
|
|
rootnames,
|
|
rootcodes,
|
|
}
|
|
tmpl := template.Must(template.New("kernconf").Parse(kernconfTmpl))
|
|
codebuf := &bytes.Buffer{}
|
|
failOn(tmpl.Execute(codebuf, vars))
|
|
return codebuf.Bytes()
|
|
}
|