Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified doc/AstraKernelManual.pdf
Binary file not shown.
14 changes: 7 additions & 7 deletions doc/contents/datetime.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
\section{Timekeeping API}
Provide calendar dates and clock time based on the on-chip RTC.

\subsection*{Overview}
\paragraph{Overview}
\begin{itemize}
\item Reads a 32-bit seconds-since-1970 counter (RTC register at `0x101e8000`).
\item Exposes two APIs:
Expand Down Expand Up @@ -35,30 +35,30 @@ \subsection*{Data Structure}
Data Register(\textbf{RTCDR}). This is a 32 bit register, and therefore
\underline{subject to the Year 2038 Problem}.

\subsection{API: \texttt{uint32\_t getdate(dateval *date\_struct)}}
\subsection{\texttt{uint32\_t getdate(dateval *date\_struct)}}
Populate the provided \texttt{*date\_struct} with the current date in days, months, and years.

\subsubsection*{Parameters}
\paragraph{Parameters}
\begin{itemize}
\item \texttt{date\_struct} pointer to a \texttt{dateval} structure; if \texttt{NULL},
only the raw \textbf{RTC} counter is returned.
\end{itemize}

\subsubsection*{Return Value}
\paragraph{Return Value}
\begin{itemize}
\item Returns number of seconds since epoch (\texttt{RTCDR}) as read from the hardware register.
\end{itemize}

\subsection{API: \texttt{uint32\_t gettime(timeval *time\_struct)}}
\subsection{\texttt{uint32\_t gettime(timeval *time\_struct)}}
Populate \texttt{*time\_struct} with the current click time in hours, minutes, and seconds.

\subsubsection*{Parameters}
\paragraph{Parameters}
\begin{itemize}
\item \texttt{time\_struct} pointer to a \texttt{timeval} structure; if \texttt{NULL},
only the raw \textbf{RTC} counter is returned.
\end{itemize}

\subsubsection*{Return Value}
\paragraph{Return Value}
\begin{itemize}
\item Returns number of seconds since epoch (\texttt{RTCDR}) as read from the hardware register.
\end{itemize}
Expand Down
30 changes: 17 additions & 13 deletions doc/contents/puts.tex → doc/contents/print.tex
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
% ------------------------------------------------
% *** Section 2: I/O API ***
% *** Section 2: I/O \& Time Services ***
% ------------------------------------------------
\newpage
\chapter{I/O \& Time Services}

\section{UART Device Driver}
\section{UART Output API}

\subsubsection{Registers \& Constants}
\begin{itemize}
\item \textbf{UART0\_DR} (Data Register), \texttt{0x101f1000}
\item \textbf{UART0\_FR} (Flag Register), \texttt{0x101f1018}
\item \textbf{UART\_FR\_TXFF}, \textbf{UART\_FR\_RXFE}
\end{itemize}

\subsection{API: \texttt{printf(char *s, ...)}}
\subsection{\texttt{printf(char *s, ...)}}

\paragraph{Description}
Sends a null-terminated format string over UART. If an incorrect datatype is given
for a format specifier, \underline{the behavior is undefined}. If a format specifier
is given without a matching argument, it is simply skipped when the string is outputted.
The following format specifiers are supported:

