diff --git a/.gitignore b/.gitignore index 81526d5..c895492 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,8 @@ *.img *.hdd -eggos.iso +*.iso +egg bootblock serial trace.txt diff --git a/README.md b/README.md index 997f3a2..75149a5 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,8 @@ Run `egg build -o kernel.elf` in your project directory to get the kernel file, `egg pack -o eggos.iso -k kernel.elf` can pack the kernel into an iso file, and then you can use https://github.com/ventoy/Ventoy to run the iso file on a bare metal. +Here are some examples [examples](./app/examples) + Happy hacking! # Debug diff --git a/README_CN.md b/README_CN.md index 97b6856..f15c776 100644 --- a/README_CN.md +++ b/README_CN.md @@ -83,6 +83,8 @@ $ mage qemu `egg pack -o eggos.iso -k kernel.elf` 可以将内核打包成一个iso文件,通过 https://github.com/ventoy/Ventoy 即可运行在真实的机器上。 +这里是一些例子[例子](./app/examples) + Happy hacking! # Debug diff --git a/app/examples/README.md b/app/examples/README.md new file mode 100644 index 0000000..d2070a5 --- /dev/null +++ b/app/examples/README.md @@ -0,0 +1,50 @@ +This directory contains examples of how `eggos` can be used to write common go applications. + +# helloworld + +``` sh +$ cd helloworld +$ egg run +``` + +# concurrent prime sieve + +``` sh +$ cd prime-sieve +$ egg run +``` + +# http server + +``` sh +$ cd httpd +$ egg run -p 8000:8000 +``` + +Access this address from browser http://127.0.0.1:8000/hello + +# simple repl program + +``` sh +$ cd repl +$ egg run +``` + +# simple animation + +Code from `The Go Programming Language` + +``` sh +$ cd graphic +$ egg pack -o graphic.iso +$ egg run graphic.iso +``` + +# handle syscall + +This example shows how to add or modify syscall + +``` sh +$ cd syscall +$ egg run +``` \ No newline at end of file diff --git a/app/examples/graphic/main.go b/app/examples/graphic/main.go new file mode 100644 index 0000000..6342584 --- /dev/null +++ b/app/examples/graphic/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "image" + "image/color" + "image/draw" + "math" + "math/rand" + "time" + + "github.com/icexin/eggos/drivers/vbe" +) + +var palette = []color.Color{color.White, color.Black} + +const ( + whiteIndex = 0 // first color in palette + blackIndex = 1 // next color in palette +) + +func main() { + // The sequence of images is deterministic unless we seed + // the pseudo-random number generator using the current time. + // Thanks to Randall McPherson for pointing out the omission. + rand.Seed(time.Now().UTC().UnixNano()) + canvas := vbe.DefaultView.Canvas() + lissajous(canvas) +} + +func lissajous(canvas draw.Image) { + const ( + cycles = 5 // number of complete x oscillator revolutions + res = 0.001 // angular resolution + size = 100 // image canvas covers [-size..+size] + nframes = 64 // number of animation frames + delay = 8 // delay between frames in 10ms units + ) + + freq := rand.Float64() * 3.0 // relative frequency of y oscillator + phase := 0.0 // phase difference + for { + rect := image.Rect(0, 0, 2*size+1, 2*size+1) + img := image.NewPaletted(rect, palette) + for t := 0.0; t < cycles*2*math.Pi; t += res { + x := math.Sin(t) + y := math.Sin(t*freq + phase) + img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), + blackIndex) + } + phase += 0.1 + time.Sleep(time.Duration(delay*10) * time.Millisecond) + draw.Draw(canvas, img.Rect, img, image.ZP, draw.Src) + vbe.DefaultView.CommitRect(img.Rect) + } +} diff --git a/app/examples/helloworld/main.go b/app/examples/helloworld/main.go new file mode 100644 index 0000000..95e49a3 --- /dev/null +++ b/app/examples/helloworld/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("hello eggos") +} diff --git a/app/examples/httpd/main.go b/app/examples/httpd/main.go new file mode 100644 index 0000000..6cdcd04 --- /dev/null +++ b/app/examples/httpd/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "io" + "net/http" +) + +func main() { + http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello eggos") + }) + fmt.Println("http server listen on :8000") + http.ListenAndServe(":8000", nil) +} diff --git a/app/examples/prime-sieve/main.go b/app/examples/prime-sieve/main.go new file mode 100644 index 0000000..5190934 --- /dev/null +++ b/app/examples/prime-sieve/main.go @@ -0,0 +1,36 @@ +// A concurrent prime sieve + +package main + +import "fmt" + +// Send the sequence 2, 3, 4, ... to channel 'ch'. +func Generate(ch chan<- int) { + for i := 2; ; i++ { + ch <- i // Send 'i' to channel 'ch'. + } +} + +// Copy the values from channel 'in' to channel 'out', +// removing those divisible by 'prime'. +func Filter(in <-chan int, out chan<- int, prime int) { + for { + i := <-in // Receive value from 'in'. + if i%prime != 0 { + out <- i // Send 'i' to 'out'. + } + } +} + +// The prime sieve: Daisy-chain Filter processes. +func main() { + ch := make(chan int) // Create a new channel. + go Generate(ch) // Launch Generate goroutine. + for i := 0; i < 10; i++ { + prime := <-ch + fmt.Println(prime) + ch1 := make(chan int) + go Filter(ch, ch1, prime) + ch = ch1 + } +} diff --git a/app/examples/repl/main.go b/app/examples/repl/main.go new file mode 100644 index 0000000..38c099f --- /dev/null +++ b/app/examples/repl/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "crypto/sha1" + "fmt" +) + +func main() { + var s string + for { + fmt.Print(">>> ") + fmt.Scan(&s) + sum := sha1.Sum([]byte(s)) + fmt.Printf("sha1(%s) = %x\n", s, sum) + } +} diff --git a/app/examples/syscall/main.go b/app/examples/syscall/main.go new file mode 100644 index 0000000..0d0731a --- /dev/null +++ b/app/examples/syscall/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "os" + "syscall" + + "github.com/icexin/eggos/kernel/isyscall" +) + +var handler isyscall.Handler + +func handleUname(req *isyscall.Request) { + fmt.Println("syscall `uname` called") + handler(req) +} + +func main() { + handler = isyscall.GetHandler(syscall.SYS_UNAME) + isyscall.Register(syscall.SYS_UNAME, handleUname) + _, err := os.Hostname() + if err != nil { + panic(err) + } +}