Browse Source

build.go: json based kernel configuration
- $CONF files are not used anymore
- build.go generates $CONF.c
- $CONF.root.c is gone, ramfs is in the new $CONF.c
- ../mk/parse still used to generate systab.c and errstr.h

Change-Id: I309cec6cddb090bb106c9f8cffc3454842942736

Aki Nyrhinen 4 years ago
parent
commit
e18c78e434
4 changed files with 326 additions and 54 deletions
  1. 5 5
      sys/src/9/k10/core.json
  2. 73 44
      sys/src/9/k10/k8cpu.json
  3. 9 0
      sys/src/all.json
  4. 239 5
      util/build.go

+ 5 - 5
sys/src/9/k10/core.json

@@ -12,6 +12,10 @@
 		"-fvar-tracking",
 		"-fvar-tracking-assignments",
 		"-Wall",
+		"-W",
+		"-Wno-sign-compare",
+		"-Wno-missing-field-initializers",
+		"-Wno-unused-parameter",
 		"-Wno-missing-braces",
 		"-Wno-parentheses",
 		"-Wno-unknown-pragmas",
@@ -38,12 +42,8 @@
 		"${TOOLPREFIX}objdump -S 9$CONF \u003e 9$CONF.asm"
 	],
 	"Pre": [
-		"awk -v objtype=amd64 -f ../mk/parse -- -mkdevc $CONF \u003e $CONF.c",
-		"awk -f ../mk/mkenumb amd64.h \u003e amd64l.h",
-		"${TOOLPREFIX}strip ../boot/boot${CONF}.elf.out",
-		"data2c boot${CONF}_out ../boot/boot${CONF}.elf.out \u003e\u003e $CONF.root.c",
-		"data2c boot_fs boot.fs \u003e\u003e $CONF.root.c",
 		"awk -f ../mk/parse -- -mksystab ../../libc/9syscall/sys.h $CONF \u003e systab.c",
+		"awk -f ../mk/mkenumb amd64.h \u003e amd64l.h",
 		"awk -f ../mk/parse -- -mkerrstr $CONF \u003e errstr.h"
 	],
 	"Projects": [

+ 73 - 44
sys/src/9/k10/k8cpu.json

@@ -8,51 +8,81 @@
 		"../ip/ip.json",
 		"../port/port.json"
 	],
+	"Kernel": {
+		"Config": {
+			"Code": [
+				"int cpuserver = 1;",
+				"uint32_t kerndate = 1;"
+			],
+			"Dev": [
+				"root",
+				"cons",
+				"arch",
+				"env",
+				"pipe",
+				"proc",
+				"mnt",
+				"srv",
+				"dup",
+				"rtc",
+				"kprof",
+				"pmc",
+				"segment",
+				"acpi",
+				"zp",
+				"ws",
+				"cec",
+				"sd",
+				"ether",
+				"ip",
+				"pci",
+				"uart"
+			],
+			"Ip": [
+				"tcp",
+				"udp",
+				"ipifc",
+				"icmp",
+				"icmp6",
+				"gre"
+			],
+			"Link": [
+				"ether8169",
+				"ether82557",
+				"ether82563",
+				"etherigbe",
+				"ether8139",
+				"ethermedium",
+				"loopbackmedium",
+				"netdevmedium"
+			],
+			"Sd": [
+				"sdiahci"
+			],
+			"Systab": "/sys/src/libc/9syscall/sys.h",
+			"Uart": [
+				"i8250",
+				"pci"
+			]
+		},
+		"Ramfiles": {
+			"bind": "/amd64/bin/bind",
+			"boot": "boot.fs",
+			"cat": "/amd64/bin/cat",
+			"date": "/amd64/bin/date",
+			"echo": "/amd64/bin/echo",
+			"ipconfig": "/amd64/bin/ip/ipconfig",
+			"listen1": "/amd64/bin/aux/listen1",
+			"ls": "/amd64/bin/ls",
+			"mount": "/amd64/bin/mount",
+			"rc": "/amd64/bin/rc",
+			"rcmain": "/rc/lib/rcmain",
+			"srv": "/amd64/bin/srv",
+			"tty": "/amd64/bin/aux/tty"
+		}
+	},
 	"Name": "k8cpu",
