diff --git a/.gitignore b/.gitignore index 99ad6b47..25406f93 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,4 @@ /*.sh~ /*.img src/include/asuro.pas -.vscode/launch.json -.vscode +localenv.json diff --git a/.vscode/launch.json b/.vscode/launch.json index c945c666..5178fc41 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,18 +3,11 @@ { "name":"Run", "request": "launch", - "type": "coreclr", + "type": "PowerShell", "preLaunchTask": "Build", - "program": "VBoxSDL", - "args": [ - "--comment", - "Asuro", - "--startvm", - "7d395c96-891c-4139-b77d-9b6b144b0b93" - ], + "script": "${workspaceFolder}/virtualbox-wrapper.ps1", + "args": ["-Command", "up"], "cwd": "${workspaceFolder}", - "console": "internalConsole", - "internalConsoleOptions": "neverOpen" } ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3f74eb24..9cb0382a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -9,14 +9,18 @@ "command": "docker-compose", "args": [ "run", - "builder" + "builder", ], "type": "shell", "problemMatcher": [], "group": { "kind": "build", "isDefault": true - } + }, + "dependsOn": [ + "Close VirtualBox", + "Clean" + ] }, { "label": "Build (Builder)", @@ -26,6 +30,24 @@ "builder" ], "type": "shell" + }, + { + "label": "Clean", + "command": "docker-compose", + "args": [ + "down", + "--remove-orphans" + ], + "type": "shell" + }, + { + "label": "Close VirtualBox", + "command": "./virtualbox-wrapper.ps1", + "args": [ + "-Command", + "down" + ], + "type": "shell" } ] } \ No newline at end of file diff --git a/compile_sources.sh b/compile_sources.sh index c8f6db32..f93d93b3 100644 --- a/compile_sources.sh +++ b/compile_sources.sh @@ -4,4 +4,4 @@ echo "=======================" echo " " echo "Compiling FPC Sources..." echo " " -fpc -Aelf -gw -n -va -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* src/kernel.pas \ No newline at end of file +fpc -Aelf -gw -g -gl -n -vlewn -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* src/kernel.pas \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index b5c19202..845189bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3.9" services: builder: build: . diff --git a/linker.script b/linker.script index 875bfc95..91a7a72a 100644 --- a/linker.script +++ b/linker.script @@ -2,7 +2,7 @@ ENTRY(loader) SECTIONS { . = 0xC0100000; - + kernel_start = .; .text : AT(ADDR(.text) - 0xC0000000) { text = .; _text = .; __text = .; @@ -33,4 +33,5 @@ SECTIONS . = ALIGN(4096); } end = .; _end = .; __end = .; + kernel_end = .; } diff --git a/readme.md b/readme.md index 6ec79d39..1ab8b627 100644 --- a/readme.md +++ b/readme.md @@ -13,8 +13,8 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f I don't think this needs an explaination. * [VSCode (Optional, but highly recommended)](https://code.visualstudio.com/) Visual Studio code is our IDE of choice, and we have a number of recommended plugins. - * [C# Plugin by Microsoft](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) - This plugin gives you the ability to use the 'coreclr' task type, allowing the automatic launching of virtualbox with the resulting image generated during compilation of Asuro. + * [PowerShell Plugin by Microsoft](https://marketplace.visualstudio.com/items?itemName=ms-vscode.powershell) + This plugin gives you the ability to use the 'PowerShell' task type, allowing the automatic launching of virtualbox with the resulting image generated during compilation of Asuro. * [VirtualBox](https://www.virtualbox.org/) Virtualbox is our Virtualisation environment of choice, don't ask why, it just is. @@ -27,15 +27,15 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f 3. Install Docker for Windows. 4. Install Git for Windows. 5. Install VSCode & the listed plugins. -6. Install VirtualBox. +6. Install VirtualBox (v7+). 7. Clone this repository. 8. Run the following command in the root of the repo to build the docker image: ```powershell - docker-compose build builder + docker compose build builder ``` 9. Run the following command to compile Asuro: ```powershell - docker-compose run builder + docker compose run builder ``` 10. Create a new virtual machine in Virtualbox and mount the `Asuro.iso` generated in step 9 as a boot image. 11. Add the virtualbox installation directory to your `%PATH%` environment variable, usually: @@ -50,32 +50,29 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f ```xml ``` - Copy the uuid, in our case `7d395c96-891c-4139-b77d-9b6b144b0b93` and replace the uuid found in `.vscode\launch.json` under `args`, so that it looks something like this: + Copy the uuid, in our case `7d395c96-891c-4139-b77d-9b6b144b0b93` & create a `localenv.json` file in the project root with the following content: ```json { - "configurations": [ - { - "name":"Run", - "request": "launch", - "type": "coreclr", - "preLaunchTask": "Build", - "program": "VBoxSDL", - "args": [ - "--comment", - "Asuro", - "--startvm", - "" - ], - "cwd": "${workspaceFolder}", - "console": "internalConsole", - "internalConsoleOptions": "neverOpen" - } - ] + "VirtualBox":{ + "MachineName":"" + } } ``` This will allow VSCode to automatically launch VirtualBox once Asuro has been compiled. + + You can also enable the serial adapter "COM1" in mode "Raw File", give it a path, and provide this path in the `localenv.json` as follows: + ```json + { + "VirtualBox" : { + "MachineName": "", + "LogLocation": "Fully\\Qualified\\Path\\To\\Your\\Log\\File" + } + } + ``` + This will allow you to see the console output from Asuro in your host terminal. 13. Open your project folder in VSCode, use CTRL+SHIFT+B to build & F5 to build + run in VBox. 14. Congratulations! You can now play with Asuro! -### Gotchas -- It was noted that Windows builds above `20H2` seem to have issues installing WSL2. We may have to wait for a patch from Microsoft to fix this. Our devs are currently using build `20H2`. \ No newline at end of file +### Notes & Gotchas +- The above process has been updated to be compatible with VirtualBox 7+, in which VBoxSDL was removed and vboxmanage should be used in its place. A small wrapper powershell script is used to achieve this. +- It was noted that Windows builds above `20H2` seem to have issues installing WSL2. We may have to wait for a patch from Microsoft to fix this. Our devs are currently using build `20H2`. diff --git a/src/include/strings.pas b/src/include/strings.pas index 485dbb24..8c231233 100644 --- a/src/include/strings.pas +++ b/src/include/strings.pas @@ -16,6 +16,7 @@ Include->Strings - String Manipulation. @author(Kieron Morris ) + @author(Aaron Hance ) } unit strings; @@ -33,6 +34,10 @@ function stringCopy(str : pchar) : pchar; function stringNew(size : uint32) : pchar; function stringSize(str : pchar) : uint32; function stringConcat(str1, str2 : pchar) : pchar; +function stringTrim(str : pchar; length : uint32) : pchar; +function stringSub(str : pchar; start, size : uint32) : pchar; +function stringReplace(str, find, replace : pchar) : pchar; +function stringIndexOf(str, find : pchar) : sint32; function stringContains(str : pchar; sub : pchar) : boolean; function stringToInt(str : pchar) : uint32; function hexStringToInt(str : pchar) : uint32; @@ -151,6 +156,94 @@ begin stringConcat:= result; end; +// Trim the string to the specified length. +function stringTrim(str : pchar; length : uInt32) : pchar; +var + result : pchar; +begin + result:= stringNew(length); + memcpy(uint32(str), uint32(result), length); + stringTrim:= result; +end; + +// Return a substring of the string. +function stringSub(str : pchar; start, size : uint32) : pchar; +var + result : pchar; +begin + result:= stringNew(size); + memcpy(uint32(str)+start, uint32(result), size); + stringSub:= result; +end; + +// Replace first instance of a string with another. +function stringReplace(str, find, replace : pchar) : pchar; +var + result : pchar; + i, j, k : uint32; + found : boolean; +begin + + // Find the first instance of the find string. + i:= 0; + found:= false; + while (i < stringSize(str)) and (not found) do begin + if stringEquals(str+i, find) then begin + found:= true; + end else begin + inc(i); + end; + end; + + // If we found the find string, replace it. + if found then begin + result:= stringNew(stringSize(str) - stringSize(find) + stringSize(replace)); + j:= 0; + k:= 0; + while i < stringSize(str) do begin + if stringEquals(str+i, find) then begin + memcpy(uint32(replace), uint32(result+j), stringSize(replace)); + j:= j + stringSize(replace); + inc(i, stringSize(find)); + end else begin + result[j]:= str[i]; + inc(j); + inc(i); + end; + end; + stringReplace:= result; + end else begin + stringReplace:= stringCopy(str); + end; + + // Return the result. + stringReplace:= result; + +end; + + +// Find the index of the first instance of a string. +function stringIndexOf(str, find : pchar) : sint32; +var + i : uint32; + found : boolean; +begin + i:= 0; + found:= false; + while (i < stringSize(str)) and (not found) do begin + if stringEquals(str+i, find) then begin + found:= true; + end else begin + inc(i); + end; + end; + if found then begin + stringIndexOf:= i; + end else begin + stringIndexOf:= -1; + end; +end; + function stringContains(str : pchar; sub : pchar) : boolean; var strEnd, subEnd, i, j, count : uint32; diff --git a/src/include/system.pas b/src/include/system.pas index dd4354a0..977ddead 100644 --- a/src/include/system.pas +++ b/src/include/system.pas @@ -143,6 +143,22 @@ type PText = ^Text; +var + AK_START : uint32; external name 'kernel_start'; + AK_END : uint32; external name 'kernel_end'; + ASURO_KERNEL_START : uint32; + ASURO_KERNEL_END : uint32; + ASURO_KERNEL_SIZE : uint32; + +procedure init(); + implementation +procedure init(); +begin + ASURO_KERNEL_START := uint32(@AK_START); + ASURO_KERNEL_END := uint32(@AK_END); + ASURO_KERNEL_SIZE:= ASURO_KERNEL_END - ASURO_KERNEL_START; +end; + end. diff --git a/src/kernel.pas b/src/kernel.pas index 9b40accc..ace9f2a1 100644 --- a/src/kernel.pas +++ b/src/kernel.pas @@ -125,6 +125,9 @@ var HM : PHashMap; begin + { Init the base system unit } + System.init(); + { Serial Init } serial.init(); diff --git a/virtualbox-wrapper.ps1 b/virtualbox-wrapper.ps1 new file mode 100644 index 00000000..7fd2bf04 --- /dev/null +++ b/virtualbox-wrapper.ps1 @@ -0,0 +1,58 @@ +<# +You need a local git-ignored localenv.json file with the following content: +{ + "virtualbox": { + "MachineName": "your-machine-name or guid" + } +} +#> + +param ( + [Parameter(Mandatory=$true)] + [ValidateSet('up', 'down')] + [String]$Command +) + +$Config = Get-Content .\localenv.json | ConvertFrom-Json +$MachineName = $Config.virtualbox.MachineName +$LogLocation = $Config.virtualbox.LogLocation +$LogOutputEnabled = $LogLocation -ne $null + +if ($Command -eq 'up') { + + if($LogOutputEnabled) { + Clear-Content $LogLocation + } + + $MonitorJob = Start-Job -ArgumentList $MachineName -ScriptBlock { + param($MachineName) + Write-Output "Starting $MachineName" + VBoxManage.exe startvm $MachineName + $running=$true + while($running) { + $status=(VBoxManage.exe list runningvms) + if($status) { + $running=$status.contains($MachineName) + } else { + $running=$false + } + } + } + + if($LogOutputEnabled) { + $LogJob = Start-Job -ArgumentList $LogLocation -ScriptBlock { + param($LogLocation) + Get-Content -Path $LogLocation -Wait + } + } + + while($MonitorJob.State -eq 'Running') { + if($LogOutputEnabled) { + Receive-Job $LogJob + } + Receive-Job $MonitorJob + } +} elseif ($Command -eq 'down') { + Write-Output "Stopping $MachineName" + VBoxManage.exe controlvm $MachineName poweroff +} \ No newline at end of file