Browse Source

Add serial port controll

master
garritfra 5 years ago
parent
commit
496c8a5ee5
  1. 2
      Makefile
  2. 3
      bochsrc.txt
  3. 2
      fb.c
  4. 4
      fb.h
  5. 2
      io.h
  6. 12
      io.s
  7. 2
      kmain.c
  8. 32
      serial.c
  9. 62
      serial.h

2
Makefile

@ -1,4 +1,4 @@
OBJECTS = io.o loader.o kmain.o fb.o
OBJECTS = io.o loader.o kmain.o fb.o serial.o
CC = gcc
CFLAGS = -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector \
-nostartfiles -nodefaultlibs -Wall -Wextra -Werror -c

3
bochsrc.txt

@ -6,4 +6,5 @@ ata0-master: type=cdrom, path=os.iso, status=inserted
boot: cdrom
log: bochslog.txt
clock: sync=realtime, time0=local
cpu: count=1, ips=1000000
cpu: count=1, ips=1000000
com1: enabled=1, mode=file, dev=com1.out

2
fb.c

@ -15,7 +15,7 @@ void fb_move_cursor(unsigned short pos)
outb(FB_DATA_PORT, pos & 0x00FF);
}
int write(char *buf, unsigned int len) {
int fb_write(char *buf, unsigned int len) {
for(int i = 0; i <= (int)len; i++) {
fb_write_cell((int)(i * 2), buf[i], 0, 15);
fb_move_cursor(i);

4
fb.h

@ -9,7 +9,9 @@
#define FB_HIGH_BYTE_COMMAND 14
#define FB_LOW_BYTE_COMMAND 15
int write(char *buf, unsigned int len);
#include "io.h"
int fb_write(char *buf, unsigned int len);

2
io.h

@ -15,6 +15,6 @@ extern void outb(unsigned short port, unsigned char data);
* @param port The address of the I/O port
* @return The read byte
*/
unsigned char inb(unsigned short port);
extern unsigned char inb(unsigned short port);
#endif

12
io.s

@ -1,4 +1,5 @@
global outb ; make the label outb visible outside this file
global inb
; outb - send a byte to an I/O port
; stack: [esp + 8] the data byte
@ -8,4 +9,13 @@ outb:
mov al, [esp + 8] ; move the data to be sent into the al register
mov dx, [esp + 4] ; move the address of the I/O port into the dx register
out dx, al ; send the data to the I/O port
ret ; return to the calling function
ret ; return to the calling function
; inb - returns a byte from the given I/O port
; stack: [esp + 4] The address of the I/O port
; [esp ] The return address
inb:
mov dx, [esp + 4] ; move the address of the I/O port to the dx register
in al, dx ; read a byte from the I/O port and store it in the al register
ret ; return the read byte

2
kmain.c

@ -3,6 +3,6 @@
int main()
{
write("Hello", 4);
fb_write("Hello", 4);
return 0;
}

32
serial.c

@ -0,0 +1,32 @@
#include "serial.h"
/** serial_configure_line:
* Configures the line of the given serial port. The port is set to have a
* data length of 8 bits, no parity bits, one stop bit and break control
* disabled.
*
* @param com The serial port to configure
*/
void serial_configure_line(unsigned short com)
{
/* Bit: | 7 | 6 | 5 4 3 | 2 | 1 0 |
* Content: | d | b | prty | s | dl |
* Value: | 0 | 0 | 0 0 0 | 0 | 1 1 | = 0x03
*/
outb(SERIAL_LINE_COMMAND_PORT(com), 0x03);
}
void serial_configure_baud_rate(unsigned short com, unsigned short divisor)
{
outb(SERIAL_LINE_COMMAND_PORT(com),
SERIAL_LINE_ENABLE_DLAB);
outb(SERIAL_DATA_PORT(com),
(divisor >> 8) & 0x00FF);
outb(SERIAL_DATA_PORT(com),
divisor & 0x00FF);
}
int serial_is_transmit_fifo_empty(unsigned int com)
{
/* 0x20 = 0010 0000 */
return inb(SERIAL_LINE_STATUS_PORT(com)) & 0x20;
}

62
serial.h

@ -0,0 +1,62 @@
#ifndef INCLUDE_SERIAL
#define INCLUDE_SERIAL
#include "io.h"
/* The I/O ports */
/* All the I/O ports are calculated relative to the data port. This is because
* all serial ports (COM1, COM2, COM3, COM4) have their ports in the same
* order, but they start at different values.
*/
#define SERIAL_COM1_BASE 0x3F8 /* COM1 base port */
#define SERIAL_DATA_PORT(base) (base)
#define SERIAL_FIFO_COMMAND_PORT(base) (base + 2)
#define SERIAL_LINE_COMMAND_PORT(base) (base + 3)
#define SERIAL_MODEM_COMMAND_PORT(base) (base + 4)
#define SERIAL_LINE_STATUS_PORT(base) (base + 5)
/* The I/O port commands */
/* SERIAL_LINE_ENABLE_DLAB:
* Tells the serial port to expect first the highest 8 bits on the data port,
* then the lowest 8 bits will follow
*/
#define SERIAL_LINE_ENABLE_DLAB 0x80
/** serial_configure_baud_rate:
* Sets the speed of the data being sent. The default speed of a serial
* port is 115200 bits/s. The argument is a divisor of that number, hence
* the resulting speed becomes (115200 / divisor) bits/s.
*
* @param com The COM port to configure
* @param divisor The divisor
*/
void serial_configure_baud_rate(unsigned short com, unsigned short divisor);
/** serial_configure_line:
* Configures the line of the given serial port. The port is set to have a
* data length of 8 bits, no parity bits, one stop bit and break control
* disabled.
*
* @param com The serial port to configure
*/
void serial_configure_line(unsigned short com);
/** serial_is_transmit_fifo_empty:
* Checks whether the transmit FIFO queue is empty or not for the given COM
* port.
*
* @param com The COM port
* @return 0 if the transmit FIFO queue is not empty
* 1 if the transmit FIFO queue is empty
*/
int serial_is_transmit_fifo_empty(unsigned int com);
#endif
Loading…
Cancel
Save