-	"Post": [
-		"rm *.elf.out"
-	],
-	"Pre": [
-		"data2c _rc_lib_rcmain ../../../../rc/lib/rcmain \u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/rc rc.elf.out",
-		"${TOOLPREFIX}strip rc.elf.out",
-		"data2c _amd64_bin_rc rc.elf.out \u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/bind bind.elf.out",
-		"${TOOLPREFIX}strip bind.elf.out",
-		"data2c _amd64_bin_bind bind.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/mount mount.elf.out",
-		"${TOOLPREFIX}strip mount.elf.out",
-		"data2c _amd64_bin_mount mount.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/echo echo.elf.out",
-		"${TOOLPREFIX}strip echo.elf.out",
-		"data2c _amd64_bin_echo echo.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/ip/ipconfig ipconfig.elf.out",
-		"${TOOLPREFIX}strip ipconfig.elf.out",
-		"data2c _amd64_bin_ipconfig ipconfig.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/srv srv.elf.out",
-		"${TOOLPREFIX}strip srv.elf.out",
-		"data2c _amd64_bin_srv srv.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/date date.elf.out",
-		"${TOOLPREFIX}strip date.elf.out",
-		"data2c _amd64_bin_date date.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/ls ls.elf.out",
-		"${TOOLPREFIX}strip ls.elf.out",
-		"data2c _amd64_bin_ls ls.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/cat cat.elf.out",
-		"${TOOLPREFIX}strip cat.elf.out",
-		"data2c _amd64_bin_cat cat.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/aux/listen1 listen1.elf.out",
-		"${TOOLPREFIX}strip listen1.elf.out",
-		"data2c _amd64_bin_aux_listen1 listen1.elf.out\u003e\u003e k8cpu.root.c",
-		"cp $HARVEY/amd64/bin/aux/tty tty.elf.out",
-		"${TOOLPREFIX}strip tty.elf.out",
-		"data2c _amd64_bin_aux_tty tty.elf.out\u003e\u003e k8cpu.root.c"
-	],
 	"Program": "9k8cpu",