\paragraph{Supported Format Specifiers}
\begin{itemize}
\item \textbf{\%c}: Expects a single character.
\item \textbf{\%s}: Expects a null-terminated string.
\item \textbf{\%d}: For 32-bit signed integers in the range \texttt{-2147483648} to \texttt{2147483647}.
\item \textbf{\%ld}: For 64-bit signed integers in the range \texttt{-9223372036854775808} to \texttt{9223372036854775807}, excluding the range specified above, for \textbf{\%d}.
\item \textbf{\%lu}: For 64-bit unsigned integers in the range \texttt{2147483648} to \texttt{18446744073709551615}.
\item \textbf{\%x} and \textbf{\%X}: For 32-bit unsigned integers in the range \texttt{0} to \texttt{2147483647}, where the case of \texttt{x} determines the case of the hexadecimal digits (\texttt{a-f} or \texttt{A-F}).
\item \textbf{\%lx} and \textbf{\%lX}: For 64-bit unsigned integers printed in hexadecimal format. Has the same range as \textbf{\%lu}. The case of \texttt{x} determines the case of the hexadecimal digits (\texttt{a-f} or \texttt{A-F}).
\item \textbf{\%\%}: Outputs a '\%'.
\item \textbf{\%}: Outputs (null). This is a special case where the format specifier is not followed by any character, and it simply outputs nothing.
\item \texttt{\%c}: Expects a single character.
\item \texttt{\%s}: Expects a null-terminated string.
\item \texttt{\%d}: For 32-bit signed integers in the range \texttt{-2147483648} to \texttt{2147483647}.
\item \texttt{\%ld}: For 64-bit signed integers in the range \texttt{-9223372036854775808} to \texttt{9223372036854775807}, excluding the range specified above, for \textbf{\%d}.
\item \texttt{\%lu}: For 64-bit unsigned integers in the range \texttt{2147483648} to \texttt{18446744073709551615}.
\item \texttt{\%x}, \texttt{\%X}: For 32-bit unsigned integers in the range \texttt{0} to \texttt{2147483647}, where the case of \texttt{x} determines the case of the hexadecimal digits (\texttt{a-f} or \texttt{A-F}).
\item \texttt{\%lx}, \texttt{\%lX}: For 64-bit unsigned integers printed in hexadecimal format. Has the same range as \textbf{\%lu}. The case of \texttt{x} determines the case of the hexadecimal digits (\texttt{a-f} or \texttt{A-F}).
\item \texttt{\%\%}: Outputs a literal \texttt{\%}.
\item \texttt{\%}: If the format specifier is not followed by a valid character, prints \texttt{(null)}.
\end{itemize}

\begin{flushleft}
All the ranges specified above are inclusive. Also, note that integers in the
range \texttt{-2147483648} to \texttt{2147483647} are passed as 32 bit integers
and any integers not part of this range are passed as 64 bit integers \underline{by default}.
If desired, integers of this range can be cast as \texttt{long long} or \texttt{unsigned long long}
for use with the format specifiers prefixed by \textbf{l}(ell).
for use with the format specifiers prefixed by the character \texttt{l}.
\end{flushleft}

\subsection*{Examples}
Expand Down
71 changes: 71 additions & 0 deletions doc/contents/string.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
\newpage
\section{String Manipulation API}
\subsection{\texttt{strcmp(const char *str\_1, const char *str\_2)}}

\paragraph{Purpose}
Compares two null-terminated strings, character by character.

\paragraph{Overview}
This function compares the characters of two strings (\texttt{ASCII values}),
\texttt{str\_1} and \texttt{str\_2}, one by one. It returns:

\paragraph{Return Values}
\begin{itemize}
\item 0 if both strings are equal,
\item -1 if the first differing character in \texttt{str\_1} is less than that in \texttt{str\_2},
\item 1 if the first differing character in \texttt{str\_1} is greater than that in \texttt{str\_2}.
\end{itemize}

\paragraph{Behavior}
The comparison stops at the first difference or the null terminator.
Case sensitivity is observed. Behavior is undefined if either pointer is not a
valid null-terminated string.

\subsection*{Examples}
\begin{lstlisting}[language=C, caption=String Comparison Example]
int result = strcmp("abc", "abc"); // Expect 0
printf("Expect 0 -> %d\n", result);

result = strcmp("abc", "abd"); // Expect -1
printf("Expect -1 -> %d\n", result);

result = strcmp("abc", "ABC"); // Expect 1
printf("Expect 1 -> %d\n", result);
\end{lstlisting}

\begin{note}
In the future, we could returning the difference between the first differing
characters, which would allow for more detailed comparisons. This would enable
users to understand how far apart the strings are in terms of character values.
\end{note}