-	"Projects": [
-		"../boot/bootconf.json",
-		"/sys/src/cmd/kcmds.json"
-	],
 	"SourceFiles": [
 		"cga.c",
 		"devacpi.c",
@@ -60,7 +90,6 @@
 		"ether8139.c",
 		"ether82563.c",
 		"k8cpu.c",
-		"k8cpu.root.c",
 		"sdata.c",
 		"usbehcipc.c",
 		"usbohci.c",

+ 9 - 0
sys/src/all.json

@@ -0,0 +1,9 @@
+{
+	"Name": "All",
+	"Projects": [
+		"libs.json",
+		"klibs.json",
+		"cmd/cmds.json",
+		"9/k10/k8cpu.json"
+	]
+}

+ 239 - 5
util/build.go

@@ -5,19 +5,38 @@
 package main
 
 import (
-	//	"fmt"
+	"bytes"
+	"debug/elf"
 	"encoding/json"
+	"fmt"
 	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
 	"path"
 	"path/filepath"
+	"text/template"
 )
 
+type kernconfig struct {
+	Code []string
+	Dev  []string
+	Ip   []string
+	Link []string
+	Sd   []string
+	Uart []string
+}
+
+type kernel struct {
+	Systab   string
+	Config   kernconfig
+	Ramfiles map[string]string
+}
+
 type build struct {
 	// jsons is unexported so can not be set in a .json file
 	jsons map[string]bool
+	path  string
 	Name  string
 	// Projects name a whole subproject which is built independently of
 	// this one. We'll need to be able to use environment variables at some point.
@@ -37,6 +56,7 @@ type build struct {
 	Program string
 	Library string
 	Install string // where to place the resulting binary/lib
+	Kernel  *kernel
 }
 
 var (
@@ -51,12 +71,16 @@ func fail(err error) {
 	}
 }
 
+func adjust1(s string) string {
+	if path.IsAbs(s) {
+		return path.Join(harvey, s)
+	}
+	return s
+}
+
 func adjust(s []string) (r []string) {
 	for _, v := range s {
-		if path.IsAbs(v) {
-			v = path.Join(harvey, v)
-		}
-		r = append(r, v)
+		r = append(r, adjust1(v))
 	}
 	return
 }
@@ -71,6 +95,17 @@ func process(f string, b *build) {
 	err = json.Unmarshal(d, &build)
 	fail(err)
 	b.jsons[f] = true
+
+	if len(b.jsons) == 1 {
+		cwd, err := os.Getwd()
+		if err != nil {
+			log.Fatalf("%v", err)
+		}
+		b.path = path.Join(cwd, f)
+		b.Name = build.Name
+		b.Kernel = build.Kernel
+	}
+
 	b.SourceFiles = append(b.SourceFiles, build.SourceFiles...)
 	b.Cflags = append(b.Cflags, build.Cflags...)
 	b.Oflags = append(b.Oflags, build.Oflags...)
@@ -83,6 +118,7 @@ func process(f string, b *build) {
 	b.Program += build.Program
 	b.Library += build.Library
 	b.Install += build.Install
+
 	// For each source file, assume we create an object file with the last char replaced
 	// with 'o'. We can get smarter later.
 
@@ -303,6 +339,203 @@ func projects(b *build) {
 	}
 }
 
+func data2c(name string, path string) (string, error) {
+	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)
+		if err != nil {
+			log.Fatalf("%v\n", err)
+		}
+		args := []string{"-o", tmpf.Name(), path}
+		cmd := exec.Command(toolprefix+"strip", args...)
+		cmd.Env = nil
+		cmd.Stdin = os.Stdin
+		cmd.Stderr = os.Stderr
+		cmd.Stdout = os.Stdout
+		log.Printf("%v", cmd.Args)
+		err = cmd.Run()
+		if err != nil {
+			log.Fatalf("%v\n", err)
+		}
+
+		in, err = ioutil.ReadAll(tmpf)
+		if err != nil {
+			log.Fatalf("%v\n", err)
+		}
+		tmpf.Close()
+		os.Remove(tmpf.Name())
+	} else {
+		var file *os.File
+		var err error
+		if file, err = os.Open(path); err != nil {
+			log.Fatalf("%v", err)
+		}
+		in, err = ioutil.ReadAll(file)
+		if err != nil {
+			log.Fatalf("%v\n", 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), nil
+}
+
+func confcode(path string, kern *kernel) []byte {
+	var rootcodes []string
+	var rootnames []string
+	if kern.Ramfiles != nil {
+		for name, path := range kern.Ramfiles {
+			code, err := data2c(name, adjust1(path))
+			if err != nil {
+				log.Fatalf("%v\n", err)
+			}
+			rootcodes = append(rootcodes, code)
+			rootnames = append(rootnames, name)
+		}
+	}
+
+	vars := struct {
+		Path      string
+		Config    kernconfig
+		Rootnames []string
+		Rootcodes []string
+	}{
+		path,
+		kern.Config,
+		rootnames,
+		rootcodes,
+	}
+	tmpl, err := template.New("kernconf").Parse(`
+#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,
+};
+
+Physseg physseg[8] = {
+	{
+		.attr = SG_SHARED,
+		.name = "shared",
+		.size = SEGMAXPG,
+	},
+	{
+		.attr = SG_BSS,
+		.name = "memory",
+		.size = SEGMAXPG,
+	},
+};
+int nphysseg = 8;
+
+{{ range .Config.Code }}{{ . }}
+{{ end }}
+
+char* conffile = "{{ .Path }}";
+
+`)
+
+	codebuf := bytes.NewBuffer(nil)
+	if err != nil {
+		log.Fatalf("%v\n", err)
+	}
+	err = tmpl.Execute(codebuf, vars)
+	if err != nil {
+		log.Fatalf("%v\n", err)
+	}
+
+	return codebuf.Bytes()
+}
+
+func buildkernel(b *build) {
+
+	if b.Kernel == nil {
+		return
+	}
+
+	codebuf := confcode(b.path, b.Kernel)
+
+	if err := ioutil.WriteFile(b.Name+".c", codebuf, 0666); err != nil {
+		log.Fatalf("Writing %s.c: %v", b.Name, err)
+	}
+
+}
+
 // assumes we are in the wd of the project.
 func project(root string) {
 	b := &build{}
@@ -310,6 +543,7 @@ func project(root string) {
 	process(root, b)
 	projects(b)
 	run(b, b.Pre)
+	buildkernel(b)
 	if len(b.SourceFiles) > 0 {
 		compile(b)
 	}