\subsection{\texttt{strlen(const char *str)}}

\paragraph{Purpose}
Calculates the length of a null-terminated string.

\paragraph{Overview}
This function counts the number of characters in a null-terminated string,
excluding the null terminator itself. It returns the length of the string as an
unsigned integer. This function uses pointer arithmetic to traverse the string,
performing mathematical operations directly on the pointer values.

\paragraph{Return Values}
\begin{itemize}
\item The number of characters in the string, not including the null terminator.
\item 0 if the string is empty (i.e., the first character is the null terminator).
\end{itemize}

\paragraph{Behavior}
The function iterates through the input string until the null terminator is found, returning
the number of characters preceding it. If the input pointer is not a valid
null-terminated string, the behavior is undefined.

\subsection*{Examples}
\begin{lstlisting}[language=C, caption=String Length Example]
size_t result = strlen("abc"); // Expect 3
printf("Expect len 3 -> %d\n", result);

result = strlen(""); // Expect 0
printf("Expect len 0 -> %d\n", result);
\end{lstlisting}
14 changes: 8 additions & 6 deletions doc/front/preface.tex
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ \section*{Preface}

\addcontentsline{toc}{section}{About This Project}
\section*{About This Project}
\subsection*{Resources}
\paragraph{Resources}

To guide my learning and support development of AstraKernel, I am using the following resources,
which are particularly valuable for foundational and practical understanding of OS design:
Expand All @@ -50,26 +50,28 @@ \subsection*{Resources}
\item \textbf{The Little Book About OS Development} by Erik Helin and Adam Renberg
\end{itemize}

\subsection*{Acknowledgments \& Contributions}
\paragraph{Contributions}

AstraKernel is an open source project, and I encourage contributions from anyone
interested in improving, extending the kernel or simply experiment with it. I also
encourage anyone to improve this documentation, as it is a work in progress.
If you would like to contribute, please feel free to open an issue or pull request on the GitHub repository.
\\
\begin{info}
You can join the Matrix Server \url{https://matrix.to/#/#sandboxscience:matrix.org}
for general SandBox Science discussion as well as project-specific discussion such
as AstraKernel development.
\end{info}

\noindent
\paragraph{Acknowledgments}
Specially thanks to the following individuals for their contributions:
\begin{itemize}
\item \textbf{shade5144} (\url{https://github.com/shade5144}) for contributing the initial version of the \texttt{printf}
function as well as the documentation for it.
\item \textbf{shade5144} (\url{https://github.com/shade5144}) for contributing
the initial version of the \texttt{printf} and \texttt{datetime} function as
well as the documentation for them.
\end{itemize}

\subsection*{Disclaimer}
\paragraph{Disclaimer}

AstraKernel is currently in its early stages of development and is not intended for production use.
It is primarily an educational and experimental project. The code is provided as-is,
Expand Down
3 changes: 2 additions & 1 deletion doc/main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
% % *** Main Content ***
% % -----------------------------------------------------
\input{contents/introduction}
\input{contents/puts}
\input{contents/print}
\input{contents/string}
\input{contents/datetime}

\end{document}
18 changes: 18 additions & 0 deletions include/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef STRING_H
#define STRING_H

#include <stddef.h>

#ifdef __cplusplus
extern "C"
{
#endif

int strcmp(const char *str_1, const char *str_2);
size_t strlen(const char *str);

#ifdef __cplusplus
}
#endif

#endif // STRING_H
76 changes: 45 additions & 31 deletions kernel/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "datetime.h"
#include "printf.h"
#include "clear.h"
#include "string.h"

static const char *banner[] = {
"========================================\r\n",
Expand Down Expand Up @@ -53,37 +54,50 @@ void kernel_main(void)

switch (input_buffer[0])
{
case 'h': // Check for help command
printf("\nHelp:\n 'q' to exit\n 'h' for help\n 'c' to clear screen\n 't' to print current time\n 'd' to print current date\r\n");
break;
case 'e': // TODO: This is for testing purposes. Remove once not needed
printf("%ld %ld %ld\n", 0, -9223372036854775808, 9223372036854775807);
printf("%d %d\n", 2147483647, -2147483648);
printf("%x %lx %lX %X\n", 2147483647, 2147483649, 2147483648, 1234);
printf("%lX %x %lx\n", 0x123456789abcdef0, 1234, 9223372036854775809);
printf("Name: %c\n", 'b');
printf("Hello %s\n", "World");
printf("100%%\n");
break;
case 'q': // Check for exit command
printf("Exiting...\r\n");
is_running = false;
break;
case 'c': // Check for clear screen command
clear();
break;

case 't': // Check for time command
gettime(&time_struct);
printf("Current time(GMT): %d:%d:%d\n", time_struct.hrs, time_struct.mins, time_struct.secs);
break;
case 'd': // Check for date command
getdate(&date_struct);
printf("Current date(MM-DD-YYYY): %d-%d-%d\n", date_struct.month, date_struct.day, date_struct.year);
break;
default:
printf("Unknown command. Type 'h' for help.\r\n");
break;
case 'h': // Check for help command
printf("\nHelp:\n 'q' to exit\n 'h' for help\n 'c' to clear screen\n 't' to print current time\n 'd' to print current date\r\n");
break;
case 'e':
int result = strcmp("abc", "abc"); // Expect 0
printf("Expect 0 -> %d\n", result);

result = strcmp("abc", "abd"); // Expect -1
printf("Expect -1 -> %d\n", result);

result = strcmp("abc", "ABC"); // Expect 1
printf("Expect 1 -> %d\n", result);

result = strcmp("ABC", "abc"); // Expect -1
printf("Expect -1 -> %d\n", result);

result = strcmp("\x01\x02\x03", "\x01\x02\x03"); // Expect 0
printf("Expect 0 -> %d\n", result);

result = strcmp("\x01\x02\x03", "\x01\x02\x04"); // Expect -1
printf("Expect -1 -> %d\n", result);

result = strcmp("\x01\x02\x04", "\x01\x02\x03"); // Expect 1
printf("Expect 1 -> %d\n", result);
break;
case 'q': // Check for exit command
printf("Exiting...\r\n");
is_running = false;
break;
case 'c': // Check for clear screen command
clear();
break;

case 't': // Check for time command
gettime(&time_struct);
printf("Current time(GMT): %d:%d:%d\n", time_struct.hrs, time_struct.mins, time_struct.secs);
break;
case 'd': // Check for date command
getdate(&date_struct);
printf("Current date(MM-DD-YYYY): %d-%d-%d\n", date_struct.month, date_struct.day, date_struct.year);
break;
default:
printf("Unknown command. Type 'h' for help.\r\n");
break;
}
}
}
45 changes: 45 additions & 0 deletions user/string.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "string.h"

/**
* @brief Compares two null-terminated strings lexicographically.
*
* @param str_1 Pointer to the first string to compare.
* @param str_2 Pointer to the second string to compare.
*
* @return int 0 if strings are equal, -1 if `str_1` < `str_2`, 1 if `str_1` > `str_2`.
*/
int strcmp(const char *str_1, const char *str_2)
{
unsigned char ch1, ch2;
do
{
ch1 = *str_1++;
ch2 = *str_2++;

if (ch1 != ch2)
{
// NOTE: If needed in the future, can return the difference between
// the strings rather than just -1 or 1
return ch1 < ch2 ? -1 : 1;
}

} while (ch1);

return 0;
}

/**
* @brief Calculates the length of a null-terminated string.
*
* @param str Pointer to the null-terminated string to be measured.
* @return The number of characters in the string, excluding the null terminator.
*/
size_t strlen(const char *str)
{
const char *s = str;
while (*s)
{
++s;
}
return s - str;
}